PNG分割

Delphi新版本虽然集成了PngImage但是分割复制什么的却非常难用.稍微封装了一下.可以把一张PNG横向分割成N张.透明通道什么的都可以保持不变.

//2013.7.22代码做了改动,变成按行和列切割.CopyPng也做了处理,可以拷贝任意区域
type
  TPngArray = array of TPngImage;

{把一个PNG拷贝到另一个PNG中,带透明通道}
procedure CopyPng(const Src: TPngImage; dest: TPngImage;
  const SrcX, SrcY, DestX, DestY, Width, Height: Integer);
var
  p1, p2: PByteArray;
  pa1, pa2: PByteArray;
  sX, sY, dX, dY, s: Integer;
begin
  sY := SrcY;
  dY := DestY;
  while sY < (SrcY + Height) do
  begin
    if (sY >= Src.Height) or (dY >= dest.Height) then
      Break;
    p1 := Src.Scanline[sY];
    p2 := dest.Scanline[dY];
    pa1 := Src.AlphaScanline[sY];
    pa2 := dest.AlphaScanline[dY];

    sX := SrcX;
    dX := DestX;
    while sX < (SrcX + Width) do
    begin
      if (sX >= Src.Width) or (dX >= dest.Width) then
        Break;
      p2[3 * dX] := p1[3 * sX];
      p2[3 * dX + 1] := p1[3 * sX + 1];
      p2[3 * dX + 2] := p1[3 * sX + 2];
      pa2[dX] := pa1[sX];
      //
      Inc(sX);
      Inc(dX);
    end;
    Inc(sY);
    Inc(dY);
  end;
end;

{分割PNG,按照行列}
function SplitePng(const Src: TPngImage; RowCount, ColCount: Integer)
  : TPngArray;
var
  x, y, lwidth, lHeight, xoffset, yoffset, resultIndex: Integer;
begin
  SetLength(Result, RowCount * ColCount);
  lwidth := Src.Width div ColCount;
  lHeight := Src.Height div RowCount;
  resultIndex := 0;
  yoffset := 0;
  for y := 0 to RowCount - 1 do
  begin
    xoffset := 0;
    for x := 0 to ColCount - 1 do
    begin
      Result[resultIndex] := TPngImage.CreateBlank(COLOR_RGBALPHA, 8, lwidth,
        lHeight);
      CopyPng(Src, Result[resultIndex], xoffset, yoffset, 0, 0,
        Result[resultIndex].Width, Result[resultIndex].Height);
      Inc(xoffset, lwidth);
      //Result[resultIndex].SaveToFile(Format('d:\%d.png', [resultIndex]));
      Inc(resultIndex);
    end;
    Inc(yoffset, lHeight);
  end;
end;

此条目发表在Delphi, 未分类分类目录。将固定链接加入收藏夹。

PNG分割》有9条回应

  1. 小余说:

    你好,请问要如何调用你写的这个函数呀,本人是初学者。能不能写一小段实例呢,谢谢!

  2. 小余说:

    procedure TForm1.Button1Click(Sender: TObject);
    var
    png:Tpngimage;
    begin
    png:=Tpngimage.Create;
    png.LoadFromFile(‘d:\cz_2.png’);
    SplitePng(png,3);
    end;

    调用SplitePng后,要如何显示出图片呢?

  3. WLDNA说:

    刚好要写个东西,用了,感觉真心不错,特来感谢,呵呵

  4. zjc说:

    如果png图片是24位,会出错。

  5. dezo说:

    png文件如果是索引文件,这样分割不行吧

评论已关闭。