8

ImageとBitmapSourceを使用して、生データから作成されたビットマップを取得してWPFに表示しようとしています。

Int32[] data = new Int32[RenderHeight * RenderWidth];

for (Int32 i = 0; i < RenderHeight; i++)
{
    for (Int32 j = 0; j < RenderWidth; j++)
    {
        Int32 index = j + (i * RenderHeight);

        if (i + j % 2 == 0)
            data[index] = 0xFF0000;
        else
            data[index] = 0x00FF00;
    }
}

BitmapSource source = BitmapSource.Create(RenderWidth, RenderHeight, 96.0, 96.0, PixelFormats.Bgr32, null, data, 0);

RenderImage.Source = source;

ただし、BitmapSource.Createを呼び出すと、「値が期待される範囲内にありません」というArgumentExceptionがスローされます。これはこれを行う方法ではありませんか?私はその電話をきちんとかけていませんか?

4

1 に答える 1

39

あなたの歩幅は正しくありません。ストライドは、ビットマップの1つのスキャンラインに割り当てられたバイト数です。したがって、以下を使用します。

int stride = ((RenderWidth * 32 + 31) & ~31) / 8;

0最後のパラメータ(現在)をstride上記で定義したものに置き換えます。

神秘的なストライド式の説明は次のとおりです。

事実:スキャンラインは32ビット境界に位置合わせする必要があります(参照)。

スキャンラインあたりのバイト数の単純な式は次のようになります。

(width * bpp) / 8

ただし、これでは32ビット境界に整列されたビットマップが得られない可能性があり、(width * bpp)は8で割り切れない可能性があります。

したがって、私たちが行うことは、ビットマップに少なくとも32ビットを連続して持たせることです(私たちはそれを仮定しwidth > 0ます):

width * bpp + 31

次に、32ビット境界で整列しようとしているため、下位ビット(ビット0〜4)は気にしないと言います。

(width * bpp + 31) & ~31

次に、8で割ってバイトに戻ります。

((width * bpp + 31) & ~31) / 8

パディングは次のように計算できます

int padding = stride - (((width * bpp) + 7) / 8)

素朴な式は

stride - ((width * bpp) / 8)

ただしwidth * bpp、バイト境界に整列しない可能性があり、整列しない場合、この式はパディングをバイト単位でカウントしすぎます。width * bpp(1 bppを使用する1ピクセル幅のビットマップを考えてみてください。ストライドは4で、単純な式ではパディングは4ですが、実際には3です。)したがって、バイトではない場合をカバーするために少し追加します。境界を設定すると、上記の正しい式が得られます。

于 2009-12-31T04:10:39.923 に答える