首页 > 解决方案 > 如何在 FMX 中加载大位图(火猴)

问题描述

我正在尝试创建一个漫画查看器,它需要加载像 1000*16000 这样大尺寸的图像,我的应用程序在 delphi FMX 中, 我JPG已经尝试使用TImage, TImageViewerTImageControl但是它们都使用在加载图像后将TBitmap大小修剪为尝试搜索图像库,但我找不到任何东西,因为 我在想也许我可以将图像加载到 a 中,然后将其复制并以较小的尺寸绘制到几个位图?但我不知道如何读取和解析内存流,只选择一个干净的高度! 最后,我正在寻找一种方法来加载和显示这些大()图像, 我正在使用 delphi 10.2.3 谢谢。8192
FMX (firemonkey)
Memory stream
1000*16000Delphi FMX

编辑 01:
我想我找到了一种可以让事情变得简单的方法,我在中添加了Vcl.Imaging.jpegto uses 子句,FMX (FireMonkey)然后我使用TJPEGImage并加载了图像,我打印了宽度和高度,它们是正确的,没有修剪!所以我在想,也许我可以从中读取每个像素TJPEGImage.canvas然后将其打印到FMX TBitmap?,您如何看待这种方法?,您知道将数据复制到其中的好方法TJPEGImageFMX TBitmap

编辑02:
我找到了一个新的解决方案,TBitmapSurface似乎这个类没有TBitmap限制,我能够在其中加载图像而不会被修剪!但有个问题!我怎么能把这个给TImage?如果我简单地说Image.bitmap.assign(TBitmapsurface),那么图像会再次被修剪!所以似乎唯一可能的方法是重写TImageso 它使用TBitmapSurface而不是TBitmap,感谢有关此问题的任何帮助,谢谢。
这是代码TBitmapSurface

bitmapSurf := TBitmapSurface.Create;
TBitmapCodecManager.LoadFromFile(path, bitmapSurf);

标签: imagedelphibitmapfiremonkey

解决方案


FMX.Graphics.TBitmap尺寸限制不同8192 * 8192FMX.Surface.TBitmapSurface似乎最多支持16k * 16k甚至更多(我没有测试过),因此使用FMX.Surface.TBitmapSurface您可以加载图像而无需修剪,然后您可以轻松地将其分成两FMX.Graphics.TBitmap部分(或可能更多部分使用相同的方法)
下面您可以看到首先加载JPGintoTBitmapSurface的代码,然后是将其分成两部分的代码TBitmap

var
  srce, dest: TBitmapSurface;
  path: string;
  scan: integer;
  w, h1, h2: integer;
begin
  path := 'C:\tmp\Imgs\res.bmp';
  srce := TBitmapSurface.Create;
  TBitmapCodecManager.LoadFromFile(path, srce); 

  dest := TBitmapSurface.Create;

  // first half
  w := srce.Width;
  h1 := srce.Height div 2;
  dest.SetSize(w, h1, TPixelFormat.RGBA);
  for scan := 0 to h1-1 do
    Move(srce.Scanline[scan]^, TBitmapSurface(dest).Scanline[scan]^, srce.Width * 4);
  Image1.Bitmap.Assign(dest); 

  // second half
  h2 := srce.Height - h1;
  dest.SetSize(w, h2, TPixelFormat.RGBA);
  for scan := h1 to srce.Height-1 do
    Move(srce.Scanline[scan]^, TBitmapSurface(dest).Scanline[scan-h1]^, srce.Width * 4);
  Image2.Bitmap.Assign(dest);

end;  

这个答案是使用第一篇文章的评论和我的另一个问题的答案提供的:
How to draw FMX.Surface.TBitmapSurface on FMX.Graphics.TBitmap


推荐阅读