从BitmapSource复制到WritableBitmap

9

我正在尝试将BitmapSource的一部分复制到WritableBitmap中。

这是我目前的代码:

var bmp = image.Source as BitmapSource;
var row = new WriteableBitmap(bmp.PixelWidth, bottom - top, bmp.DpiX, bmp.DpiY, bmp.Format, bmp.Palette);
row.Lock();
bmp.CopyPixels(new Int32Rect(top, 0, bmp.PixelWidth, bottom - top), row.BackBuffer, row.PixelHeight * row.BackBufferStride, row.BackBufferStride);
row.AddDirtyRect(new Int32Rect(0, 0, row.PixelWidth, row.PixelHeight));
row.Unlock();

我遇到了"ArgumentException: Value does not fall within the expected range."的问题,出现在CopyPixels这一行。

我尝试将row.PixelHeight * row.BackBufferStriderow.PixelHeight * row.PixelWidth交换,但是我得到了一个错误,说这个值太低了。

我找不到任何使用这个重载版本的CopyPixels的代码示例,所以想请教一下。

谢谢!

1个回答

20

你想要复制图片的哪一部分?改变目标构造函数中的宽度和高度,以及Int32Rect中的宽度和高度,还有前两个参数(0,0),它们是图像中的x和y偏移量。如果你想要复制整张图片,可以直接不修改这些参数。

BitmapSource source = sourceImage.Source as BitmapSource;

// Calculate stride of source
int stride = source.PixelWidth * (source.Format.BitsPerPixel + 7) / 8;

// Create data array to hold source pixel data
byte[] data = new byte[stride * source.PixelHeight];

// Copy source image pixels to the data array
source.CopyPixels(data, stride, 0);

// Create WriteableBitmap to copy the pixel data to.      
WriteableBitmap target = new WriteableBitmap(
  source.PixelWidth, 
  source.PixelHeight, 
  source.DpiX, source.DpiY, 
  source.Format, null);

// Write the pixel data to the WriteableBitmap.
target.WritePixels(
  new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight), 
  data, stride, 0);

// Set the WriteableBitmap as the source for the <Image> element 
// in XAML so you can see the result of the copy
targetImage.Source = target;

谢谢!我有点希望能够直接从BitmapSource复制到WritableBitmap...现在我想知道这个CopyPixels的重载实际上是用来做什么的... - Ramon Snir
1
矩形重载将位图图像复制到Int32Rect中,因此将其传递给WriteableBitmap并不是很有用。如果您想要非常简短的代码并且想要复制整个图像:
  • WriteableBitmap target = new WriteableBitmap(Pic1.Source as BitmapSource); Pic2.Source = target; *
- Dominic
如果我只需要BitmapSource的一部分(我需要一个高度相对较小且宽度相同的矩形),该怎么办? - Ramon Snir
6
如果您每个像素使用一个字节,这将会出现问题。"每像素字节数"的正确步幅计算是(bitsPerPixel + 7) / 8。请注意,我已经尽力使翻译尽可能简洁明了,并保持原意不变。 - Kevin Shea
1
答案中有 width * (bitsPerPixel + 7) / 8。它不应该是 width * ((bitsPerPixel + 7) / 8) 吗? - mafu
为了增加我的困惑,https://learn.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/how-to-create-a-new-bitmapsource 使用了 (width * pf.BitsPerPixel + 7) / 8 - mafu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接