線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2913
推到 Plurk!
推到 Facebook!

用GDI+實現通過位圖創建多邊形區域的功能

尚未結案
babaabc
一般會員


發表:2
回覆:2
積分:0
註冊:2004-08-30

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-08-30 13:55:58 IP:222.183.xxx.xxx 未訂閱
我這兒有一段用C#的代碼(用GDI 實現"通過位圖創建多邊形區域"的功能 ) 在 http://www.vchelp.net/vchelp/archive.asp?type_id=91&class_id=2&cata_id=20&article_id=854&search_term= 這兒能下載到 想把它轉成DELPHI的代碼,我轉了一部分就不知怎樣轉了. 請大哥大姐們幫我看一下,怎麼做. C#Code--------------------------------------------------------------------------------- public unsafe static Region Convert( Bitmap bitmap, Color transparencyKey, TransparencyMode mode ) { //sanity check if ( bitmap == null ) throw new ArgumentNullException( "Bitmap", "Bitmap cannot be null!" ); //flag = true means the color key represents the opaque color bool modeFlag = ( mode == TransparencyMode.ColorKeyOpaque ); GraphicsUnit unit = GraphicsUnit.Pixel; RectangleF boundsF = bitmap.GetBounds( ref unit ); Rectangle bounds = new Rectangle( (int)boundsF.Left, (int)boundsF.Top, (int)boundsF.Width, (int)boundsF.Height ); uint key = (uint)((transparencyKey.A << 24) | (transparencyKey.R << 16) | (transparencyKey.G << 8) | (transparencyKey.B << 0)); //get access to the raw bits of the image BitmapData bitmapData = bitmap.LockBits( bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb ); uint* pixelPtr = (uint*)bitmapData.Scan0.ToPointer(); //avoid property accessors in the for int yMax = (int)boundsF.Height; int xMax = (int)boundsF.Width; //to store all the little rectangles in GraphicsPath path = new GraphicsPath(); for ( int y = 0; y < yMax; y ) { //store the pointer so we can offset the stride directly from it later //to get to the next line byte* basePos = (byte*)pixelPtr; for ( int x = 0; x < xMax; x , pixelPtr ) { //is this transparent? if yes, just go on with the loop if ( modeFlag ^ ( *pixelPtr == key ) ) continue; //store where the scan starts int x0 = x; //not transparent - scan until we find the next transparent byte while( x < xMax && !( modeFlag ^ ( *pixelPtr == key ) ) ) { x; pixelPtr ; } //add the rectangle we have found to the path path.AddRectangle( new Rectangle( x0, y, x-x0, 1 ) ); } //jump to the next line pixelPtr = (uint*)(basePos bitmapData.Stride); } //now create the region from all the rectangles Region region = new Region( path ); //clean up path.Dispose(); bitmap.UnlockBits( bitmapData ); return region; } C#Code--------------------------------------------------------------------------------- delphiCode----------------------------------------------------------------------------- procedure TInnerPicture.BitmapToRegion; var bitmap : TGPBitmap; boundsF : TGPRectF; bounds : TGPRect; gUnit : TUnit; key : TUnit; pixelPtr : TUnit; bitmapData : TBitmapData; yMax, xMax, i, j : Integer; path : TGPGraphicsPath; basePos : Byte; begin bitmap := TGPBitmap.Create(); path := TGPGraphicsPath.Create(); try //GraphicsUnit gunit = GraphicsUnit.Pixel; bitmap.Create(FIIFilePath); gUnit := UnitPixel; bitmap.GetBounds(boundsF,gUnit); bounds.X :=Trunc(boundsF.X); bounds.Y :=Trunc(boundsF.Y); bounds.Width :=Trunc(boundsF.Width); bounds.Height :=Trunc(boundsF.Height); bitmap.LockBits(bounds, ImageFlagsReadOnly,PixelFormat1bppIndexed,bitmapData); pixelPtr := TUnit(bitmapData.Scan0); xMax := Trunc(boundsF.Width); yMax := Trunc(boundsF.Height); key := ((transparencyKey.A << 24) | (transparencyKey.R << 16) | (transparencyKey.G << 8) | (transparencyKey.B << 0)); for i := 0 to yMax -1 do begin basePos := byte(pixelPtr); for j := 0 to xMax -1 do begin if (pixelPtr^ = 0) then continue; end; pixelPtr := TUnit(basePos bitmapData.Stride); end; finally path.Free; bitmap.Free; end; end; delphiCode----------------------------------------------------------------------------- 發表人 - babaabc 於 2004/08/30 13:59:51
babaabc
一般會員


發表:2
回覆:2
積分:0
註冊:2004-08-30

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-08-30 20:58:50 IP:218.70.xxx.xxx 未訂閱
怎么没有人回答呀
richtop
資深會員


發表:122
回覆:646
積分:468
註冊:2003-06-10

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-08-30 23:02:24 IP:211.76.xxx.xxx 未訂閱
babaabc 您好:    這是一個耍賴的方法,提供參考;但如果您的目的是要完成該程式的實作細節,那就把以下內容當成娛樂吧! 依您提供的 class="code">procedure TForm1.Image1Click(Sender: TObject); begin Close; end; procedure TForm1.FormActivate(Sender: TObject); begin Form1.ClientWidth := Image1.Picture.Width; Form1.ClientHeight := Image1.Picture.Height; Form1.TransparentColorValue := Image1.Picture.Bitmap.TransparentColor; Form1.TransparentColor := true; end; 如此就可以模擬出執行的結果。(似乎必須在有支援透明色的作業系統才可以?) RichTop 敬上 =====***** 把數學當工具,可以解決問題;將數學變能力,能夠發現並解決問題! =====#####
babaabc
一般會員


發表:2
回覆:2
積分:0
註冊:2004-08-30

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-08-31 12:46:21 IP:222.183.xxx.xxx 未訂閱
RichTop你好 首先感谢您的支持. 但我现在不是想做图像窗体.是用于绘图软件. 所以不太合适.
wameng
版主


發表:31
回覆:1336
積分:1188
註冊:2004-09-16

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-09-16 19:51:12 IP:61.222.xxx.xxx 未訂閱
// Evon    { 自動將 TwinControl 利用圖形產生不規則物件                                 }   Procedure AutoRglon(ControlHandle:Thandle;PICBMP:TBITMAP;TransColor:Tcolor);   { 自動利用圖形產生不規則 Hrgn 曲線                                          }   Function BitmapToRgn(Bitmap:TBitmap;                        Const TransColor:Tcolor  = Clwhite;                        Const Inverted  :Boolean = false):HRgn;    Function BitmapToRgn(Bitmap:TBitmap;                      Const TransColor:Tcolor  = Clwhite;                      Const Inverted  :Boolean = false):HRgn; const   AllocUnit=100; var   BMP:TBitmap;   MaxRects:Integer;   HData:HGlobal;   PData:PRgnData;   CB,CR,CG,LR,LG,LB:Byte;   P32:Pointer;   X,X0,Y:Integer;   P:PLongInt;   PR:PRect;   H:Hrgn; begin   Result :=0;   BMP    :=TBitmap.Create;   BMP.Assign(Bitmap);   BMP.HandleType  :=bmDIB;   BMP.PixelFormat :=pf32bit;   MaxRects        :=AllocUnit;   HData := GlobalAlloc(GMem_Moveable,SizeOf(TRgnDataHeader)+SizeOf(TRect)*MaxRects);   PData := GlobalLock(HData);   PData^.RDH.dwSize   :=SizeOf(TRgnDataHeader);   PData^.RDH.iType    :=RDH_Rectangles;   PData^.RDH.nCount   :=0;   PData^.RDH.nRgnSize :=0;   SetRect(PData^.RDH.rcBound,MaxInt,MaxInt,0,0);   LR:=GetRValue(ColorToRGB(TransColor));   LG:=GetGValue(ColorToRGB(TransColor));   LB:=GetBValue(ColorToRGB(TransColor));   for Y:=0 to Bitmap.Height-1 do   begin     X:=-1;     P32:=BMP.ScanLine[Y];     while X+1X0 then begin if PData^.RDH.nCount>=MaxRects then begin GlobalUnlock(HData); Inc(MaxRects,AllocUnit); HData:=GlobalReAlloc(HData,SizeOf(TRgnDataHeader) SizeOf(TRect)*MaxRects,GMem_Moveable); PData:=GlobalLock(HData) end; PR:=@PData^.Buffer[PData^.RDH.nCount*SizeOf(TRect)]; SetRect(PR^,X0,Y,X,Y 1); if X0PData^.RDH.rcBound.Right then PData^.RDH.rcBound.Left:=X; if Y 1>PData^.RDH.rcBound.Bottom then PData^.RDH.rcBound.Bottom:=Y 1; Inc(PData^.RDH.nCount); if PData^.RDH.nCount=2000 then begin H:=ExtCreateRegion(nil,SizeOf(TRgnDataHeader) (SizeOf(TRect)*MaxRects),PData^); if Result<>0 then begin CombineRgn(Result,Result,H,RGN_OR); DeleteObject(H); end else Result:=H; PData^.RDH.nCount:=0; SetRect(PData^.RDH.rcBound,MaxInt,MaxInt,0,0) end; end; end; end; H:=ExtCreateRegion(nil,SizeOf(TRgnDataHeader) (SizeOf(TRect)*MaxRects),PData^); if Result<>0 then begin CombineRgn(Result,Result,H,RGN_OR); DeleteObject(H); end else Result:=H; GlobalFree(HData); BMP.Free; end; Procedure AutoRglon(ControlHandle:Thandle;PICBMP:TBITMAP;TransColor:Tcolor); var Hrg : HRGN; begin Hrg := BitmapToRgn(PicBMP,TransColor); Try SetWindowRgn(ControlHandle,Hrg,True); finally DeleteObject(Hrg); end; end;
系統時間:2024-05-07 17:32:36
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!