开发者

Using RenderTargetBitmap to save a portion of the displayed images

开发者 https://www.devze.com 2023-03-21 16:39 出处:网络
I have a simple WPF application where I display one very large image (9000x2875) and on top of it, many small images (64x64).

I have a simple WPF application where I display one very large image (9000x2875) and on top of it, many small images (64x64).

To do this, I have a Canvas with one Image, then I programatically add the small images as they arrive.

Now I am trying to save portions of the composite image as png files. I thought I would use a RenderTargetBitmap to render the portion of the Canvas that I wanted. 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. 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.

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? (I already tried a single WriteableBitmap, but that was about as slow as doing the RenderTargetBitmap of the entire canvas.


What you want to use is a CroppedBitmap, which will allow you to save a cropped portion of your image.

// (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.

0

精彩评论

暂无评论...
验证码 换一张
取 消