位图切割器:
虽然网上有类似的工具,PhotoShop 也有类似功能,但前者似乎不支持超大位图切割(以 G 计大小),而后者的切割块数量好像有比较小的限定范围,于是自己动手写了这个工具。
至于为什么是“位图”切割器,原因只是我实在不想费力去解析譬如 JPG、PNG、TGA 等图像格式,而大家都知道解析 BMP 文件比较简单。
核心处理代码很简单,无外乎 ReadFile、SetFilePointer 等之类 API 调用而已。
function HandleSplit(const FileName, DstPath, ImgName: string;
UnitW, UnitH: Integer): Boolean;
var
Handle : Integer;
FileHeader : TBitmapFileHeader;
BmpInfoHeader: TBitmapInfoHeader;
Offset : Integer;
VOffset : Integer;
Mem, DstMem : TMemoryStream;
LineLen : Integer;
PerBits : Integer;
I, J, W, H : Integer;
X, Y : string; procedure ReadAreaImgData(L, T, W, H: Integer; Dst: PByte);
var
N : Integer;
Len: Integer;
begin
Len := W * PerBits;
for N := VOffset + T to VOffset + T + H - do
begin
FileSeek(Handle, Offset + LineLen * N + L * PerBits, );
FileRead(Handle, Dst^, Len);
Inc(Dst, Len);
end;
end; begin
Result := False; Handle := FileOpen(FileName, fmOpenRead or fmShareDenyWrite);
if Handle < then
Exit; try
if FileRead(Handle, FileHeader, SizeOf(FileHeader)) <> SizeOf(FileHeader) then
Exit; if FileHeader.bfType <> $4D42 then
Exit; if FileRead(Handle, BmpInfoHeader, SizeOf(BmpInfoHeader)) <> SizeOf(BmpInfoHeader) then
Exit; case BmpInfoHeader.biBitCount of
:
begin
PerBits := ;
end;
:
begin
PerBits := ;
end;
:
begin
PerBits := ;
end
else
Exit;
end; Offset := SizeOf(FileHeader) + SizeOf(BmpInfoHeader);
VOffset := BmpInfoHeader.biHeight - BmpInfoHeader.biHeight div UnitH * UnitH;
LineLen := (BmpInfoHeader.biWidth * PerBits + ) div * ;
Mem := TMemoryStream.Create;
DstMem := TMemoryStream.Create; W := BmpInfoHeader.biWidth div UnitW;
H := BmpInfoHeader.biHeight div UnitH;
for J := to H - do
begin
for I := to W - do
begin
X := Format('%.3d', [I]);
Y := Format('%.3d', [H - - J]);
Mem.Clear;
Mem.SetSize(UnitW * PerBits * UnitH);
Mem.Position := ;
ReadAreaImgData(I * UnitW, J * UnitH, UnitW, UnitH, Mem.Memory);
DstMem.Clear;
DstMem.Write(FileHeader, SizeOf(FileHeader));
BmpInfoHeader.biWidth := UnitW;
BmpInfoHeader.biHeight := UnitH;
BmpInfoHeader.biSizeImage := ;
DstMem.Write(BmpInfoHeader, SizeOf(BmpInfoHeader));
DstMem.Write(Mem.Memory^, Mem.Size);
DstMem.SaveToFile(ImgName + '_' + Y + '_' + X + '.bmp');
end;
end; FreeAndNil(Mem);
FreeAndNil(DstMem); Result := True;
finally
FileClose(Handle);
end;
end;
工具下载链接在这里。
位图裁剪器:写这个程序的初衷是因找不到方便的图片截取工具,尤其是在需要精确裁剪较大的图片时——这里的“较大”,和上文的切割器不一样,它不大可能能裁剪以 G 计大小的位图——这个工具写得较早些,当时没考虑支持超大图片,现在也没意愿去改进了。
此工具的下载链接在这里。