Saving Windows.Media.Drawing with BmpBitmapEncoder black image - how to remove alpha?

南楼画角 提交于 2019-12-25 03:54:44

问题


I'm using SVG# (http://sharpvectors.codeplex.com/), to batch convert SVG files to other formats. The SVG images being converted are black line drawings with no background. I've little experience with WPF or the System.Windows.Media namespace, so please excuse me if this is a basic question.

I'm using a modified version of the ImageSvgConverter from SVG#, which accepts a System.Windows.Media.Drawing object, which is then converted using a System.Windows.Media encoder (BmpBitmapEncoder, PngBitmapEncoder etc) to export to the desired file format.

When I export using either a TiffBitmapEncoderor, PngBitmapEncoder or GifBitmap the images are generated as expected. The generated images all have transparent backgrounds.

However, when I export using the JpegBitmapEncoder or BmpBitmapEncoder, all images are coming out black. As the tif, png and gif all have transparent backgrounds, I think that the jpg / bmp images are being drawn correctly, however, as alpha isn't supported in these file formats, having a black output makes sense as the transparency would be interpreted as nothing / black.

I think this is as described in these SO posts Strange bmp black output from BitmapSource - any ideas? , Convert Transparent PNG to JPG with Non-Black Background Color and Background Turns Black When Saving Bitmap - C#.

However, I cannot see a way of applying the solutions is these posts to my problem. Can anyone point me in the right direction?

I have tried applying a white SolidColorBrush to the DrawingContext's PushOpacityMask method, however, this makes no difference.

Really appreciate any pointers.

        private Stream SaveImageFile(Drawing drawing)
    {
        // black output
        BitmapEncoder bitmapEncoder = new BmpBitmapEncoder(); 

        // works
        //bitmapEncoder  = new PngBitmapEncoder();

        // The image parameters...
        Rect drawingBounds = drawing.Bounds;
        int pixelWidth = (int)drawingBounds.Width;
        int pixelHeight = (int)drawingBounds.Height;
        double dpiX = 96;
        double dpiY = 96;

        // The Visual to use as the source of the RenderTargetBitmap.
        DrawingVisual drawingVisual = new DrawingVisual();
        DrawingContext drawingContext = drawingVisual.RenderOpen();

        // makes to difference - still black
        //drawingContext.PushOpacityMask(new SolidColorBrush(System.Windows.Media.Color.FromRgb(255,255,255)));

        drawingContext.DrawDrawing(drawing);
        drawingContext.Close();

        // The BitmapSource that is rendered with a Visual.
        RenderTargetBitmap targetBitmap = new RenderTargetBitmap(pixelWidth, pixelHeight, dpiX, dpiY, PixelFormats.Pbgra32);

        targetBitmap.Render(drawingVisual);

        // Encoding the RenderBitmapTarget as an image file.
        bitmapEncoder.Frames.Add(BitmapFrame.Create(targetBitmap));

        MemoryStream stream = new MemoryStream();
        bitmapEncoder.Save(stream);
        stream.Position = 0;
        return stream;
    }

回答1:


You could draw a filled "background" rectangle with an appropriate size prior to the actual drawing object.

using (var drawingContext = drawingVisual.RenderOpen())
{
    drawingContext.DrawRectangle(Brushes.White, null, new Rect(drawingBounds.Size));
    drawingContext.DrawDrawing(drawing);
}


来源:https://stackoverflow.com/questions/14360378/saving-windows-media-drawing-with-bmpbitmapencoder-black-image-how-to-remove-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!