我的本质上是一个二维颜色数组,每个索引代表像素,值是该像素的颜色。为简单起见,让我们设想一个3x3像素阵列,基本上有1像素的红色行,1像素的绿色行和1像素的蓝色行:
Color[,] colorArray = new Color[3,3];
for (int i = 0; i < 3; ++i)
{
colorArray[0,i] = Colors.Red;
colorArray[1,i] = Colors.Green;
colorArray[2,i] = Colors.Blue;
}
我有一个带有图像的XAML文件(为简单起见,我们假设图像也是3x3像素)。如何将上述像素数据写入可以在该图像文件中显示的内容?
修改
我尝试过同时使用WriteableBitmaps
和BitmapSources
,但似乎无法让它们正常运行。例如,下面的代码(我只是试图将整个屏幕画成黄色)会产生一个白色图像(借用here)。
BitmapSource示例
uint[] pixelData = new uint[width * height];
for (int y = 0; y < height; ++y)
{
int yIndex = y * width;
for (int x = 0; x < width; ++x)
{
pixelData[x + yIndex] = (0 << 24) + (255 << 16) + (255 << 8) + 255;
}
}
var bmp = BitmapSource.Create(width, height, dpi, dpi, PixelFormats.Bgra32, null, pixelData, width * 4);
TestImage.Source = bmp;
WriteableBitmap示例
WriteableBitmap wb = new WriteableBitmap(width, height, dpi, dpi, pf, null);
byte[] pixelData = new byte[height * width * 4];
for (int i = 0; i < (int)wb.Height; i++)
{
for (int j = 0; j < (int)wb.Width; j++)
{
var color = colors[i, j];
var idx = j * 4 + i * width * 4;
byte blue = color.B;
byte green = color.G;
byte red = color.R;
pixelData[idx] = blue;
pixelData[idx + 1] = green;
pixelData[idx + 2] = red;
pixelData[idx + 3] = 255;
//byte[] colorData = { blue, green, red, 255 };
//Int32Rect rect = new Int32Rect(j, i, 1, 1);
//wb.WritePixels(rect, colorData, 4, 0);
}
}
Int32Rect rect = new Int32Rect(0, 0, width, height);
wb.WritePixels(rect, pixelData, 4, 0);
TestImage.Source = wb;
答案 0 :(得分:3)
以下代码适用于位图源和32位颜色:
var height = colorArray.GetUpperBound(0) + 1;
var width = colorArray.GetUpperBound(1) + 1;
var pixelFormat = PixelFormats.Bgra32;
var stride = width * 4; // bytes per row
byte[] pixelData = new byte[height * stride];
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
var color = colorArray[y, x];
var index = (y * stride) + (x * 4);
pixelData[index] = color.B;
pixelData[index + 1] = color.G;
pixelData[index + 2] = color.R;
pixelData[index + 3] = color.A; // color.A;
}
}
var bitmap = BitmapSource.Create(width, height, 96, 96, pixelFormat, null, pixelData, stride);
Image.Source = bitmap;
答案 1 :(得分:1)
This blog描述了如何使用BitmapSource从带有像素的字节数组创建图像。
以下是该博客的代码:
double dpi = 96;
int width = 128;
int height = 128;
byte[] pixelData = new byte[width*height];
for (int y = 0; y < height; ++y)
{
int yIndex = y * width;
for (int x = 0; x < width; ++x)
{
pixelData[x + yIndex] = (byte) (x + y);
}
}
BitmapSource bmpSource = BitmapSource.Create(width, height, dpi, dpi,PixelFormats.Gray8, null, pixelData, width);
答案 2 :(得分:1)
使用WriteableBitmap
课程。 WritePixels
方法正是您所需要的。 (msdn)
你的例子:
WriteableBitmap wb = new WriteableBitmap(3, 3, 96, 96, PixelFormats.Bgra32, null);
for (int i = 0; i < (int) wb.Height; i++)
{
byte blue = (byte) (i == 2 ? 255 : 0),
green = (byte) (i == 1 ? 255 : 0),
red = (byte) (i == 0 ? 255 : 0);
byte[] colorData = {blue, green, red, 255};
for (int j = 0; j < (int) wb.Width; j++)
{
Int32Rect rect = new Int32Rect(j, i, 1, 1);
wb.WritePixels(rect, colorData, 4, 0);
}
}
img.Source = wb;
但是如果你想绘制一幅大图,你不应该每次写一个像素。它可能很慢。相反,您应该填充字节数组并将其复制到您的WritableBitmap
实例中。