WriteableBitmap 设置像素
WriteableBitmap set pixels
我正在使用 WPF,我想处理图像的一些像素。我正在使用 WritableBitmap,因为我可以从源代码间接使用它。当我尝试设置一些像素 RGB 值(按顺序)时,结果不是我预期的那样。
我使用这个扩展方法来阅读源代码:
public static PixelColor[,] CopyPixels(this BitmapSource source,out int stride)
{
if (source.Format != PixelFormats.Bgra32)
source = new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0);
PixelColor[,] pixels = new PixelColor[source.PixelWidth, source.PixelHeight];
stride = source.PixelWidth * ((source.Format.BitsPerPixel + 7) / 8);
GCHandle pinnedPixels = GCHandle.Alloc(pixels, GCHandleType.Pinned);
source.CopyPixels(
new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight),
pinnedPixels.AddrOfPinnedObject(),
pixels.GetLength(0) * pixels.GetLength(1) * 4, stride);
pinnedPixels.Free();
return pixels;
}
输出结构是
[StructLayout(LayoutKind.Sequential)]
public struct PixelColor
{
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
}
这是将像素(200x200 到 300x300 之间)修改为黑色的简单示例代码:
int stride = 0;
PixelColor[,] PixelData = wBitmap.CopyPixels(out stride);
for (int i = 0; i < PixelData.GetLength(0); i++)
{
for (int j = 0; j < PixelData.GetLength(1); j++)
{
if ((200 < i && 300 > i) && (200 < j && 300 > j))
{
PixelData[i, j].Blue = 0;
PixelData[i, j].Red = 0;
PixelData[i, j].Green = 0;
}
}
}
wBitmap.WritePixels(new Int32Rect(0, 0, wBitmap.PixelWidth, wBitmap.PixelHeight), PixelData, stride,0);
令人惊讶的结果是
这是一张参数为 500x500 的图片。我预计结果将是图像中间的黑色填充正方形而不是黑色垂直线。我的示例代码有什么问题? (线条后面的彩点是原图的一部分。)
只需更改 CopyPixels 方法中二维数组声明中维度的顺序:
var pixels = new PixelColor[source.PixelHeight, source.PixelWidth];
我正在使用 WPF,我想处理图像的一些像素。我正在使用 WritableBitmap,因为我可以从源代码间接使用它。当我尝试设置一些像素 RGB 值(按顺序)时,结果不是我预期的那样。 我使用这个扩展方法来阅读源代码:
public static PixelColor[,] CopyPixels(this BitmapSource source,out int stride)
{
if (source.Format != PixelFormats.Bgra32)
source = new FormatConvertedBitmap(source, PixelFormats.Bgra32, null, 0);
PixelColor[,] pixels = new PixelColor[source.PixelWidth, source.PixelHeight];
stride = source.PixelWidth * ((source.Format.BitsPerPixel + 7) / 8);
GCHandle pinnedPixels = GCHandle.Alloc(pixels, GCHandleType.Pinned);
source.CopyPixels(
new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight),
pinnedPixels.AddrOfPinnedObject(),
pixels.GetLength(0) * pixels.GetLength(1) * 4, stride);
pinnedPixels.Free();
return pixels;
}
输出结构是
[StructLayout(LayoutKind.Sequential)]
public struct PixelColor
{
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
}
这是将像素(200x200 到 300x300 之间)修改为黑色的简单示例代码:
int stride = 0;
PixelColor[,] PixelData = wBitmap.CopyPixels(out stride);
for (int i = 0; i < PixelData.GetLength(0); i++)
{
for (int j = 0; j < PixelData.GetLength(1); j++)
{
if ((200 < i && 300 > i) && (200 < j && 300 > j))
{
PixelData[i, j].Blue = 0;
PixelData[i, j].Red = 0;
PixelData[i, j].Green = 0;
}
}
}
wBitmap.WritePixels(new Int32Rect(0, 0, wBitmap.PixelWidth, wBitmap.PixelHeight), PixelData, stride,0);
令人惊讶的结果是
这是一张参数为 500x500 的图片。我预计结果将是图像中间的黑色填充正方形而不是黑色垂直线。我的示例代码有什么问题? (线条后面的彩点是原图的一部分。)
只需更改 CopyPixels 方法中二维数组声明中维度的顺序:
var pixels = new PixelColor[source.PixelHeight, source.PixelWidth];