なぜBitmapSource.Createは、ArgumentExceptionがスローしていますか?
-
22-09-2019 - |
質問
私がイメージしてた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がスローされます。これは、これを行う方法はありませんか?私は適切にその呼び出しを行っていないだろうか?
解決
あなたのストライドが正しくありません。ストライドのいずれの走査線のために割り当てられたバイト数であります ビットマップ。このため、以下を使用します:
をint stride = ((RenderWidth * 32 + 31) & ~31) / 8;
と上で定義されたとおり0
と最後のパラメータ(現在stride
)を置き換えます。
ここで神秘的なストライド公式の説明があります:
ファクト:走査線が(参照の)32ビット境界に位置合わせされなければなりませんます。
走査線あたりのバイト数のナイーブな式は次のようになります。
(width * bpp) / 8
しかし、これは8でさえされていない可能性があります、私たちに割り切れるを(* BPP幅)32ビット境界と上に整列ビットマップを与えていない可能性があります。
そうは、私たちがやっていることは、我々は(我々はそのwidth > 0
を仮定)行に少なくとも32ビットを持っている私たちのビットマップを強制されます
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
でない場合をカバーするために少しを追加するので(ストライドが4である。広い1つのBPPを使用してビットマップ1つのピクセルを考えると素朴な式は、パディングが4であることを言うだろうが、現実には3です)バイト境界とし、我々は、上記で与えられた正しい式を取得します。