#1 2012-12-27 20:49:47

tomc
Member
Registered: 2012-12-27
Posts: 2

copying part of a larger png image - is it possible?

Hi,

I was wondering if your component is capable of displaying a small part of a large png image easily (retaining transparency).

This would be in a similar way to modern web apps using css, i.e. specifying width, height and offsets.

for example: the image shown here would be one master png image: http://glyphicons.com/
and to display a particular image you would provide the offsets with standard width and height.

Thanks,
Tom

Offline

#2 2012-12-28 11:34:33

tomc
Member
Registered: 2012-12-27
Posts: 2

Re: copying part of a larger png image - is it possible?

Found this function in pngfunctions.pas  (from pngimagelist opensource component) that should do it:

procedure SlicePNG(JoinedPNG: TPNGObject; Columns, Rows: Integer; out SlicedPNGs: TObjectList);
var
   X, Y, ImageX, ImageY, OffsetX, OffsetY: Integer;
   Width, Height: Integer;
   Bitmap: TBitmap;
   BitmapLine: PRGBLine;
   AlphaLineA, AlphaLineB: pngimage.PByteArray;
   PNG: TPNGObject;
begin
//This function slices a large PNG file (e.g. an image with all images for a
//toolbar) into smaller, equally-sized pictures.
SlicedPNGs := TObjectList.Create(False);
Width := JoinedPNG.Width div Columns;
Height := JoinedPNG.Height div Rows;

//Loop through the columns and rows to create each individual image
for ImageY := 0 to Rows - 1
do begin
   for ImageX := 0 to Columns - 1
   do begin
      OffsetX := ImageX * Width;
      OffsetY := ImageY * Height;
      Bitmap := TBitmap.Create;
      try
        Bitmap.Width := Width;
        Bitmap.Height := Height;
        Bitmap.PixelFormat := pf24bit;

        //Copy the color information into a temporary bitmap. We can't use TPNGObject.Draw
        //here, because that would combine the color and alpha values.
        for Y := 0 to Bitmap.Height - 1
        do begin
           BitmapLine := Bitmap.Scanline[Y];
           for X := 0 to Bitmap.Width - 1
           do BitmapLine^[X] := ColorToTriple(JoinedPNG.Pixels[X + OffsetX, Y + OffsetY]);
           end;

        PNG := TPNGObject.Create;
        PNG.Assign(Bitmap);

        if JoinedPNG.Header.ColorType in [COLOR_GRAYSCALEALPHA, COLOR_RGBALPHA]
        then begin
             //Copy the alpha channel
             PNG.CreateAlpha;
             for Y := 0 to PNG.Height - 1
             do begin
                AlphaLineA := JoinedPNG.AlphaScanline[Y + OffsetY];
                AlphaLineB := JoinedPNG.AlphaScanline[Y];
                for X := 0 to PNG.Width - 1
                do AlphaLineB^[X] := AlphaLineA^[X + OffsetX];
                end;
             end;

        SlicedPNGs.Add(PNG);
      finally
        Bitmap.Free;
       end;
      end;
   end;
end;

Offline

Board footer

Powered by FluxBB