dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.48k stars 4.76k forks source link

Zero length EMF file [System.Drawing.Common][.Net Core][Linux] #45646

Closed AsposeAG closed 1 year ago

AsposeAG commented 3 years ago

Writing data to EMF file on Linux creates Zero length file on disk.

static string folder = @"d:\save\rec";
using (FileStream fstr = new FileStream(Path.Combine(folder, "metareal.emf"), FileMode.Create))
{
    MemoryStream ms = new MemoryStream();
    Metafile mf = EmfHelpers.CreateMetafileFromStream(ms, 200, 200);
    using (Graphics graph = EmfHelpers.CreateGraphicsFromMetafile(mf, 200, 200))
        DrawShapesOnImage(graph);

    fstr.Write(ms.ToArray(), 0, (int)ms.Length);
}

static void DrawShapesOnImage(Graphics graph)
{
    SolidBrush lYb = new SolidBrush(Color.Yellow);
    SolidBrush lCb = new SolidBrush(Color.Cyan);
    SolidBrush lMb = new SolidBrush(Color.Magenta);
    SolidBrush lKb = new SolidBrush(Color.Black);

    graph.Clear(Color.White);
    graph.FillRectangle(lYb, new Rectangle(20, 20, 80, 80));
    graph.FillRectangle(lCb, new Rectangle(100, 20, 80, 80));
    graph.FillRectangle(lMb, new Rectangle(20, 100, 80, 80));
    graph.FillRectangle(lKb, new Rectangle(100, 100, 80, 80));
}

class EmfHelpers
{
    //https://www.codeproject.com/Articles/177394/Working-with-Metafile-Images-in-NET
    public static Metafile CreateMetafileFromStream(Stream stream, int width, int height)
    {
        using (Graphics offScreenBufferGraphics = Graphics.FromImage(new Bitmap(1,1)))
        {
            IntPtr hdc = offScreenBufferGraphics.GetHdc();
            Metafile m = new Metafile(stream, hdc, new RectangleF(0, 0, width, height), MetafileFrameUnit.Pixel, EmfType.EmfPlusOnly);
            offScreenBufferGraphics.ReleaseHdc();
            return m;
        }
    }

    public static Graphics CreateGraphicsFromMetafile(Metafile meta, int width, int height)
    {
        Graphics graphics = Graphics.FromImage(meta);
        graphics.SetClip(new RectangleF(0, 0, width, height));
        graphics.PageUnit = GraphicsUnit.Pixel;
        return graphics;
    }
}

System Info: Kubuntu 20.04 .Net Core 3.1 System.Drawing.Common 5.0

Example project: [EmfBug.zip]EmfBug.zip

ghost commented 3 years ago

Tagging subscribers to this area: @safern, @tannergooding See info in area-owners.md if you want to be subscribed.

Issue Details
Writing data to EMF file on Linux creates Zero length file on disk. ```charp static string folder = @"d:\save\rec"; using (FileStream fstr = new FileStream(Path.Combine(folder, "metareal.emf"), FileMode.Create)) { MemoryStream ms = new MemoryStream(); Metafile mf = EmfHelpers.CreateMetafileFromStream(ms, 200, 200); using (Graphics graph = EmfHelpers.CreateGraphicsFromMetafile(mf, 200, 200)) DrawShapesOnImage(graph); fstr.Write(ms.ToArray(), 0, (int)ms.Length); } static void DrawShapesOnImage(Graphics graph) { SolidBrush lYb = new SolidBrush(Color.Yellow); SolidBrush lCb = new SolidBrush(Color.Cyan); SolidBrush lMb = new SolidBrush(Color.Magenta); SolidBrush lKb = new SolidBrush(Color.Black); graph.Clear(Color.White); graph.FillRectangle(lYb, new Rectangle(20, 20, 80, 80)); graph.FillRectangle(lCb, new Rectangle(100, 20, 80, 80)); graph.FillRectangle(lMb, new Rectangle(20, 100, 80, 80)); graph.FillRectangle(lKb, new Rectangle(100, 100, 80, 80)); } class EmfHelpers { //https://www.codeproject.com/Articles/177394/Working-with-Metafile-Images-in-NET public static Metafile CreateMetafileFromStream(Stream stream, int width, int height) { using (Graphics offScreenBufferGraphics = Graphics.FromImage(new Bitmap(1,1))) { IntPtr hdc = offScreenBufferGraphics.GetHdc(); Metafile m = new Metafile(stream, hdc, new RectangleF(0, 0, width, height), MetafileFrameUnit.Pixel, EmfType.EmfPlusOnly); offScreenBufferGraphics.ReleaseHdc(); return m; } } public static Graphics CreateGraphicsFromMetafile(Metafile meta, int width, int height) { Graphics graphics = Graphics.FromImage(meta); graphics.SetClip(new RectangleF(0, 0, width, height)); graphics.PageUnit = GraphicsUnit.Pixel; return graphics; } } ``` System Info: Kubuntu 20.04 .Net Core 3.1 System.Drawing.Common 5.0 Example project: [EmfBug.zip][EmfBug.zip](https://github.com/dotnet/runtime/files/5648457/EmfBug.zip)
Author: AsposeAG
Assignees: -
Labels: `area-System.Drawing`, `untriaged`
Milestone: -
safern commented 3 years ago

Thanks, @AsposeAG. I added it to future as I believe this might be related to us using libgdiplus external library for drawing operations, however we are investigating on what our story for System.Drawing should be on Unix and will get back to these issues.

badpaybad commented 3 years ago

Hi, Could some one help, or suggest other way to do? I read image from ms word (ImagePart), in my laptop window worked well In centos 7, I got blank image

                            stream.Position = 0;
            using (Metafile img = new Metafile(stream))
            {
                MetafileHeader header = img.GetMetafileHeader();
                float scale = header.DpiX / 96f;
                int width = (int)(scale * img.Width / header.DpiX * 100);
                int height = (int)(scale * img.Height / header.DpiY * 100);

                Bitmap bitmap = new Bitmap(width, height);
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.Clear(System.Drawing.Color.White);
                    g.ScaleTransform(scale, scale);
                    g.DrawImage(img, 0, 0);

                }

                return bitmap;
            }
JeremyKuhne commented 1 year ago

Closing this issue as System.Drawing.Common is only supported on Windows now.