0

この質問のバリエーションは以前に尋ねられたようですが、具体的にはそうではありません。また、BitmapImagesストレートとは違うようですBitmaps。だからここに行きます:

の中にある ImageをBitmapImage x:Name="HeightMapImage"指しているがあります。上の特定の X、Y 座標で半透明と非透明の両方を描画したいと考えています。x:Name="image"ContentPresenter x:Name="contentPresenter"Viewbox x:Name="viewBox"HeightMapImage

この設定の理由は、BitmapImageがスクロールおよびズームされているためです。X,Yで描画すると、BitmapImageそれも自動的にスクロールしてズームしたい。

私は非常に古いオタクで、何年にもわたって多くの異なる GDI で多くのマシンについて書いてきました。これは、グラフィック デバイス コンテキストの問題の「ハンドルを握る」ように思えます。

よろしくお願いいたします。

誰かがコードを見たいと思っていました。は次のXAMLとおりです。

<Viewbox x:Name="viewBox" Margin="0,0,0,0">
    <ContentPresenter x:Name="contentPresenter" Width="350" Height="350" >
        <ContentPresenter.Content>
            <Image x:Name="image" Width="350" Height="350">
                <Image.Source>
                    <BitmapImage x:Name="HeightMapImage" UriSource="DinoIslandLogo.bmp" />
                </Image.Source>
            </Image>
        </ContentPresenter.Content>
    </ContentPresenter>
</Viewbox>

そして、これは誰かが望んでいたスクリーン キャプチャです。

ここに画像の説明を入力

ユーザーが選択したビットマップを取得し、それを読み込んで表示するコードは次のとおりです。

string selectedFileName = dlg.FileName;
BitmapImage bitmap = new BitmapImage();

bitmap.BeginInit();
bitmap.UriSource = new Uri(selectedFileName);
bitmap.EndInit();

image.Source = bitmap;

これは のために書き直す必要がありWriteable Bitmapますか?

4

1 に答える 1

4

BitmapImage の代わりに (または実際には BitmapImage に加えて) WriteableBitmap を使用できます。まず、通常どおり BitmapImage を作成します (ただし、コードは少なくなります)。

var selectedFileName = dlg.FileName;
var bitmap = new BitmapImage(new Uri(selectedFileName));

次に、BitmapImage から WritableBitmap を作成し、それを Image コントロールに割り当てます。

var writeableBitmap = new WriteableBitmap(bitmap);
image.Source = writeableBitmap;

これで、オーバーレイ データを描画するために WriteableBitmap を変更できます。次のコード スニペットは、ビットマップ内のピクセルを取得および変更する方法を示しています。

if (writeableBitmap.Format.BitsPerPixel == 32)
{
    var x = 10;
    var y = 20;
    var pixelRect = new Int32Rect(x, y, 1, 1);
    var pixelBuffer = new byte[4];
    writeableBitmap.CopyPixels(pixelRect, pixelBuffer, 4, 0);
    // modify pixelBuffer and write it back
    writeableBitmap.WritePixels(pixelRect, pixelBuffer, 4, 0);
}

編集: オーバーレイの色のアルファ値を考慮に入れる SetPixel メソッドの提案。このメソッドは、ビットマップのピクセル形式が Bgr32 であることを前提としていることに注意してください。

public void SetPixel(WriteableBitmap wb, int x, int y, Color color)
{
    var pixelRect = new Int32Rect(x, y, 1, 1);
    var pixelBuffer = new byte[4];
    wb.CopyPixels(pixelRect, pixelBuffer, 4, 0);
    pixelBuffer[0] = (byte)(pixelBuffer[0] * (1F - color.ScA) + color.B * color.ScA);
    pixelBuffer[1] = (byte)(pixelBuffer[1] * (1F - color.ScA) + color.G * color.ScA);
    pixelBuffer[2] = (byte)(pixelBuffer[2] * (1F - color.ScA) + color.R * color.ScA);
    wb.WritePixels(pixelRect, pixelBuffer, 4, 0);
}

一度に多くのピクセルを設定する方がはるかに効率的であることにも注意してください。すべてのオーバーレイ ピクセルを一度に設定するのが理想的です。すべてのピクセル値を 1 つの大きな配列にコピーし、上記のように新しい RGB 値を計算してから、一度にすべて書き戻します。

于 2013-05-26T17:45:32.360 に答える