我試圖實現以下目標:使用上的TImage
假設一個大PNG(背景透明16000 X 70像素),其中包含50個不同的其他PNG文件... 我需要加載該PNG,並從中提取個別PNG(最好是例如有一種函數,我可以說coords(左,頂部,高度,寬度),我想提取的PNG ...提取PNG應該顯示在timage然後...
當然,我可以使用GIF圖像,再次重新創建動畫,但我需要PNG出於某種原因...
的想法是將其加載到一個ImageList但失敗了,因爲所有的50個png格式的有(320x70px)的TImageList的尺寸僅支持256PX寬度...
我的下一個想法是,也許我可以這樣做:
將Png加載到TBitmapArray中。那麼,提取工作相當不錯,但與所有正在失去alpha通道沒有什麼副作用是透明的,而不是了,我得到一個胖黑色邊框:-(
type
TRectArray = array of TRect;
TBitmapArray = array of TBitmap;
// Zwei Funktionen die Rechtecke aufbereiten:
function FixRect(SrcRect: TRect): TRect;
procedure Switch(var a,b: integer);
var c: integer;
begin
c := a; a := b; b := c;
end;
begin
if SrcRect.Left > SrcRect.Right then
Switch(SrcRect.Left,SrcRect.Right);
if SrcRect.Top > SrcRect.Bottom then
Switch(SrcRect.Top,SrcRect.Bottom);
result := SrcRect;
end;
function TrimRect(SrcRect: TRect; minx,miny,maxx,maxy: integer): TRect;
begin
result := fixrect(srcrect);
if result.Left < minx then result.left := minx;
if result.top < miny then result.top := miny;
if result.right > maxx then result.right := maxx;
if result.bottom > maxy then result.bottom := maxy;
end;
// Stanzt die in SrcRect übergebenen rechtecke aus SrcPNG aus und lädt sie ins
// DstBitmapArray
procedure GetBitmaps(const SrcPNG: TPNGObject; const SrcRects: TRectArray;
var DstBitmapArray: TBitmapArray);
var
i: integer;
Rct: TRect;
Bmp: TBitmap;
begin
// Bitmap vom PNG Erzeugen
Bmp := TBitmap.Create;
Bmp.Assign(SrcPNG);
// Länge der auszugebenden Bilderliste festlegen (=Anzahl der Rechtecke)
setlength(DstBitmapArray,high(SrcRects)+1);
for i := 0 to high(SrcRects) do
begin
// Bitmap erzeugen
DstBitmapArray[i] := TBitmap.Create;
// Rechteck vorbereiten mit obigen Funktionen (ggf Zurechtschneiden,
// falls es über die Grenzen des PNGs hinausgeht)
Rct := TrimRect(SrcRects[i],0,0,SrcPng.Width,SrcPNG.Height);
// Größe des Bitmaps setzen
DstBitmapArray[i].SetSize(rct.Right-rct.left,rct.bottom-rct.top);
// rechteck ausstanzen und auf Bitmap kopieren
BitBlt(DstBitmapArray[i].Canvas.Handle,0,0,DstBitmapArray[i].width,
DstBitmapArray[i].Height,bmp.Canvas.handle,rct.left,rct.top,srccopy);
end;
Bmp.free;
end;
// Stanzt ebenfalls Bilder aus dem PNG aus, die rechtecke werden aber im
// Parameter Positions testbasiert übergeben. jede Zeile definiert ein rechteck
// Die Koordinaten des Rechtecks werden in der reihenfolge Left, Top, Right, Bottom
// angegeben und durch Kommata separiert. Beispiel:
// 0,0,100,50
// 100,0,100,100
// etc...
procedure LoadBitmaps(const SrcPNG: TPNGObject; const Positions: TStrings;
var DstBitmapArray: TBitmapArray);
var
i: integer;
l: integer;
rectarray: TRectArray;
tmp: tstringlist;
begin
setlength(rectarray,positions.Count);
l := 0;
tmp := tstringlist.Create;
tmp.Delimiter := ',';
for i := 0 to positions.count - 1 do
begin
tmp.DelimitedText := Positions[i];
if TryStrToInt(trim(tmp[0]),rectarray[l].Left) and
TryStrToInt(trim(tmp[1]),rectarray[l].Top) and
TryStrToInt(trim(tmp[2]),rectarray[l].Right) and
TryStrToInt(trim(tmp[3]),rectarray[l].Bottom) then
inc(l);
end;
setlength(rectarray,l);
GetBitmaps(srcpng,rectarray,dstbitmaparray);
tmp.free;
end;
//extract the second png from the large one
procedure TForm1.btnExtractClick(Sender: TObject);
var
src: TPNGImage;
begin
src := TPNGImage.Create;
src.Assign(img.Picture.Graphic);
try
myPictures[0] := TBitmap.Create;
// ok transparency is lost here!
LoadBitmaps(src, ImageListAreas, myPictures);
imgExtract.Picture.Assign(myPictures[0]);
finally
FreeAndNil(src);
end;
end;
也許有人有一個想法,如何可以這樣做不失去tranparency ... 任何幫助深表感謝,但是這將是很好也許沒有第三方組件...至少GR32將是確定太
最親切的問候,
小號!
這裏的最終目標究竟是什麼?你想創建一個動畫?你需要將圖形文件嵌入到exe文件中嗎? – GrandmasterB 2010-07-08 18:49:59
從透明的png中提取單獨的png保持不變! 沒有talkig關於嵌入可執行多數民衆贊成在沒問題...我正在加載圖像文件從光盤 問候 s! – stOrM 2010-07-13 11:09:56