位图切割器&位图裁剪器

  位图切割器:

    虽然网上有类似的工具,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 - 1 do begin FileSeek(Handle, Offset + LineLen * N + L * PerBits, 0); FileRead(Handle, Dst^, Len); Inc(Dst, Len); end; end; begin Result := False; Handle := FileOpen(FileName, fmOpenRead or fmShareDenyWrite); if Handle < 0 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 16: begin PerBits := 2; end; 24: begin PerBits := 3; end; 32: begin PerBits := 4; end else Exit; end; Offset := SizeOf(FileHeader) + SizeOf(BmpInfoHeader);
VOffset := BmpInfoHeader.biHeight - BmpInfoHeader.biHeight div UnitH * UnitH; LineLen :
= (BmpInfoHeader.biWidth * PerBits + 3) div 4 * 4; Mem := TMemoryStream.Create; DstMem := TMemoryStream.Create; W := BmpInfoHeader.biWidth div UnitW; H := BmpInfoHeader.biHeight div UnitH; for J := 0 to H - 1 do begin for I := 0 to W - 1 do begin X := Format('%.3d', [I]); Y := Format('%.3d', [H - 1 - J]); Mem.Clear; Mem.SetSize(UnitW * PerBits * UnitH); Mem.Position := 0; ReadAreaImgData(I * UnitW, J * UnitH, UnitW, UnitH, Mem.Memory); DstMem.Clear; DstMem.Write(FileHeader, SizeOf(FileHeader)); BmpInfoHeader.biWidth := UnitW; BmpInfoHeader.biHeight := UnitH; BmpInfoHeader.biSizeImage := 0; 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 计大小的位图——这个工具写得较早些,当时没考虑支持超大图片,现在也没意愿去改进了。

    此工具的下载链接在这里

posted @ 2015-04-28 18:03  ecofast  阅读(714)  评论(0编辑  收藏  举报