- This topic has 2 replies, 2 voices, and was last updated 12 years, 9 months ago by Whookie.
-
AuthorPosts
-
February 5, 2012 at 9:06 pm #35040WhookieParticipant
Hi!
At the moment I want to using TPNGGraphic and some TAlphaImageLists. What I want to do, is loading a bigger .png Image with a lot of little
Images (they could be organized in “stripes”). Now at Runtime i want to clear the AlphaImageList and load it with such a stripe of new images.
The point here is to preserve the alpha-channel.
So one way would be to “cut” out image by image from the original .png and add it to the ImageList, but I have not found a way to do that.
I thought of creating a new png in the size of one image and then copy pixel by pixel but I would need to retrieve and set the alpha-value
of each pixel ….
It would be even better to build a Stream or Resource to us AlphaImageList.LoadFromStream/Resource and load the list in one single call.
But at the moment any hint how to achieve my goal would be be great!
February 16, 2012 at 9:20 am #47801SupportKeymasterHello
I have not a solution at moment. Alphacontrols can't make a new Png files (only read them).
February 18, 2012 at 7:46 pm #47823WhookieParticipantHi 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;
// -
AuthorPosts
- You must be logged in to reply to this topic.