Как переиспользовать один и тот же bitmap при многократной отрисовке в EMF?

Мне нужно много раз отрисовывать большой TBitmap32 в EMF. Каждый раз битмап один и тот же, но его смещение и размер могут меняться.

Если рисовать наивно (кейс 1), то все работает хорошо, но размер EMF огромен, потому что он сохраняет новую копию битмапа для каждой операции отрисовки.

Было бы здорово, если бы EMF позволял повторно использовать один и тот же исходный битмап в вызовах отрисовки, но это, похоже, не работает (кейс 2).

Использование кисти могло бы быть хорошим решением, но её экземпляры нельзя независимо масштабировать.

Пример кода:

procedure CreateStretchedBitmapEMF(aMode: Integer; const aMetafilePath: string);
var
  Metafile: TMetafile;
  MetafileCanvas: TMetafileCanvas;
  Bitmap32: TBitmap32;
begin
  Metafile := TMetafile.Create;
  Metafile.Width := 800;
  Metafile.Height := 600;
  MetafileCanvas := TMetafileCanvas.Create(Metafile, 0);

  Bitmap32 := TBitmap32.Create;
  Bitmap32.LoadFromFile('sample.bmp'); // 1000x1000px

  case aMode of
    1:  // Работает, но размер файла 39mb
        for var i := 0 to 9 do
          StretchBlt(MetafileCanvas.Handle, i * 60, i * 40, 100, 100, Bitmap32.Handle, 0, 0, Bitmap32.Width, Bitmap32.Height, SRCCOPY);
    2:  // Работает, но размер файла 39mb
        begin
          var TempBitmap := TBitmap.Create;
          TempBitmap.PixelFormat := pf32bit;
          TempBitmap.Width := Bitmap32.Width;
          TempBitmap.Height := Bitmap32.Height;
          Bitmap32.DrawTo(TempBitmap.Canvas.Handle, 0, 0);

          var CompatibleDC: HDC := CreateCompatibleDC(MetafileCanvas.Handle);
          var OldBitmap: HGDIOBJ := SelectObject(CompatibleDC, TempBitmap.Handle);
          for var i := 0 to 9 do
            StretchBlt(MetafileCanvas.Handle, i * 60, i * 40, 100, 100, CompatibleDC, 0, 0, TempBitmap.Width, TempBitmap.Height, SRCCOPY);
          SelectObject(CompatibleDC, OldBitmap);
          DeleteDC(CompatibleDC);
        end;
    3:  // Не работает как надо, но размер файла 3.9mb
        begin
          var TempBitmap := TBitmap.Create;
          TempBitmap.PixelFormat := pf32bit;
          TempBitmap.Width := Bitmap32.Width;
          TempBitmap.Height := Bitmap32.Height;
          Bitmap32.DrawTo(TempBitmap.Canvas.Handle, 0, 0);

          var PatternBrush := CreatePatternBrush(TempBitmap.Handle);
          var OldBrush := SelectObject(MetafileCanvas.Handle, PatternBrush);

          for var i := 0 to 9 do
          begin
            SetRectRgn(PatternBrush,  0,  0, 100, 100);
            FillRect(MetafileCanvas.Handle, Rect(i * 60, i * 40, i * 60 + 100, i * 40 + 100), PatternBrush);
          end;

          SelectObject(MetafileCanvas.Handle, OldBrush);
          DeleteObject(PatternBrush);
        end;
  end;

  Bitmap32.Free;
  MetafileCanvas.Free;
  Metafile.SaveToFile(aMetafilePath);
  Metafile.Free;
end;

Примеры 1 и 2 выглядят хорошо, но занимают слишком много места. Размер EMF увеличивается при каждой операции рисования (несмотря на то, что исходное растровое изображение одно и то же):  
[![введите сюда описание изображения][1]][1]

Пример 3 занимает меньше места, но выглядит неправильно:  
[![введите сюда описание изображения][2]][2]

Вопрос - как переиспользовать один битмап для многократной отрисовки с разными размерами в EMF?

  [1]: https://i.sstatic.net/TiTrYBJj.png
  [2]: https://i.sstatic.net/vUqnGAo7.png

Ответы (0 шт):