Using part of an .png for an AlphaImageList

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #47801
    Support
    Keymaster

      Hello

      I have not a solution at moment. Alphacontrols can't make a new Png files (only read them).

      #47823
      Whookie
      Participant

        Hi again! I've found a way to do what I wanted. The following code might help someone else and is based on MakeIcon32Rect() from acPng.pas

        Code:
        unit SkinImgLstLoader;

        interface

        Uses
        Windows, SysUtils, acPng, acAlphaImageList, Graphics, sConst, sAlphaGraph;

        Type
        TAlphaImageListLoader = Class
        private
        fGraphic: TPNGGraphic;
        fW: Integer;
        fH: Integer;
        fMaskBitmap: TBitmap;
        fFast32Src: TacFast32;
        fDstBmp: TBitmap;
        fFast32Dst: TacFast32;
        fError: Boolean;
        function MakeIcon32Rect(SrcX, SrcY: Integer): HICON;
        public
        constructor Create(const AGraphic: TPNGGraphic; AImgWidth, AImgHeight: Integer); Virtual;
        procedure LoadFrom(AX, AY, ACount: Integer; AImgList: TsAlphaImageList; ReplaceImages: Boolean=TRUE);
        property Error: Boolean read fError;
        End;

        implementation

        Uses
        CommCtrl;

        { TAlphaImageListLoader }

        constructor TAlphaImageListLoader.Create(const AGraphic: TPNGGraphic; AImgWidth, AImgHeight: Integer);
        begin
        fGraphic := AGraphic;
        fW := AImgWidth;
        fH := AImgHeight;
        end;

        procedure TAlphaImageListLoader.LoadFrom(AX, AY, ACount: Integer; AImgList: TsAlphaImageList; ReplaceImages: Boolean);
        var
        iCnt: Integer;
        ico: HICON;
        begin
        fMaskBitmap := TBitmap.Create;
        fMaskBitmap.PixelFormat := pf1bit; // doesnt matter, when bmDDB is used (otherwise pf8bit need)
        fMaskBitmap.HandleType := bmDDB; // doesnt work when bmDIB (works but needs MaskBitmap.Canvas.Pixels[x,y]:=C.A)?
        fMaskBitmap.Width := fW;
        fMaskBitmap.Height := fH;
        //
        fDstBmp := TBitmap.Create;
        fDstBmp.PixelFormat := pf32Bit;
        fDstBmp.Width := fW;
        fDstBmp.Height := fH;
        //
        fFast32Src := TacFast32.Create;
        fFast32Dst := TacFast32.Create;
        //
        if fFast32Src.Attach(fGraphic) And fFast32Dst.Attach(fDstBmp) then
        begin
        AImgList.AcBeginUpdate;
        if ReplaceImages then //else add images to this list(!)
        AImgList.Clear;
        AImgList.Width := fW;
        AImgList.Height := fH;
        fError := FALSE;
        //
        for iCnt := 0 to ACount – 1 do
        begin
        ico := MakeIcon32Rect(AX, AY);
        if ico 0 then
        begin
        fError := fError Or (ImageList_AddIcon(AImgList.Handle, Ico) < 0);
        DestroyIcon(Ico);
        end;
        Inc(AX, fW); // LoadFromRow (LoadFromCol = Inc(AY, fH))
        end;
        AImgList.AcEndUpdate;

        end;
        fFast32Src.Free;
        fFast32Dst.Free;
        fMaskBitmap.Free;
        fDstBmp.Free;
        end;

        function TAlphaImageListLoader.MakeIcon32Rect(SrcX,SrcY: Integer): HICON;
        var
        IconInfo: TIconInfo;
        X, Y : integer;
        begin
        for y := 0 to fH – 1 do
        begin
        for x := 0 to fW – 1 do
        begin
        fFast32Dst[x,y] := fFast32Src[SrcX+x,SrcY+y];
        end;
        end;

        IconInfo.fIcon := True;
        IconInfo.hbmColor := fDstBmp.Handle;
        IconInfo.hbmMask := fMaskBitmap.Handle;

        Result := CreateIconIndirect(IconInfo);
        end;

        end.

        Now one can use that class to load some images from a greater png like:

        Code:
        fImgList := TsAlphaImageList.Create(nil); // create an image list

        // AGraphic … is a png image loaded from somewhere
        // iW, iH … the width/height of one image in the image list
        iLoader := TAlphaImageListLoader.Create(AGraphic, iW, iH);
        //
        // now load some image into the list
        // iX, iY … position (upper left corner) of the first image inside the png
        // iCn … number of images to load (images have to be horizontally side by side)
        // fImgList … img list to add the images to (you could call LoadFrom more than once to have more than one row of images
        // using iLoader.LoadFrom(iX, iY, iCn, fImgList, FALSE);)
        iLoader.LoadFrom(iX, iY, iCn, fImgList);
        iLoader.Free;
        //

      Viewing 2 posts - 1 through 2 (of 2 total)
      • You must be logged in to reply to this topic.