1

私は本質的に色の2次元配列であり、各インデックスはピクセルを表し、値はそのピクセルの色です。簡単にするために、基本的に1ピクセルの赤の行、1ピクセルの緑の行、1ピクセルの青の行を持つ3x3ピクセルの配列を想像してみましょう。

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たが、それらを機能させることができないようです。たとえば、次のコード(画面全体を黄色にペイントしようとしている場合)は、白い画像(ここから借用)になります。

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;
4

3 に答える 3

4

次のコードは、ビットマップソースと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;
于 2012-08-14T04:52:52.507 に答える
1

このブログでは、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);
于 2012-08-13T07:56:33.027 に答える
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;

しかし、全体像を描きたい場合は、毎回1ピクセルを書くべきではありません。非常に遅い場合があります。代わりに、バイト配列を埋めて、部分ごとのインスタンスにコピーする必要がありますWritableBitmap

于 2012-08-13T08:00:48.110 に答える