简体   繁体   English

使用 RenderTargetBitmap 保存部分显示的图像

[英]Using RenderTargetBitmap to save a portion of the displayed images

I have a simple WPF application where I display one very large image (9000x2875) and on top of it, many small images (64x64).我有一个简单的 WPF 应用程序,我在其中显示一个非常大的图像 (9000x2875),在它上面显示许多小图像 (64x64)。

To do this, I have a Canvas with one Image , then I programatically add the small images as they arrive.为此,我有一个Canvas和一个Image ,然后我在小图像到达时以编程方式添加它们。

Now I am trying to save portions of the composite image as png files.现在我正在尝试将部分合成图像保存为png文件。 I thought I would use a RenderTargetBitmap to render the portion of the Canvas that I wanted.我想我会使用RenderTargetBitmap来渲染我想要的Canvas部分。 My problem is that I cannot find a good way to save the right portion of the image.我的问题是我找不到保存图像正确部分的好方法。 Here is a my current hack:这是我目前的黑客:

private static void SaveImage(Canvas canvas, string file, int x, int y, int width, int height)
{
  //changing 0,0 on the canvas so RenderTargetBitmap works as expected.
  canvas.RenderTransform = new MatrixTransform(1d, 0d, 0d, 1d, -x, -y);
  canvas.UpdateLayout();
  RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, 96d, 96d, Pixelformats.Pbgra32);
  bmp.Render(canvas);
  PngBitmapEncoder encoder = new PngBitmapEncoder();
  encoder.Frames.Add(BitmapFrame.Create(bmp));
  using(Stream s = File.Create(file))
  {
    encoder.Save(s);
  }
}

The obvious problem with this is that the display will change due to the RenderTransform .明显的问题是显示会因RenderTransform而改变。 It also makes the application slower.它还使应用程序变慢。 I did try to do a RenderTargetBitmap of the entire canvas, but that was much slower than doing this.我确实尝试过对整个 canvas 进行 RenderTargetBitmap,但这比这样做要慢得多。

So my questions are:所以我的问题是:
Is there an easier way to save just a portion of the viewed image?有没有更简单的方法来保存查看的图像的一部分?
If not, does someone have a suggestion for a better way to go about this?如果没有,有人对 go 有更好的建议吗? (I already tried a single WriteableBitmap , but that was about as slow as doing the RenderTargetBitmap of the entire canvas. (我已经尝试过单个WriteableBitmap ,但这与整个 canvas 的RenderTargetBitmap一样慢。

What you want to use is a CroppedBitmap , which will allow you to save a cropped portion of your image.您要使用的是CroppedBitmap ,它将允许您保存图像的裁剪部分。

// (BitmapSource bmps)
CroppedBitmap crop = new CroppedBitmap(bmps, new Int32Rect(selRect.X, selRect.Y, selRect.Width, selRect.Height));

Edit: Since there seems to be no way to get this to perform the way you want in WPF I would suggest pre-cropping the large image using GDI+ (without displaying it) and loading the region of it you want onto a smaller canvas.编辑:由于似乎没有办法让它在 WPF 中按照您想要的方式执行,我建议使用 GDI+ 预先裁剪大图像(不显示它)并将您想要的区域加载到较小的 canvas 上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM