0

似乎之前已经提出过这个问题的变体,但不是这个问题。此外,它似乎BitmapImages与 Straight 不同Bitmaps。所以我们开始:

我有一个BitmapImage x:Name="HeightMapImage"指向x:Name="image"内部的图像,ContentPresenter x:Name="contentPresenter"它位于Viewbox x:Name="viewBox". 我想在HeightMapImage.

这种设置的原因BitmapImage是正在滚动和缩放。当我BitmapImage在 X 处绘图时,我也希望它能够自动滚动和缩放。

多年来,我是一个非常老的极客,为许多不同 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

您可以使用 WriteableBitmap 代替(或实际上除了)BitmapImage。首先像往常一样创建您的 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);
}

编辑:对考虑覆盖颜色 alpha 值的 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);
}

另请注意,一次设置更多像素会更有效。理想情况下,您会一次设置所有叠加像素。您可以将所有像素值复制到一个大数组中,如上所示计算它们的新 RGB 值,然后一次将它们全部写回。

于 2013-05-26T17:45:32.360 回答