如何在多次拉伸绘制到EMF时复用Bitmap?
在EMF中复用拉伸后的TBitmap32以减小文件体积
我需要将同一张大尺寸的TBitmap32多次绘制到EMF文件中,每次绘制的偏移位置和目标尺寸都不同。
采用常规方式绘制(案例1)时,显示效果正常,但EMF文件体积异常庞大——原因是每次StretchBlt操作都会在EMF中存储一份新的位图副本。
我尝试过先将位图放入兼容DC再复用(案例2),但结果和案例1一样,文件体积还是39MB,并没有实现位图复用。
用图案画刷的方式(案例3)能大幅缩小文件体积(仅3.9MB),但绘制效果异常,而且图案画刷无法实现独立的缩放控制。
示例代码
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:绘制效果正常,但文件体积随绘制次数增长(即使源位图相同)

- 案例3:文件体积极小,但绘制效果异常

请问是否存在某种方法可以在EMF中复用拉伸后的位图?
内容的提问来源于stack exchange,提问作者Kromster
相关产品推荐
相关产品推荐

