1

WinRTアプリで各ピクセルのRGB値を取得しようとしています。を含むバイトの配列にアクセスできますが、PixelDataそれを操作する方法がわからないので、バイト配列からRGB情報を抽出するにはどうすればよいですか?

var bd = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
var pd = await bd.GetPixelDataAsync();
var tempBuffer = pd.DetachPixelData();
var PixelMatrix = new byte[bd.PixelWidth, bd.PixelHeight];
// how do I get the RGB value for PixelMatrix[0,0]?
4

2 に答える 2

1

あなたはRGB画像を持っているので、tempBuffer[k + 0]は赤のチャンネル、tempBuffer[k + 1]は緑のチャンネル、tempBuffer[k + 2]は青のチャンネルです。つまりtempBuffer、 は1D配列です。すべてのピクセルをループする場合、この擬似コードは次のようになります。

for i = 0 to height - 1
    for j = 0 to width - 1
        k = (i * width + j) * 3
        r, g, b = tempBuffer[k + 0], tempBuffer[k + 1], tempBuffer[k + 2]
于 2012-12-18T18:17:23.663 に答える
1

Marshal クラスは WinRT では使用できないため、最もパフォーマンスの高い方法は、SafeMemoryMappedViewHandle (SafeBuffer) を使用することです。

このメソッドは、BinaryReader を使用してコンポーネントごとに読み取る必要なく、マルチバイト コンポーネントでピクセル形式を処理することもできます (コンポーネントあたり 16 ビットの RGBA16)。デコーダーのBitmapPixelFormatプロパティを使用してピクセル形式を調べ、適切に宣言された構造体を使用します。

    // declare more of these appropriately laid
    // out structures for different pixel formats
    struct RGBA16
    {
        public uint R;
        public uint G;
        public uint B;
        public uint A;
    }

    struct RGBA8
    {
        public byte R;
        public byte G;
        public byte B;
        public byte A;
    }

    struct BRGA8
    {
        public byte B;
        public byte G;
        public byte R;
        public byte A;
    }
    ...

    var handle = GCHandle.Alloc(tempBuffer /* the raw byte[] */, GCHandleType.Pinned);
    try
    {
        var ptr = handle.AddrOfPinnedObject();
        var safeBuffer = new SafeMemoryMappedViewHandle(true /* I believe DetachPixelData returns a copy? false otherwise  */)
        safeBuffer.SetHandle(ptr);

        #if STREAM_PROCESSING
            // pixel by pixel
            int offset = 0;
            for (int i = 0; i < width * height; i++)
            {
                var pixel = safeBuffer.Read<RGBA16>(offset);
                offset += RGB24bpp.Size;
            }
        #else
            // Read it all in at once - this makes a copy
            var pixels = new RGBA16[width * height];
            safeBuffer.ReadArray<RGBA16>(0, pixels, 0, width * height);
        #endif
    }
    finally
    {
        safeBuffer.Dispose();
        handle.Free;
    }

: このメソッドは、Marshal.PtrToStructure または WinRT での同等の操作を必要とする操作の代わりにもなります。

于 2012-12-18T18:45:14.423 に答える