Использование RenderTargetBitmap для сохранения части отображаемых изображений - PullRequest
1 голос
/ 19 июля 2011

У меня есть простое приложение WPF, в котором я отображаю одно очень большое изображение (9000x2875), а поверх него множество маленьких изображений (64x64).

Для этого у меня есть Canvas с одним Image, затем я программно добавляю маленькие изображения по мере их поступления.

Теперь я пытаюсь сохранить части составного изображения в виде png файлов. Я думал, что буду использовать RenderTargetBitmap для рендеринга части Canvas, которую я хотел. Моя проблема в том, что я не могу найти хороший способ сохранить правильную часть изображения. Вот мой текущий хак:

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);
  }
}

Очевидная проблема с этим состоит в том, что дисплей изменится из-за RenderTransform. Это также замедляет работу приложения. Я попытался сделать RenderTargetBitmap всего холста, но это было намного медленнее, чем это.

Итак, мои вопросы:
Есть ли более простой способ сохранить только часть просмотренного изображения?
Если нет, есть ли у кого-нибудь предложение для лучшего способа обойти это? (Я уже пробовал один WriteableBitmap, но это было примерно так же медленно, как и RenderTargetBitmap всего холста.

1 Ответ

3 голосов
/ 19 июля 2011

То, что вы хотите использовать, это CroppedBitmap , который позволит вам сохранить обрезанную часть вашего изображения.

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

Редактировать: Поскольку, кажется, нет способа заставить это работать так, как вы хотите в WPF, я бы предложил предварительно обрезать большое изображение с помощью GDI + (без его отображения) и загрузить область это вы хотите на меньший холст.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...