如何将图像列表保存为一个位图,如 tilesheet?
How to save an imagelist as one bitmap like a tilesheet?
我有一个包含多个位图的图像列表,我想将它们一起保存为一个位图,但我需要它保存,就像在 2d 和 rpg 游戏等中绘制 spritesheet 或 tilesheet 一样
通常情况下,tilesheet 绘制有多个图像(连续),因此例如,如果我希望每行最多 6 个图像,它只会绘制 6 个,并在新行的下方绘制更多图像.
我可以像这样将它保存在一行中:
var
CurrentFrame: Integer;
StripWidth: Integer;
Strip: TBitmap;
Bmp: TBitmap;
I: Integer;
begin
if SaveDialog.Execute then
begin
StripWidth := ImageList1.Width * ImageList1.Count - ImageList1.Width;
CurrentFrame := - ImageList1.Width;
Strip := TBitmap.Create;
try
Strip.SetSize(StripWidth, ImageList1.Height);
Bmp := TBitmap.Create;
try
for I := 0 to ImageList1.Count - 1 do
begin
CurrentFrame := CurrentFrame + ImageList1.Width;
ImageList1.GetImage(I, Bmp);
Strip.Canvas.Draw(CurrentFrame, 0, Bmp);
end;
finally
Bmp.Free;
end;
Strip.SaveToFile(SaveDialog.FileName);
finally
Strip.Free;
end;
end;
end;
想象一下上面的结果是:
我想要的结果是这样的:
所以上面会在程序/函数中考虑一个参数,例如每行只允许 3 张图像。
如何将图像列表中的所有图像导出到一个位图中,如果在创建新行之前水平绘制图像,则只允许 x 数量?
谢谢。
编辑
感谢 David 的回答,我整理了这些程序:
procedure DrawImageOnSheet(Images: TImageList; Sheet: TBitmap;
ImageIndex, X, Y: Integer);
var
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
Images.GetBitmap(ImageIndex, Bitmap);
Sheet.Canvas.Draw(X, Y, Bitmap);
finally
Bitmap.Free;
end;
end;
procedure SaveImageListAsSheet(Images: TImageList; FileName: string;
NumberOfColumns: Integer);
var
Sheet: TBitmap;
nImage: Integer;
nCol: Integer;
nRow: Integer;
nToDraw: Integer;
nRemaining: Integer;
ImageIndex: Integer;
X, Y: Integer;
I: Integer;
begin
Sheet := TBitmap.Create;
try
nImage := Images.Count;
nCol := NumberOfColumns;
nRow := (nImage + nCol - 1) div nCol;
Sheet.Height := nRow * Images.Height;
Sheet.Width := nCol * Images.Width;
nRemaining := nImage;
ImageIndex := 0;
Y := 0;
while nRemaining > 0 do
begin
nToDraw := Math.Min(nRemaining, nCol);
X := 0;
for I := 0 to nToDraw - 1 do
begin
DrawImageOnSheet(Images, Sheet, ImageIndex, X, Y);
Inc(ImageIndex);
Inc(X, Images.Width);
end;
Inc(Y, Images.Height);
Dec(nRemaining, nToDraw);
end;
Sheet.SaveToFile(FileName);
finally
Sheet.Free;
end;
end;
根据评论的说明,您正在努力解决图像计数、rows/columns 组织等问题。因此,假设您已经拥有将图像 ImageIndex
绘制到输出位图中 X
、Y
.
位置的函数
procedure Draw(ImageIndex, X, Y: Integer);
我们还假设图像的尺寸由 ImageWidth
和 ImageHeight
给出。最后,有 nImage
个图像,您希望每列有 nCol
个图像。
那么,首先,你需要多少行?
nRow := (nImage + nCol - 1) div nCol;
现在您可以设置输出位图的大小。它的宽度为 nCol * ImageWidth
,高度为 nRow * ImageHeight
。
现在开始绘制图像。
nRemaining := nImage;
ImageIndex := 0;
Y := 0;
while nRemaining > 0 do
begin
nToDraw := Math.Min(nRemaining, nCol);
X := 0;
for i := 0 to nToDraw - 1 do
begin
Draw(ImageIndex, X, Y);
inc(ImageIndex);
inc(X, ImageWidth);
end;
inc(Y, ImageHeight);
dec(nRemaining, nToDraw);
end;
我有一个包含多个位图的图像列表,我想将它们一起保存为一个位图,但我需要它保存,就像在 2d 和 rpg 游戏等中绘制 spritesheet 或 tilesheet 一样
通常情况下,tilesheet 绘制有多个图像(连续),因此例如,如果我希望每行最多 6 个图像,它只会绘制 6 个,并在新行的下方绘制更多图像.
我可以像这样将它保存在一行中:
var
CurrentFrame: Integer;
StripWidth: Integer;
Strip: TBitmap;
Bmp: TBitmap;
I: Integer;
begin
if SaveDialog.Execute then
begin
StripWidth := ImageList1.Width * ImageList1.Count - ImageList1.Width;
CurrentFrame := - ImageList1.Width;
Strip := TBitmap.Create;
try
Strip.SetSize(StripWidth, ImageList1.Height);
Bmp := TBitmap.Create;
try
for I := 0 to ImageList1.Count - 1 do
begin
CurrentFrame := CurrentFrame + ImageList1.Width;
ImageList1.GetImage(I, Bmp);
Strip.Canvas.Draw(CurrentFrame, 0, Bmp);
end;
finally
Bmp.Free;
end;
Strip.SaveToFile(SaveDialog.FileName);
finally
Strip.Free;
end;
end;
end;
想象一下上面的结果是:
我想要的结果是这样的:
所以上面会在程序/函数中考虑一个参数,例如每行只允许 3 张图像。
如何将图像列表中的所有图像导出到一个位图中,如果在创建新行之前水平绘制图像,则只允许 x 数量?
谢谢。
编辑
感谢 David 的回答,我整理了这些程序:
procedure DrawImageOnSheet(Images: TImageList; Sheet: TBitmap;
ImageIndex, X, Y: Integer);
var
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
Images.GetBitmap(ImageIndex, Bitmap);
Sheet.Canvas.Draw(X, Y, Bitmap);
finally
Bitmap.Free;
end;
end;
procedure SaveImageListAsSheet(Images: TImageList; FileName: string;
NumberOfColumns: Integer);
var
Sheet: TBitmap;
nImage: Integer;
nCol: Integer;
nRow: Integer;
nToDraw: Integer;
nRemaining: Integer;
ImageIndex: Integer;
X, Y: Integer;
I: Integer;
begin
Sheet := TBitmap.Create;
try
nImage := Images.Count;
nCol := NumberOfColumns;
nRow := (nImage + nCol - 1) div nCol;
Sheet.Height := nRow * Images.Height;
Sheet.Width := nCol * Images.Width;
nRemaining := nImage;
ImageIndex := 0;
Y := 0;
while nRemaining > 0 do
begin
nToDraw := Math.Min(nRemaining, nCol);
X := 0;
for I := 0 to nToDraw - 1 do
begin
DrawImageOnSheet(Images, Sheet, ImageIndex, X, Y);
Inc(ImageIndex);
Inc(X, Images.Width);
end;
Inc(Y, Images.Height);
Dec(nRemaining, nToDraw);
end;
Sheet.SaveToFile(FileName);
finally
Sheet.Free;
end;
end;
根据评论的说明,您正在努力解决图像计数、rows/columns 组织等问题。因此,假设您已经拥有将图像 ImageIndex
绘制到输出位图中 X
、Y
.
procedure Draw(ImageIndex, X, Y: Integer);
我们还假设图像的尺寸由 ImageWidth
和 ImageHeight
给出。最后,有 nImage
个图像,您希望每列有 nCol
个图像。
那么,首先,你需要多少行?
nRow := (nImage + nCol - 1) div nCol;
现在您可以设置输出位图的大小。它的宽度为 nCol * ImageWidth
,高度为 nRow * ImageHeight
。
现在开始绘制图像。
nRemaining := nImage;
ImageIndex := 0;
Y := 0;
while nRemaining > 0 do
begin
nToDraw := Math.Min(nRemaining, nCol);
X := 0;
for i := 0 to nToDraw - 1 do
begin
Draw(ImageIndex, X, Y);
inc(ImageIndex);
inc(X, ImageWidth);
end;
inc(Y, ImageHeight);
dec(nRemaining, nToDraw);
end;