首页 > 其他 > 详细

位图切割器&位图裁剪器

时间:2015-04-28 20:31:50      阅读:314      评论:0      收藏:0      [点我收藏+]

  位图切割器:

    虽然网上有类似的工具,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;
  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 := T to 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);
    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 计大小的位图——这个工具写得较早些,当时没考虑支持超大图片,现在也没意愿去改进了。

技术分享

    此工具的下载链接在这里

位图切割器&位图裁剪器

原文:http://www.cnblogs.com/ecofast/p/4463695.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!