C# 如何使裁剪的位图透明?
我有一个裁剪过的位图:C# 如何使裁剪的位图透明?,c#,wpf,bitmap,transparent,C#,Wpf,Bitmap,Transparent,我有一个裁剪过的位图: CroppedBitmap crop = new CroppedBitmap(rtb, new Int32Rect(MapOffset, MapOffset, BOARD_WIDTH - 1 - MapOffset, BOARD_HEIGHT - 1 - MapOffset)); 我需要将白色设置为透明。很遗憾,这不起作用裁剪位图不包含“MakeTransparent”的定义: crop.MakeTransparent(Colors.White); 有人有什么想法/
CroppedBitmap crop = new CroppedBitmap(rtb, new Int32Rect(MapOffset, MapOffset, BOARD_WIDTH - 1 - MapOffset, BOARD_HEIGHT - 1 - MapOffset));
我需要将白色设置为透明。很遗憾,这不起作用裁剪位图不包含“MakeTransparent”的定义:
crop.MakeTransparent(Colors.White);
有人有什么想法/建议吗
提前谢谢
~~~~~~~~~~~~~~~
我找到了这个密码
但是当我实施它的时候
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());
}
它不能使白色透明;它用黑色代替白色:
编辑
解决方案
解决方案就在这里问题与WPF和透明度有关:
一种可能的变体是从裁剪的位图创建可写位图:
WriteableBitmap writeable = new WriteableBitmap(cropped);
然后,您可以分析位图的每个像素,并将白色像素更改为透明像素。最快的方法是使用Lock方法获取像素缓冲区,然后使用不安全的代码在BackBuffer中循环。更简单但速度较慢的方法是使用CopyPixels和WritePixels方法。问题在于WPF处理透明度的方式。BMP不是解决方法,PNG是 解决方案如下:
您知道有一个链接演示了如何使用锁定方法获取像素缓冲区,然后使用不安全代码在BackBuffer中循环吗?MSDN上有一个示例:请参阅页面底部示例中的DrawPixel方法。但它并不完美,因为它们将IntPtr强制转换为int,因此在64位平台上可能会失败。您应该将它改为byte*,并直接使用指针。请注意,您可以在一次锁定调用后处理所有字节,然后在最后调用Unlock。