Image 如何在FMX(fire monkey)中加载大位图
我正在尝试创建一个漫画查看器,它需要加载大尺寸(如1000*16000)的Image 如何在FMX(fire monkey)中加载大位图,image,delphi,bitmap,firemonkey,Image,Delphi,Bitmap,Firemonkey,我正在尝试创建一个漫画查看器,它需要加载大尺寸(如1000*16000)的JPG图像,我的应用程序是delphi FMX,我已经尝试使用TImage,TImageViewer,TImageControl但它们都使用TBitmap在加载图像后将大小修剪为8192。 我尝试搜索图像库,但找不到FMX(firemonkey) 我在想,也许我可以将图像加载到内存流中,然后将其复制并以较小的尺寸绘制到多个位图中?但我不知道如何读取和解析内存流,并且只选择某个干净的高度 最后,我正在寻找一种在Delphi
JPG
图像,我的应用程序是delphi FMX,我已经尝试使用TImage
,TImageViewer
,TImageControl
但它们都使用TBitmap
在加载图像后将大小修剪为8192
。我尝试搜索图像库,但找不到
FMX(firemonkey)
我在想,也许我可以将图像加载到
内存流中
,然后将其复制并以较小的尺寸绘制到多个位图中?但我不知道如何读取和解析内存流,并且只选择某个干净的高度最后,我正在寻找一种在
Delphi FMX
中加载和显示这些大型(
1000*16000
)图像的方法
我正在使用delphi 10.2.3谢谢 编辑01:
我想我已经找到了一种可能使事情变得简单的方法,我在
FMX(FireMonkey)
中的uses子句中添加了Vcl.Imaging.jpeg
,然后我使用TJPEGImage
加载了图像,我打印了宽度和高度,它们是正确的,没有修剪!所以我在想,也许我可以从TJPEGImage.canvas
中读取每个像素,然后将其打印到FMX-TBitmap
,你认为这种方法怎么样?你知道一种将TJPEGImage
中的数据复制到FMX-TBitmap
的好方法吗
编辑02:我找到了一个新的解决方案,
TBitmapSurface
,这个类似乎没有TBitmap
的限制,我可以在里面加载图像而不需要修剪!但是有一个问题!如何将此信息发送给TImage
?如果我只是说Image.bitmap.assign(TBitmapsurface)
,那么图像会再次被修剪!因此,似乎唯一可能的方法是重写TImage
,因此它使用TBitmapSurface
而不是TBitmap
,我们非常感谢您对此问题提供的任何帮助。以下是
TBitmapSurface
的代码:
bitmapSurf := TBitmapSurface.Create;
TBitmapCodecManager.LoadFromFile(path, bitmapSurf);
与
FMX.Graphics.TBitmap
的大小限制为8192*8192
不同,FMX.Surface.TBitmapSurface
似乎支持高达16k*16k
甚至更多(我还没有测试过),因此使用FMX.Surface.TBitmapSurface
可以加载图像而无需修剪,然后,您可以轻松地将其拆分为两个FMX.Graphics.TBitmap
(或使用相同方法的更多部分)下面您可以看到先将
JPG
加载到tbitmapsface
中,然后将其拆分为两个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;
这个答案是使用第一篇帖子上的评论和我另一个问题的答案提供的:有多种格式,甚至在
JPG
中,更不用说压缩和颜色格式了。通过流读取图像将是支持这些不同格式的主要任务。你打算瞄准哪个平台?@Jerrydoge现在是桌面版,但我希望在这之后瞄准android,我甚至有一个工作原型,它可以与普通漫画一起工作,这些漫画都有小图片,是的,通过流媒体阅读确实是一件非常困难的事情,这就是为什么我在寻找更好的方式!,顺便问一下,你认为将图像加载到流中,然后手动绘制它怎么样?这可能吗?当然可能。但这和我刚才描述的是一样的——你需要自己解析它并解释一切。从研究JPG规范开始。或者继续搜索第三方库。您可以使用支持tera像素的imagemagick()),要在delphi中使用它,您还可以查看OpenGL库,以便在任何画布上绘制图像。