none
Converting EMF to PNG preserves/displaying Excel cell with No Color data RRS feed

  • Question

  • Hi,
    We have NT EMF virtual printer, We have Excel sheet (contains each cell data with no color) show that no color cell will not be printed.
    When we print that Excel sheet to our virtual printer, it will print EMF data to or WPF application.
    The problem is after receiving the print data from Excel the data in no color cell are also visible.

    Print Excel sheet to our virtual printer, Excel Print Preview is not showing the no color data. Screenshot attached. (Excel Print Preview.png)
    See data in cell A1, C2, E3, G4 is not visible in Excel Print Preview.

    After receiving the excel printed data as EMF in our WPF application, we are trying convert EMF (Metafile) to PNG and when preview no color cell data is visible. Screenshot attached. (WPF Preview.png)
    See A1, C2, E3 , G4 data are visible.

    We are using below code to convert EMF to PNG.
    int borderSize = 10;
    float Dpi = 2f; //2.54f
    string FilePath = System.IO.Path.GetTempPath();
    string Desc = System.IO.Path.Combine(FilePath, "TemptiffView.png");

    System.Drawing.Imaging.Metafile m_emf = "Excel print data to our application via our virtual printer";

    using (var target = new Bitmap(Width, Height))
    {                       
        using (var g = Graphics.FromImage(target))
        {
            g.Clear(System.Drawing.Color.White);

    1. using (System.Drawing.Brush border = new SolidBrush(System.Drawing.Color.White /*Change it to whichever color you want.*/))
    2. {
    3. g.FillRectangle(border, 0, 0, Width + borderSize, Height + borderSize);
    4. }
    5. var WMargin = (float) (borderSize * Dpi);
    6. var HMargin = (Height > Width)
    7. ? (float) ((borderSize * Dpi) / 2)
    8. : (float) (borderSize * Dpi);
    9. g.DrawImage(m_emf, borderSize, borderSize, (Width - (float) WMargin), (Height - (float) HMargin));
    10. target.Save(Desc, ImageFormat.Png);
    11. }
    12. m_emf.Dispose();

    }

    Kindly help us to resolve this issue.

    Regards
    Ashok

    Friday, June 26, 2020 4:18 AM

All replies

  • By “no color” do you mean white background and white text in Excel?

    Friday, June 26, 2020 5:47 AM
  • Yes.

    Enter data in cell and set Font Color as White Background.

    Friday, June 26, 2020 2:14 PM
  • Did you check this issue using some other programs? For example, open the metafile in Paint application.

    If possible, give a sample metafile made by your printer.

    Friday, June 26, 2020 5:35 PM
  • Thank you. Please verify this with the shared EMF file.
    https://1drv.ms/u/s!AodKo5CpIMq2iiDaYvBJDO2hwtwg?e=Y2Elvw

    If I use StretchDIBBits C++ API in my VC++ project those white background cell data is not visible, only problem is C# EMF to PNG conversion.

    Monday, June 29, 2020 4:48 AM
  • Hi,

    Is it possible to directly convert the excel sheet into a png picture?

    If it is possible, you can install a nuget package: FreeSpire.XLS.

    Then use the following code.

            public static void ExcelToEMF() 
            {
                Workbook workbook = new Workbook();
                workbook.LoadFromFile(@"D:\test\test.xlsx");
    
                Worksheet sheet = workbook.Worksheets[0];
                sheet.SaveToImage(@"D:\test\test.png", ImageFormat.Png);
            }

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, June 29, 2020 7:15 AM
  • Thank you for your reply.

    But we cannot use any third party library.

    Our virtual printer driver will print any document and send the print data to our WPF application, will receive the print data as EMF and convert to PNG. The problem is converting EMF to PNG using C# is displaying the white background Excel cell data.

    Tuesday, June 30, 2020 4:46 AM
  • Hi,

    I noticed that you said:

    >>If I use StretchDIBBits C++ API in my VC++ project those white background cell data is not visible.

    We can use PInvoke in C# to call the API in C++, so try the following way.

            [DllImport("gdi32.dll")]
            static extern int StretchDIBits(IntPtr hdc, int XDest, int YDest,
              int nDestWidth, int nDestHeight, int XSrc, int YSrc, int nSrcWidth,
              int nSrcHeight, byte[] lpBits, [In] ref BITMAPINFO lpBitsInfo, uint iUsage,
              uint dwRop);
            public enum BitmapCompressionMode : uint
            {
                BI_RGB = 0,
                BI_RLE8 = 1,
                BI_RLE4 = 2,
                BI_BITFIELDS = 3,
                BI_JPEG = 4,
                BI_PNG = 5
            }
            [StructLayout(LayoutKind.Sequential)]
            public struct RGBQUAD
            {
                public byte rgbBlue;
                public byte rgbGreen;
                public byte rgbRed;
                public byte rgbReserved;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct BITMAPINFOHEADER
            {
                public uint biSize;
                public int biWidth;
                public int biHeight;
                public ushort biPlanes;
                public ushort biBitCount;
                public BitmapCompressionMode biCompression;
                public uint biSizeImage;
                public int biXPelsPerMeter;
                public int biYPelsPerMeter;
                public uint biClrUsed;
                public uint biClrImportant;
    
                public void Init()
                {
                    biSize = (uint)Marshal.SizeOf(this);
                }
            }
    
            [StructLayoutAttribute(LayoutKind.Sequential)]
            struct BITMAPINFO
            {
                /// <summary>
                /// A BITMAPINFOHEADER structure that contains information about the dimensions of color format.
                /// </summary>
                public BITMAPINFOHEADER bmiHeader;
    
                /// <summary>
                /// An array of RGBQUAD. The elements of the array that make up the color table.
                /// </summary>
                [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 1, ArraySubType = UnmanagedType.Struct)]
                public RGBQUAD[] bmiColors;
            }

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, June 30, 2020 7:45 AM
  • Thank you for your reply Timon.

    If possible, kindly share C# code to convert the EMF to BMP using PInvoke you have shared above.

    Tuesday, June 30, 2020 9:14 AM
  • A1, C2, E3, G4 are not in "no color", they are in white.

    If I fill your EMF file in red =>

    Tuesday, June 30, 2020 11:56 AM
  • Yes. Font Color as White.

    We want EMF to PNG like Excel print preview without displaying the data with white font color.

    Tuesday, June 30, 2020 1:58 PM
  • Yes. Font Color as White.

    We want EMF to PNG like Excel print preview without displaying the data with white font color.

    But Excel print preview has a white background

    So with white on white, it is normal that you don't see them.

    (if I convert your .EMF file into .PNG with for example IShellImageData::Decode, I get a transparent background and white characters can be seen, but not if I fill the image in white)

    Tuesday, June 30, 2020 3:32 PM
  • Even in my sample also I am using below code to set white background. But still Excel white background data is visible.

    g.Clear(System.Drawing.Color.White);

    >(if I convert your .EMF file into .PNG with for example IShellImageData::Decode, I get a transparent background >and white characters can be seen, but not if I fill the image in white)

    Could please share the code to convert EMF to PNG using IShellImageData::Decode

    Wednesday, July 1, 2020 9:44 AM
  • You can modify pixels like you want with Bitmap.LockBits

    For example, a test with your file where I convert and save the default .PNG (transparent background)
    and another one with white background =>

    using (System.Drawing.Image image = System.Drawing.Image.FromFile("C:\\Users\\Christian\\Downloads\\test.emf"))
    {
        image.Save("C:\\Users\\Christian\\Downloads\\test_emf_converted.png", System.Drawing.Imaging.ImageFormat.Png);
        Bitmap bmp = new Bitmap(image);            
        System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        Bitmap newBitmap = new Bitmap(bmp.Width, bmp.Height, bmpData.Stride, System.Drawing.Imaging.PixelFormat.Format32bppArgb, bmpData.Scan0);
        IntPtr pPixelData = bmpData.Scan0;
    
        int nNumBytes = bmpData.Stride * bmp.Height;
        byte[] pixels = new byte[nNumBytes];
        Marshal.Copy(pPixelData, pixels, 0, nNumBytes);
        int nPixelSize = 4;
        for (int nY = 0; nY < bmpData.Height; nY++)
        {
            for (int nX = 0; nX < bmpData.Width; nX++)
            {
                int nPos = nY * bmpData.Stride + nX * nPixelSize;
                byte b = pixels[nPos], g = pixels[nPos + 1], r = pixels[nPos + 2], a = pixels[nPos + 3];
                // remove Alpha and change black to white
                if (b == 0 && g == 0 && r == 0 && a == 0)
                {
                    pixels[nPos] = 255;
                    pixels[nPos + 1] = 255;
                    pixels[nPos + 2] = 255;
                    pixels[nPos + 3] = 255;
                }                           
            }
        }
    
        Marshal.Copy(pixels, 0, pPixelData, nNumBytes);
        bmp.UnlockBits(bmpData);
        newBitmap.Save("C:\\Users\\Christian\\Downloads\\test_emf_converted_white.png", System.Drawing.Imaging.ImageFormat.Png);
    }

    Wednesday, July 1, 2020 10:58 AM
  • Thank you for your reply with code.

    I do not want white background, my point is how not to show the A1, C2, E3 and G4 cell data while converting the EMF to PNG.

    From your code both test_emf_converted.png and test_emf_converted_white.png are displaying those cell data.

    Friday, July 3, 2020 7:04 AM
  • Thank you for your reply with code.

    I do not want white background, my point is how not to show the A1, C2, E3 and G4 cell data while converting the EMF to PNG.

    From your code both test_emf_converted.png and test_emf_converted_white.png are displaying those cell data.

    As those characters are white (255, 255, 255) + opacity 255, you don't see them only if the background is white (255, 255, 255 instead of 0, 0, 0), like in Excel or in test_emf_converted_white.png or if you change R, G, B to background R, G, B



    • Edited by Castorix31 Friday, July 3, 2020 7:37 AM
    Friday, July 3, 2020 7:18 AM
  • But still test_emf_convereted_white.png is displaying those cell data. Please refer attached.
    Friday, July 3, 2020 11:35 AM
  • I get  A1, C2, E3 and G4 totally white in my test :

    I uploaded the original file and the 2 resulting files : testemf.zip


    • Edited by Castorix31 Friday, July 3, 2020 12:08 PM
    Friday, July 3, 2020 12:07 PM