Ale*_*der 11 delphi jpeg tiles bitmap image-stitching
这是问题所在.我有一大组512x512像素的JPEG图块作为常规的jpg文件.
我编写了一个软件,可以完成很多工作,并且需要在最后将所有这些文件拼接成一个巨大的JPEG.
首先,我不希望使用ImageMagick执行此操作,而是在我的软件中执行它!
在Delphi中,无法将JPG文件复制到另一个JPG画布上,因此必须首先创建TBitmap,然后将切片复制到TBitmap画布上,然后将TBitmap转换为jpeg图片并保存到文件中.
当结果文件尺寸太大(如20 000 x 20 000像素)时会出现问题.当我调用TBitmap.SetSize时,我自然会得到一个错误(内存不足或类似的东西).
我在同一台机器上使用Photoshop进行了一些测试,并且能够创建一个复杂(非空白)30 000 x 30 000文件并将其保存为JPEG.
所以问题是,我怎么能做同样的事情?通过将结果直接写入磁盘或使用其他技巧来某种方式拼接所有JPEGS?...
尽管20k x 20k像素看起来足够大,但这个值仅适用于我的机器(4 GB ram),所以少量的ram对软件的限制更大!
谢谢
编辑:澄清:
我想要的是找到一种拼接那些小JPG图像并编写大图像而不将大图像保存在RAM中的方法.显然,可以直接在磁盘上读取/写入位图流(不确定),但这会导致非常大的文件.因此,如果JPG格式不允许这样做,那么任何其他压缩格式(如TIFF或PNG)都可以.我还想避免过多的再压缩,不要失去(已压缩的)初始JPG质量.
因此,完美的解决方案将是一种直接读取小文件并以某种方式写入大文件的方法.瓷砖的尺寸为256x256或512x512,以防有助于JPEG压缩内容的某些对齐.
谢谢大家 !
实际上,答案和可能的解决方案是继续像Photoshop一样,即从磁贴写入位图流到磁盘上的大bmp文件(例如,一个20 000 x 30 000文件将是2.4 Gb),然后使用NativeJpg库通过条带馈送位图数据将这个大位图转换为jpg,每个位图高8像素.
也可以拼接一行瓷砖(512像素高),然后将它8送到NativeJpg库8,然后继续下一行瓷砖!
Erik Turner的一些示例代码:
procedure GetBitmapTile(BM: TBitmap; Y, X: Integer);
var JpegImage: TJpegImage;
begin
JpegImage := NIL; // Replace with tile lookup //
BM.PixelFormat := pf32bit;
BM.Width := JpegImage.Width;
BM.Height := JpegImage.Height;
BM.Canvas.Draw(0, 0, JpegImage);
end;
procedure WriteBitmapFile(TileCountY, TileCountX: Integer; BM_Stm: TStream);
var
BM: TBitmap;
TileY: Integer;
TileX: Integer;
PixelY: Integer;
begin
BM := TBitmap.Create;
for TileY := 0 to TileCountY-1 do
for TileX := 0 to TileCountX-1 do
begin
GetBitmapTile(BM, TileY, TileX);
for PixelY := 0 to 511 do
BM_Stm.Write(BM.ScanLine[PixelY]^, 512 * SizeOf(TRGBQuad));
end;
BM.Free;
end;
Run Code Online (Sandbox Code Playgroud)
NativeJpg库:http://www.simdesign.nl/nativejpg.html