如何使CroppedBitmap透明化?

时间:2017-03-28 13:20:51

标签: c# wpf bitmap transparent

我有一个裁剪位图:

 CroppedBitmap crop = new CroppedBitmap(rtb, new Int32Rect(MapOffset, MapOffset, BOARD_WIDTH - 1 - MapOffset, BOARD_HEIGHT - 1 - MapOffset));

我需要将白色设置为透明。不幸的是,这不起作用(CroppedBitmap不包含'MakeTransparent'的定义):

crop.MakeTransparent(Colors.White);

有人有什么想法/建议吗?

提前致谢。

~~~~~~~~~~~~~~~

我找到了这段代码How can I make all white (FFFFFFFF) pixel in an image(ImageBrush) to be transparent

但是当我实施它时

    public void SaveMainCanvas2BMP(string filename)
    {

        // Write BMP
        VisualBrush sourceBrush = new VisualBrush(MainCanvas);
        DrawingVisual drawingVisual = new DrawingVisual();
        DrawingContext drawingContext = drawingVisual.RenderOpen();
        using (drawingContext)
        {
            drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(- MapOffset, - MapOffset), new Point(BOARD_WIDTH - 1 + MapOffset, BOARD_HEIGHT - 1 + MapOffset)));
        }

        RenderTargetBitmap rtb = new RenderTargetBitmap(BOARD_WIDTH - 1, BOARD_HEIGHT - 1, 96, 96, PixelFormats.Default);
        rtb.Render(drawingVisual);

        //crops  rectangle at position (0,0).
        CroppedBitmap crop = new CroppedBitmap(rtb, new Int32Rect(0, 0, BOARD_WIDTH - 1, BOARD_HEIGHT - 1));

        WriteableBitmap writeable = new WriteableBitmap(crop);

        // Code to turn WHITE pixels TRANSPARENT
        int pixelWidth = (int)writeable.Width;
        int pixelHeight = (int)writeable.Height;
        int Stride = pixelWidth * 4;

        BitmapSource imgSource = (BitmapSource)writeable;
        byte[] pixels = new byte[pixelHeight * Stride];
        imgSource.CopyPixels(pixels, Stride, 0);
        byte TransparentByte = byte.Parse("0");
        byte Byte255 = byte.Parse("255");
        int N = pixelWidth * pixelHeight;
        //Operate the pixels directly
        for (int i = 0; i < N; i++)
        {
            byte a = pixels[i * 4];
            byte b = pixels[i * 4 + 1];
            byte c = pixels[i * 4 + 2];
            byte d = pixels[i * 4 + 3];
            if (a == Byte255 && b == Byte255 && c == Byte255 && d == Byte255)
            {
                pixels[i * 4] = TransparentByte;
                pixels[i * 4 + 1] = TransparentByte;
                pixels[i * 4 + 2] = TransparentByte;
                pixels[i * 4 + 3] = TransparentByte;
            }
        }
        WriteableBitmap writeableBitmap = new WriteableBitmap(pixelWidth, pixelHeight, 96, 96,
            PixelFormats.Pbgra32, BitmapPalettes.Halftone256Transparent);
        writeableBitmap.WritePixels(new Int32Rect(0, 0, pixelWidth, pixelHeight), pixels, Stride, 0);



        //encode as BMP
        BitmapEncoder bmpEncoder = new BmpBitmapEncoder();

        bmpEncoder.Frames.Add(BitmapFrame.Create(writeableBitmap));

        //save to memory stream
        System.IO.MemoryStream ms = new System.IO.MemoryStream();
        bmpEncoder.Save(ms);
        ms.Close();
        System.IO.File.WriteAllBytes(filename, ms.ToArray());
    }

它不会使白色透明;它用黑色代替WHITE:

enter image description here

EDIT 解

解决方案就在这里(问题与WPF和透明度有关): Solution to transparency problem

2 个答案:

答案 0 :(得分:1)

一种可能的变体是从CroppedBitmap创建可写位图:

WriteableBitmap writeable = new WriteableBitmap(cropped);

然后,您可以分析位图的每个像素,并将白色像素更改为透明像素。最快的方法是使用Lock方法获取像素缓冲区,然后使用不安全的代码循环遍历BackBuffer。更简单但更慢的方法是使用CopyPixelsWritePixels方法。

答案 1 :(得分:0)

问题在于WPF处理透明度的方式(BMP不是可行的方式,PNG是)。

这里的解决方案: Solution to transparency problem