Delphi图形图像处理
delphi7编程技巧与实例精解之图形图像(修正重绘变形)
delphi7编程技巧与实例精解之图形图像(修正重绘变形)unit Unit1;interfaceusesWin do ws, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, ComCtrls, ExtCtrls, StdCtrls;typeTForm1 = class(TForm)img1: TImage;btn1: TButton;btn2: TButton;tmr1: TTimer;tb1: TTrackBar;dlgOpen1: TOpenDialog;rg1: TRadioGroup;procedure FormCreate(Sender: TObject);procedure tb1Change(Sender: TObject);procedure btn1Click(Sender: TObject);procedure tmr1Timer(Sender: TObject);procedure btn2Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;i: Integer;L,T,R,B: Integer;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject); beginT:= Img1.Top;l:= img1.Left;b:= img1.Top+ img1.Height;r:= img1.Left+ img1.Width;end;procedure TForm1.tb1Change(Sender: TObject); begintmr1.Interval:= tb1.Position;end;procedure TForm1.btn1Click(Sender: TObject); vark: Integer;beginCanvas.Pen.Color:= Form1.Color;if rg1.ItemIndex<2 then beginfor k:= 0 to b do beginCanvas.MoveTo(0,k);Canvas.LineTo(r,k);end;end else if rg1.ItemIndex=2 then beginfor k:=0 to b+4 do beginCanvas.MoveTo(0,k);Canvas.LineTo(r,k);end;end;tmr1.Enabled:= True;i:= 0;end;procedure TForm1.tmr1Timer(Sender: TObject);varx,y: Integer;beginif rg1.ItemIndex=0 then beginSelf.Canvas.CopyRect(Rect(l,t+i,r,t+i+1),img1.Canvas,Rec t(0,0+i,img1.Width,0+i+1));Self.Canvas.CopyRect(Rect(l,b-i,r,b-i+1),img1.Canvas,Rect(0,img1.Height-i,img1.Width,img1.Height-i+1));i:= i+1;if i>b/2-1 then tmr1.Enabled:= False;end else if rg1.ItemIndex=1 then beginSelf.Canvas.CopyRect(Rect(l,t+i*4,r,t+i*4+2),img1.Canvas ,Rect(0,0+i*4,img1.Width,0+i*4+2));Self.Canvas.CopyRect(Rect(l,b-i*4-2,r,b-I*4),img1.Canvas,Rect(0,img1.Height-i*4-2,img1.Width,img1.Height-i*4));i:= i+1;if i>img1.Height/4 then tmr1.Enabled:= False;end else if rg1.ItemIndex=2 then beginfor x:= 0 to (img1.Width div 8 ) do beginfor y:= 0 to (img1.Height div 8 ) do begincase i of0:Self.Canvas.CopyRect(Rect(l+x*8,t+y*8,l+x*8+4,t+y*8+4),im g1.Canvas,Rect(0+x*8,0+y*8,0+x*8+4,0+y*8+4));1:Self.Canvas.CopyRect(Rect(l+x*8+4,t+y*8+4,l+x*8+8,t+y*8+ 8),img1.Canvas,Rect(0+x*8+4,0+y*8+4,0+x*8+8,0+y*8+8));2:Self.Canvas.CopyRect(Rect(L+x*8,t+y*8+4,l+x*8+4,t+y*8+8) ,img1.Canvas,Rect(0+x*8,0+y*8+4,0+x*8+4,0+y*8+8));3:Self.Canvas.CopyRect(Rect(l+x*8+4,t+y*8,l+x*8+8,t+y*8+4), img1.Canvas,Rect(0+x*8+4,0+y*8,0+x*8+8,0+y*8+4));end;end;end;i:= i+1;if i>3 then tmr1.Enabled:= False;end;end;procedure TForm1.btn2Click(Sender: TObject);beginif not dlgOpen1.Execute then Exit;img1.Picture.LoadFromFile(dlgOpen1.FileName);T:= Img1.Top;l:= img1.Left;b:= img1.Top+ img1.Height;r:= img1.Left+ img1.Width;end;end.。
Delphi基本图像处理方法.
本文实例汇总了Delphi基本图像处理方法。
分享给大家供大家参考。
具体分析如下: //浮雕 procedureEmboss(SrcBmp,DestBmp:TBitmap;AzimuthChange:integer;overload; var i, j, Gray, Azimuthvalue, R, G, B: integer; SrcRGB, SrcRGB1, SrcRGB2, DestRGB: pRGBTriple; begin for i := 0 to SrcBmp.Height - 1 do begin SrcRGB := SrcBmp.ScanLine[i]; DestRGB := DestBmp.ScanLine[i]; if (AzimuthChange >= -180 and (AzimuthChange < -135 then begin if i > 0 then SrcRGB1 := SrcBmp.ScanLine[i-1] else SrcRGB1 := SrcRGB; Inc(SrcRGB1; SrcRGB2 := SrcRGB; Inc(SrcRGB2; end else if (AzimuthChange >= -135 and (AzimuthChange < -90 then begin if i > 0 thenSrcRGB1 := SrcBmp.ScanLine[i-1] else SrcRGB1 := SrcRGB; SrcRGB2 := SrcRGB1; Inc(SrcRGB2; end else if (AzimuthChange >= -90 and (AzimuthChange < -45 then begin if i > 0 then SrcRGB1 := SrcBmp.ScanLine[i-1] else SrcRGB1 := SrcRGB; SrcRGB2 := SrcRGB1; end else if (AzimuthChange >= -45 and (AzimuthChange < 0 then begin SrcRGB1 := SrcRGB; if i > 0 then SrcRGB2 := SrcBmp.ScanLine[i-1] else SrcRGB2 := SrcRGB; end else if (AzimuthChange >= 0 and (AzimuthChange < 45 then begin SrcRGB2 := SrcRGB; if (i < SrcBmp.Height - 1 then SrcRGB1 := SrcBmp.ScanLine[i+1] else SrcRGB1 := SrcRGB; end else if (AzimuthChange >= 45 and (AzimuthChange < 90 then begin if (i < SrcBmp.Height - 1 then SrcRGB1 := SrcBmp.ScanLine[i+1] else SrcRGB1 := SrcRGB; SrcRGB2 := SrcRGB1; end else if (AzimuthChange >= 90 and (AzimuthChange < 135 then begin if (i < SrcBmp.Height - 1 then SrcRGB1 := SrcBmp.ScanLine[i+1] else SrcRGB1 := SrcRGB; SrcRGB2 := SrcRGB1; Inc(SrcRGB1; end else if (AzimuthChange >= 135 and (AzimuthChange <= 180 then begin if (i < SrcBmp.Height - 1 then SrcRGB2 := SrcBmp.ScanLine[i+1] else SrcRGB2 := SrcRGB; Inc(SrcRGB2; SrcRGB1 := SrcRGB; Inc(SrcRGB1; end; for j := 0 to SrcBmp.Width - 1 do begin if (AzimuthChange >= -180 and (AzimuthChange < -135 then begin Azimuthvalue := AzimuthChange + 180; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed*Azimuthvalue div 45-((SrcRGB2.rgbtRed*(45-Azimuthvalue div45+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen*Azimuthvalue div 45-((SrcRGB2.rgbtGreen*(45-Azimuthvalue div 45+78; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue*Azimuthvalue div 45-((SrcRGB2.rgbtBlue*(45-Azimuthvalue div 45+78; end else if (AzimuthChange >= -135 and (AzimuthChange < -90 then begin Azimuthvalue := AzimuthChange + 135; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed*Azimuthvalue div 45-((SrcRGB2.rgbtRed*(45-Azimuthvalue div 45+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen*Azimuthvalue div 45-((SrcRGB2.rgbtGreen*(45-Azimuthvalue div 45+78; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue*Azimuthvalue div 45-((SrcRGB2.rgbtBlue*(45-Azimuthvalue div 45+78; end else if (AzimuthChange >= -90 and (AzimuthChange < -45 then begin if j=1 then Inc(SrcRGB1,-1; Azimuthvalue := AzimuthChange + 90;R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed*Azimuthvalue div 45-((SrcRGB2.rgbtRed*(45-Azimuthvalue div 45+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen*Azimuthvalue div 45-((SrcRGB2.rgbtGreen*(45-Azimuthvalue div 45+78; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue*Azimuthvalue div 45-((SrcRGB2.rgbtBlue*(45-Azimuthvalue div 45+78; end else if (AzimuthChange >= -45 and (AzimuthChange < 0 then begin if j=1 then begin Inc(SrcRGB1,-1; Inc(SrcRGB2,-1; end; Azimuthvalue := AzimuthChange + 45; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed*Azimuthvalue div 45-((SrcRGB2.rgbtRed*(45-Azimuthvalue div 45+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen*Azimuthvalue div 45-((SrcRGB2.rgbtGreen*(45-Azimuthvalue div 45+78; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue*Azimuthvalue div 45-((SrcRGB2.rgbtBlue*(45-Azimuthvalue div 45+78; end else if (AzimuthChange >= 0 and (AzimuthChange < 45 then begin if j=1 then begin Inc(SrcRGB1,-1; Inc(SrcRGB2,-1; end; Azimuthvalue := AzimuthChange; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed*Azimuthvalue div 45-((SrcRGB2.rgbtRed*(45-Azimuthvalue div 45+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen*Azimuthvalue div 45-((SrcRGB2.rgbtGreen*(45-Azimuthvalue div 45+78; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue*Azimuthvalue div 45-((SrcRGB2.rgbtBlue*(45-Azimuthvalue div 45+78; end else if (AzimuthChange >= 45and (AzimuthChange < 90 then begin if j=1 then Inc(SrcRGB2,-1; Azimuthvalue := AzimuthChange - 45; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed*Azimuthvalue div 45-((SrcRGB2.rgbtRed*(45-Azimuthvalue div 45+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen*Azimuthvalue div 45-((SrcRGB2.rgbtGreen*(45-Azimuthvalue div 45+78; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue*Azimuthvalue div 45-((SrcRGB2.rgbtBlue*(45-Azimuthvalue div 45+78; end else if (AzimuthChange >= 90 and (AzimuthChange < 135 then begin Azimuthvalue := AzimuthChange - 90;R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed*Azimuthvalue div 45-((SrcRGB2.rgbtRed*(45-Azimuthvalue div 45+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen*Azimuthvalue div 45-((SrcRGB2.rgbtGreen*(45-Azimuthvalue div 45+78; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue*Azimuthvalue div 45-((SrcRGB2.rgbtBlue*(45-Azimuthvalue div 45+78; end else if (AzimuthChange >= 135 and (AzimuthChange <= 180 then begin Azimuthvalue := AzimuthChange - 135;R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed*Azimuthvalue div 45-((SrcRGB2.rgbtRed*(45-Azimuthvalue div 45+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen*Azimuthvalue div 45-((SrcRGB2.rgbtGreen*(45-Azimuthvalue div 45+78; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue*Azimuthvalue div 45-((SrcRGB2.rgbtBlue*(45-Azimuthvalue div 45+78; end; R:=Min(R,255; R:=Max(R,0; G:=Min(G,255; G:=Max(G,0; B:=Min(B,255; B:=Max(B,0; Gray := (R shr 2 + (R shr 4 + (G shr 1 + (G shr 4 + (B shr 3; DestRGB.rgbtRed:=Gray; DestRGB.rgbtGreen:=Gray; DestRGB.rgbtBlue:=Gray; if (j=-180 and (AzimuthChange<-135 or ((AzimuthChange>=90 and (AzimuthChange<=180 then begin Inc(SrcRGB1; end; if (j=135 and (AzimuthChange<180 or ((AzimuthChange>=-180 and (AzimuthChange<=-90 then begin Inc(SrcRGB2; end;Inc(SrcRGB; Inc(DestRGB; end; end; end; procedureEmboss(Bmp:TBitmap;AzimuthChange:integer;ElevationChange:integer;WeightChange: integer;overload; var DestBmp:TBitmap; begin DestBmp:=TBitmap.Create; DestBmp.Assign(Bmp;Emboss(Bmp,DestBmp,AzimuthChange,ElevationChange,WeightChange;Bmp.Assign(DestBmp; end; //反色 procedure Negative(Bmp:TBitmap; var i, j: Integer; PRGB: pRGBTriple; begin Bmp.PixelFormat:=pf24Bit; for i := 0 to Bmp.Height - 1 do begin PRGB := Bmp.ScanLine[i]; for j := 0 to Bmp.Width - 1 do beginPRGB^.rgbtRed :=not PRGB^.rgbtRed ; PRGB^.rgbtGreen :=not PRGB^.rgbtGreen; PRGB^.rgbtBlue :=not PRGB^.rgbtBlue; Inc(PRGB; end; end; end; //曝光 procedure Exposure(Bmp:TBitmap; var i, j: integer; PRGB: pRGBTriple; beginBmp.PixelFormat:=pf24Bit; for i := 0 to Bmp.Height - 1 do begin PRGB :=Bmp.ScanLine[i]; for j := 0 to Bmp.Width - 1 do begin if PRGB^.rgbtRed<128 then PRGB^.rgbtRed :=not PRGB^.rgbtRed ; if PRGB^.rgbtGreen<128 thenPRGB^.rgbtGreen :=not PRGB^.rgbtGreen; if PRGB^.rgbtBlue<128 thenPRGB^.rgbtBlue :=not PRGB^.rgbtBlue; Inc(PRGB; end; end; end; //模糊 procedure Blur(SrcBmp:TBitmap; var i, j:Integer; SrcRGB:pRGBTriple; SrcNextRGB:pRGBTriple; SrcPreRGB:pRGBTriple; Value:Integer; procedure IncRGB; begin Inc(SrcPreRGB;Inc(SrcRGB; Inc(SrcNextRGB; end; procedure DecRGB; begin Inc(SrcPreRGB,-1;Inc(SrcRGB,-1; Inc(SrcNextRGB,-1; end; begin SrcBmp.PixelFormat:=pf24Bit; for i := 0 to SrcBmp.Height - 1 do begin if i > 0 then SrcPreRGB:=SrcBmp.ScanLine[i-1] else SrcPreRGB := SrcBmp.ScanLine[i]; SrcRGB := SrcBmp.ScanLine[i]; if i <SrcBmp.Height - 1 then SrcNextRGB:=SrcBmp.ScanLine[i+1] elseSrcNextRGB:=SrcBmp.ScanLine[i]; for j := 0 to SrcBmp.Width - 1 do begin if j > 0 then DecRGB; Value:=SrcPreRGB.rgbtRed+SrcRGB.rgbtRed+SrcNextRGB.rgbtRed; if j > 0 then IncRGB;Value:=Value+SrcPreRGB.rgbtRed+SrcRGB.rgbtRed+SrcNextRGB.rgbtRed; if j < SrcBmp.Width - 1 then IncRGB;Value:=(Value+SrcPreRGB.rgbtRed+SrcRGB.rgbtRed+SrcNextRGB.rgbtRed div 9; DecRGB; SrcRGB.rgbtRed:=value;if j > 0 then DecRGB;Value:=SrcPreRGB.rgbtGreen+SrcRGB.rgbtGreen+SrcNextRGB.rgbtGreen; if j > 0 thenIncRGB;Value:=Value+SrcPreRGB.rgbtGreen+SrcRGB.rgbtGreen+SrcNextRGB.rgbtGreen; if j < SrcBmp.Width - 1 then IncRGB;Value:=(Value+SrcPreRGB.rgbtGreen+SrcRGB.rgbtGreen+SrcNextRGB.rgbtGreen div 9; DecRGB; SrcRGB.rgbtGreen:=value; if j > 0 then DecRGB;Value:=SrcPreRGB.rgbtBlue+SrcRGB.rgbtBlue+SrcNextRGB.rgbtBlue; if j > 0 then IncRGB; Value:=Value+SrcPreRGB.rgbtBlue+SrcRGB.rgbtBlue+SrcNextRGB.rgbtBlue; if j < SrcBmp.Width - 1 then IncRGB;Value:=(Value+SrcPreRGB.rgbtBlue+SrcRGB.rgbtBlue+SrcNextRGB.rgbtBlue div 9; DecRGB; SrcRGB.rgbtBlue:=value; IncRGB; end; end; end; //锐化 procedureSharpen(SrcBmp:TBitmap; var i, j: integer; SrcRGB: pRGBTriple; SrcPreRGB: pRGBTriple; Value: integer; begin SrcBmp.PixelFormat:=pf24Bit; for i := 0 to SrcBmp.Height - 1 do begin SrcRGB := SrcBmp.ScanLine[i]; if i > 0 then SrcPreRGB:=SrcBmp.ScanLine[i-1] else SrcPreRGB:=SrcBmp.ScanLine[i]; for j := 0 to SrcBmp.Width - 1 do begin if j = 1 then Dec(SrcPreRGB;Value:=SrcRGB.rgbtRed+(SrcRGB.rgbtRed-SrcPreRGB.rgbtRed div 2;Value:=Max(0,Value; Value:=Min(255,Value; SrcRGB.rgbtRed:=value;Value:=SrcRGB.rgbtGreen+(SrcRGB.rgbtGreen-SrcPreRGB.rgbtGreen div 2;Value:=Max(0,Value; Value:=Min(255,Value; SrcRGB.rgbtGreen:=value;Value:=SrcRGB.rgbtBlue+(SrcRGB.rgbtBlue-SrcPreRGB.rgbtBlue div 2;Value:=Max(0,Value; Value:=Min(255,Value; SrcRGB.rgbtBlue:=value; Inc(SrcRGB; Inc(SrcPreRGB; end; end; end; [图像的旋转和翻转] 以下代码用ScanLine配合指针移动实现,用于24位色! //旋转90度 procedure Rotate90(const Bitmap:TBitmap; var i,j:Integer; rowIn,rowOut:pRGBTriple; Bmp:TBitmap; Width,Height:Integer; begin Bmp:=TBitmap.Create; Bmp.Width := Bitmap.Height; Bmp.Height := Bitmap.Width; Bmp.PixelFormat := pf24bit; Width:=Bitmap.Width-1; Height:=Bitmap.Height-1; for j := 0 to Height do begin rowIn := Bitmap.ScanLine[j]; for i := 0 to Width do beginrowOut := Bmp.ScanLine[i]; Inc(rowOut,Height - j; rowOut^ := rowIn^; Inc(rowIn; end;end; Bitmap.Assign(Bmp; end; //旋转180度 procedure Rotate180(constBitmap:TBitmap; var i,j:Integer; rowIn,rowOut:pRGBTriple; Bmp:TBitmap;Width,Height:Integer; begin Bmp:=TBitmap.Create; Bmp.Width := Bitmap.Width; Bmp.Height := Bitmap.Height; Bmp.PixelFormat := pf24bit; Width:=Bitmap.Width-1; Height:=Bitmap.Height-1; for j := 0 to Height do begin rowIn := Bitmap.ScanLine[j]; for i := 0 to Width do begin rowOut := Bmp.ScanLine[Height - j]; Inc(rowOut,Width - i; rowOut^ := rowIn^; Inc(rowIn; end; end; Bitmap.Assign(Bmp; end; //旋转270度procedure Rotate270(const Bitmap:TBitmap; var i,j:Integer; rowIn,rowOut:pRGBTriple; Bmp:TBitmap; Width,Height:Integer; begin Bmp:=TBitmap.Create; Bmp.Width := Bitmap.Height; Bmp.Height := Bitmap.Width; Bmp.PixelFormat :=pf24bit; Width:=Bitmap.Width-1; Height:=Bitmap.Height-1; for j := 0 to Height do begin rowIn := Bitmap.ScanLine[j]; for i := 0 to Width do begin rowOut :=Bmp.ScanLine[Width - i]; Inc(rowOut,j; rowOut^ := rowIn^; Inc(rowIn; end; end; Bitmap.Assign(Bmp; end; //任意角度 functionRotateBitmap(Bitmap:TBitmap;Angle:Integer;BackColor:TColor:TBitmap; vari,j,iOriginal,jOriginal,CosPoint,SinPoint : integer; RowOriginal,RowRotated : pRGBTriple; SinTheta,CosTheta : Extended; AngleAdd : integer; beginResult:=TBitmap.Create; Result.PixelFormat := pf24bit;Result.Canvas.Brush.Color:=BackColor; Angle:=Angle Mod 360; if Angle<0 then Angle:=360-Abs(Angle; if Angle=0 then Result.Assign(Bitmap else if Angle=90 then begin Result.Assign(Bitmap; Rotate90(Result;//如果是旋转90度,直接调用上面的代码 end else if (Angle>90 and (Angle<180 then begin AngleAdd:=90; Angle:=Angle-AngleAdd; end else if Angle=180 then begin Result.Assign(Bitmap; Rotate180(Result;//如果是旋转180度,直接调用上面的过程 end else if (Angle>180 and (Angle<270 then begin AngleAdd:=180; Angle:=Angle-AngleAdd; end else if Angle=270 then begin Result.Assign(Bitmap; Rotate270(Result;//如果是旋转270度,直接调用上面的过程end else if (Angle>270 and (Angle<360 then begin AngleAdd:=270; Angle:=Angle-AngleAdd; end else AngleAdd:=0; if (Angle>0 and (Angle<90 then begin SinCos((Angle+ AngleAdd * Pi / 180, SinTheta, CosTheta; if (SinTheta * CosTheta < 0 then begin Result.Width := Round(Abs(Bitmap.Width * CosTheta - Bitmap.Height * SinTheta; Result.Height := Round(Abs(Bitmap.Width * SinTheta - Bitmap.Height * CosTheta; end else begin Result.Width := Round(Abs(Bitmap.Width * CosTheta + Bitmap.Height * SinTheta; Result.Height := Round(Abs(Bitmap.Width * SinTheta + Bitmap.Height * CosTheta; end; CosTheta:=Abs(CosTheta; SinTheta:=Abs(SinTheta; if (AngleAdd=0 or (AngleAdd=180 then begin CosPoint:=Round(Bitmap.Height*CosTheta;SinPoint:=Round(Bitmap.Height*SinTheta; end else beginSinPoint:=Round(Bitmap.Width*CosTheta; CosPoint:=Round(Bitmap.Width*SinTheta; end; for j := 0 to Result.Height-1 do begin RowRotated := Result.Scanline[j]; for i := 0 to Result.Width-1 do begin Case AngleAdd of 0: begin jOriginal := Round((j+1*CosTheta-(i+1-SinPoint*SinTheta-1; iOriginal := Round((i+1*CosTheta-(CosPoint-j-1*SinTheta-1; end; 90: begin iOriginal := Round((j+1*SinTheta-(i+1-SinPoint*CosTheta-1; jOriginal := Bitmap.Height-Round((i+1*SinTheta-(CosPoint-j-1*CosTheta; end; 180: begin jOriginal := Bitmap.Height-Round((j+1*CosTheta-(i+1-SinPoint*SinTheta; iOriginal := Bitmap.Width-Round((i+1*CosTheta-(CosPoint-j-1*SinTheta; end; 270: begin iOriginal := Bitmap.Width-Round((j+1*SinTheta-(i+1-SinPoint*CosTheta; jOriginal := Round((i+1*SinTheta-(CosPoint-j-1*CosTheta-1; end; end; if (iOriginal >= 0 and (iOriginal <= Bitmap.Width-1and (jOriginal >= 0 and (jOriginal <=Bitmap.Height-1 then begin RowOriginal := Bitmap.Scanline[jOriginal];Inc(RowOriginal,iOriginal; RowRotated^ := RowOriginal^; Inc(RowRotated; end else begin Inc(RowRotated; end; end; end; end; end; //水平翻转 procedure FlipHorz(const Bitmap:TBitmap; var i,j:Integer; rowIn,rowOut:pRGBTriple; Bmp:TBitmap;Width,Height:Integer; begin Bmp:=TBitmap.Create; Bmp.Width := Bitmap.Width; Bmp.Height := Bitmap.Height; Bmp.PixelFormat := pf24bit; Width:=Bitmap.Width-1; Height:=Bitmap.Height-1; for j := 0 to Height do begin rowIn := Bitmap.ScanLine[j]; for i := 0 to Width do begin rowOut := Bmp.ScanLine[j]; Inc(rowOut,Width - i; rowOut^ := rowIn^; Inc(rowIn; end; end; Bitmap.Assign(Bmp; end; //垂直翻转 procedureFlipVert(const Bitmap:TBitmap; var i,j:Integer; rowIn,rowOut:pRGBTriple;Bmp:TBitmap; Width,Height:Integer; begin Bmp:=TBitmap.Create; Bmp.Width := Bitmap.Height; Bmp.Height := Bitmap.Width; Bmp.PixelFormat := pf24bit;Width:=Bitmap.Width-1; Height:=Bitmap.Height-1; for j := 0 to Height do beginrowIn := Bitmap.ScanLine[j]; for i := 0 to Width do begin rowOut :=Bmp.ScanLine[Height - j]; Inc(rowOut,i; rowOut^ := rowIn^; Inc(rowIn; end; end; Bitmap.Assign(Bmp; end; [亮度、对比度、饱和度的调整] 以下代码用ScanLine配合指针移动实现! function Min(a, b: integer: integer; begin if a < b then result := a else result := b; end; function Max(a, b: integer: integer; begin if a > b then result := a else result := b; end; //亮度调整 procedure BrightnessChange(constSrcBmp,DestBmp:TBitmap;ValueChange:integer; var i, j: integer; SrcRGB, DestRGB: pRGBTriple; begin for i := 0 to SrcBmp.Height - 1 do begin SrcRGB :=SrcBmp.ScanLine[i]; DestRGB := DestBmp.ScanLine[i]; for j := 0 to SrcBmp.Width - 1 do begin if ValueChange > 0 then begin DestRGB.rgbtRed := Min(255, SrcRGB.rgbtRed + ValueChange; DestRGB.rgbtGreen := Min(255, SrcRGB.rgbtGreen + ValueChange; DestRGB.rgbtBlue := Min(255, SrcRGB.rgbtBlue + ValueChange; end else begin DestRGB.rgbtRed := Max(0, SrcRGB.rgbtRed + ValueChange; DestRGB.rgbtGreen := Max(0, SrcRGB.rgbtGreen + ValueChange; DestRGB.rgbtBlue := Max(0,SrcRGB.rgbtBlue + ValueChange; end; Inc(SrcRGB; Inc(DestRGB; end; end; end; //对比度调整 procedure ContrastChange(const SrcBmp,DestBmp:TBitmap;ValueChange:integer; var i, j: integer; SrcRGB, DestRGB: pRGBTriple; begin for i := 0 to SrcBmp.Height - 1 do begin SrcRGB := SrcBmp.ScanLine[i]; DestRGB := DestBmp.ScanLine[i]; for j := 0 to SrcBmp.Width - 1 do begin if ValueChange>=0 then begin if SrcRGB.rgbtRed >= 128 then DestRGB.rgbtRed := Min(255, SrcRGB.rgbtRed + ValueChange else DestRGB.rgbtRed := Max(0, SrcRGB.rgbtRed - ValueChange; if SrcRGB.rgbtGreen >= 128 then DestRGB.rgbtGreen := Min(255, SrcRGB.rgbtGreen + ValueChange else DestRGB.rgbtGreen := Max(0, SrcRGB.rgbtGreen - ValueChange; ifSrcRGB.rgbtBlue >= 128 then DestRGB.rgbtBlue := Min(255, SrcRGB.rgbtBlue + ValueChange else DestRGB.rgbtBlue := Max(0, SrcRGB.rgbtBlue - ValueChange; end else begin if SrcRGB.rgbtRed >= 128 then DestRGB.rgbtRed := Max(128,SrcRGB.rgbtRed + ValueChange else DestRGB.rgbtRed := Min(128, SrcRGB.rgbtRed - ValueChange; if SrcRGB.rgbtGreen >= 128 then DestRGB.rgbtGreen := Max(128, SrcRGB.rgbtGreen + ValueChange else DestRGB.rgbtGreen := Min(128,SrcRGB.rgbtGreen - ValueChange; if SrcRGB.rgbtBlue >= 128 thenDestRGB.rgbtBlue := Max(128, SrcRGB.rgbtBlue + ValueChange elseDestRGB.rgbtBlue := Min(128, SrcRGB.rgbtBlue - ValueChange; end; Inc(SrcRGB; Inc(DestRGB; end; end; end; //饱和度调整 procedure SaturationChange(const SrcBmp,DestBmp:TBitmap;ValueChange:integer; var Grays: array[0..767] of Integer; Alpha: array[0..255] of Word; Gray, x, y: Integer; SrcRGB,DestRGB: pRGBTriple; i: Byte; begin ValueChange:=ValueChange+255; for i := 0 to 255 do Alpha[i] := (i * ValueChange Shr 8; x := 0; for i := 0 to 255 do begin Gray := i - Alpha[i]; Grays[x] := Gray; Inc(x; Grays[x] := Gray; Inc(x; Grays[x] := Gray; Inc(x; end; for y := 0 to SrcBmp.Height - 1 do begin SrcRGB := SrcBmp.ScanLine[Y]; DestRGB := DestBmp.ScanLine[Y]; for x := 0 to SrcBmp.Width - 1 do begin Gray :=Grays[SrcRGB.rgbtRed + SrcRGB.rgbtGreen + SrcRGB.rgbtBlue]; if Gray +Alpha[SrcRGB.rgbtRed]>0 then DestRGB.rgbtRed := Min(255,Gray +Alpha[SrcRGB.rgbtRed] else DestRGB.rgbtRed := 0; if Gray +Alpha[SrcRGB.rgbtGreen]>0 then DestRGB.rgbtGreen := Min(255,Gray +Alpha[SrcRGB.rgbtGreen] else DestRGB.rgbtGreen := 0; if Gray +Alpha[SrcRGB.rgbtBlue]>0 then DestRGB.rgbtBlue := Min(255,Gray +Alpha[SrcRGB.rgbtBlue] else DestRGB.rgbtBlue := 0; Inc(SrcRGB; Inc(DestRGB; end; end; end; //RGB调整 procedureRGBChange(SrcBmp,DestBmp:TBitmap;RedChange,GreenChange,BlueChange:integer; var SrcRGB, DestRGB: pRGBTriple; i,j:integer; begin for i := 0 to SrcBmp.Height- 1 dobegin SrcRGB := SrcBmp.ScanLine[i]; DestRGB :=DestBmp.ScanLine[i]; for j := 0 to SrcBmp.Width - 1 do begin if RedChange> 0 then DestRGB.rgbtRed:= Min(255, SrcRGB.rgbtRed + RedChange else DestRGB.rgbtRed := Max(0, SrcRGB.rgbtRed + RedChange; if GreenChange> 0 then DestRGB.rgbtGreen :=Min(255, SrcRGB.rgbtGreen + GreenChange else DestRGB.rgbtGreen := Max(0, SrcRGB.rgbtGreen + GreenChange; if BlueChange> 0 then DestRGB.rgbtBlue :=Min(255, SrcRGB.rgbtBlue + BlueChange else DestRGB.rgbtBlue := Max(0, SrcRGB.rgbtBlue + BlueChange; Inc(SrcRGB; Inc(DestRGB; end; end; end; [颜色调整] //RGB<=>BGR procedure RGB2BGR(const Bitmap:TBitmap; var X: Integer; Y: Integer; PRGB: pRGBTriple; Color: Byte; begin for Y := 0 to (Bitmap.Height - 1 do begin forX := 0 to (Bitmap.Width - 1 do begin Color := PRGB^.rgbtRed; PRGB^.rgbtRed := PRGB^.rgbtBlue; PRGB^.rgbtBlue := Color; Inc(PRGB; end; end end; end; //灰度化(加权 procedure Grayscale(const Bitmap:TBitmap; var X: Integer; Y: Integer; PRGB: pRGBTriple; Gray: Byte; begin for Y := 0 to (Bitmap.Height - 1 do begin PRGB := Bitmap.ScanLine[Y]; for X := 0 to (Bitmap.Width - 1 do begin Gray := (77 * Red + 151 * Green + 28 * Blue shr 8; PRGB^.rgbtRed:=Gray; PRGB^.rgbtGreen:=Gray;PRGB^.rgbtBlue:=Gray; Inc(PRGB; end; end; end; 绘图区-即窗口显示图像的区域,亦可为全屏幕(在全屏幕下绘图的效果比一般窗口下好)中心点-即要绘图区显示的中心点在原始图像的坐标(声明:这个概念特别重要)先说说图像的放大,要放大一张图片,我们一般的做法是直接放大图像,但本文介绍的方法仅放大我们能够看到的部分,放大分两种情况,一种是放大后比绘图区还要小,这种情况没什么好说,当然是显示全部的图像;第二种是放大后的图像比绘图区大,这才是我们今天要讨论的重点话题,这种情况下我们先要确定图像放大后的大小,然后根据“中心点”计算在原始图像的位置和大小,最后把截取的图像放大到绘图区。
Delphi图像处理之图像二值化
Delphi图像处理之图像⼆值化-----------开发环境D7---效果图-------只提供参考----------------unit开始1unit Unit1;23interface45uses6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,7 Dialogs, ExtCtrls, StdCtrls, ExtDlgs;89type10 ThresholdValueArray=array of array of Byte ;11 TForm1 = class(TForm)12 Button1: TButton;13 Button2: TButton;14 Image1: TImage;15 Image2: TImage;16 OpenPictureDialog1: TOpenPictureDialog;17 Label1: TLabel;18 Button4: TButton;19 Label2: TLabel;20 EditX: TEdit;21 EditY: TEdit;22 Label3: TLabel;23 Label4: TLabel;24 Label5: TLabel;25 Label6: TLabel;26 Label7: TLabel;27procedure Button1Click(Sender: TObject);28procedure Button2Click(Sender: TObject);29procedure Button4Click(Sender: TObject);30procedure EditXChange(Sender: TObject);31private32function GetThresholdValue(sBmp: TBitmap; sX,sY: Byte): ThresholdValueArray;33function GetThresholdArrayGray(const sArray:ThresholdValueArray; sStartX, sEndX, sStartY, sEndY: word): Byte; 34{ Private declarations }35public36{ Public declarations }37end;3839var40 Form1: TForm1;4142implementation4344{$R *.dfm}4546procedure TForm1.Button1Click(Sender: TObject);47begin48if OpenPictureDialog1.Execute then49begin50 Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);51 Label1.Caption:='图⽚宽x⾼:'+inttostr(Image1.Picture.Width)+'x'+inttostr(Image1.Picture.Height);52end;53end;5455procedure TForm1.Button2Click(Sender: TObject);56const57 vThresholdValue:Byte=128;58var59 vP:PByteArray;60 x,y:Integer;61 vBmp:TBitmap;62 vGray:Integer;63begin64if Image1.Picture.Graphic =nil then65begin66 ShowMessage('没有图⽚!');67 Exit;68end;69 vBmp:=TBitmap.Create;70 vBmp.Assign(Image1.Picture.Bitmap);71 vBmp.PixelFormat:=pf24bit;72for y:=0to vBmp.Height-1do73begin74 vP:=vBmp.ScanLine[y];75for x:=0to vBmp.Width-1do76begin77 vGray:=(77*vP[3*x+2] + 149*vP[3*x+1] + 29*vP[3*x]) shr8;78if vGray>vThresholdValue then79begin80 vP[3*x+2]:=255;81 vP[3*x+1]:=255;82 vP[3*x]:=255;83end84else85begin86 vP[3*x+2]:=0;87 vP[3*x+1]:=0;88 vP[3*x]:=0;89end;90end;91end;92 Image2.Picture.Assign(vBmp);93 vBmp.Free;94end;9596function TForm1.GetThresholdArrayGray(const sArray: ThresholdValueArray; sStartX,97 sEndX, sStartY, sEndY: word): Byte;98var99 vGraySum:DWORD;100 i,j:Word;101begin102 Result:=128;//默认返回128103if sArray=nil then104 Exit;105 vGraySum:=0;106for i:=sStartX-1to sEndX-1do107begin108for j:=sStartY-1to sEndY-1do109begin110 vGraySum:=vGraySum+sArray[i,j];111end;112end;113 Result:=Round(vGraySum/((sEndX-sStartX+1)*(sEndY-sStartY+1)));114end;115116function TForm1.GetThresholdValue(sBmp: TBitmap; sX,117 sY: Byte): ThresholdValueArray;118119var120 i,j,x,y,vGray:Word;121 vLengthX,vLengthY,vModX,vModY:Word;122 vP:PByteArray;123 vBitmapGrayArray:ThresholdValueArray;124 vResultGrayArray:ThresholdValueArray;125begin126 Result:=nil;127if sBmp=nil then128 Exit;129if sX=0then130 sX:=1;131if sY=0then132 sY:=1;133 setlength(vBitmapGrayArray,sBmp.Width);134for i:=0to sBmp.Width-1do135begin136 setlength(vBitmapGrayArray[i],sBmp.Height);137end;138 SetLength(vResultGrayArray,sX);139for i:=0to sX-1do140begin141 SetLength(vResultGrayArray[i],sY);142end;143144for y:=0to sBmp.Height-1do145begin146 vP:=sBmp.ScanLine[y];147for x:=0to sBmp.Width-1do148begin149 vGray:=(77*vP[3*x+2] + 149*vP[3*x+1] + 29*vP[3*x]) shr8;150 vBitmapGrayArray[x,y]:=vGray;151end;152end;153 vLengthX:=sBmp.width div sX;154 vLengthY:=sBmp.Height div sY;155 vModX:=sBmp.width mod sX;156 vMody:=sBmp.Height mod sY;157for i:=0to sX-1do//⼩块158begin159for j:=0to sY-1do//⼩块160begin161if i<>sX-1then162begin163 vResultGrayArray[i,j]:=GetThresholdArrayGray(vBitmapGrayArray,vLengthX*i+1,vLengthX*i+vLengthX,vLengthY*j+1,vLengthY*j+vLengthY);164end165else//最后⼀列166begin167 vResultGrayArray[i,j]:=GetThresholdArrayGray(vBitmapGrayArray,vLengthX*i+1,vLengthX*i+vLengthX+vModX,vLengthY*j+1,vLengthY*j+vLengthY+vModY); 168end;169173 Result:=vResultGrayArray;174//数组释放175for i:=0to sBmp.Width-1do176begin177 setlength(vBitmapGrayArray[i],0);178end;179 setlength(vBitmapGrayArray,0);180end;181182procedure TForm1.Button4Click(Sender: TObject);183var184 vP:PByteArray;185 x,y:Integer;186 vBmp:TBitmap;187 vGray:Integer;188 vLengthX, vLengthY, vModX, vModY,vRowMod,vColMod: Word;189 vX,vY:Byte;190 vGrayArray:ThresholdValueArray;191 vRow,vCol:byte;192begin193if Image1.Picture.Graphic =nil then194begin195 ShowMessage('没有图⽚!');196 Exit;197end;198 vX:=StrToIntDef(editX.Text ,3);199 vY:=StrToIntDef(editY.Text ,3);200201//暂时最多分成255*255块202if (vX<1) or (vX>255) or (vY<1) or (vY>255) then203begin204 MessageBox(Handle,PChar('X和Y的范围:1到255; 请输⼊在这个范围内的数字!'),PChar(Application.Title),MB_ICONEXCLAMATION); 205 Exit;206end;207 Label6.Caption:='总块数:'+inttostr(vX*vY);208 vBmp:=TBitmap.Create;209 vBmp.Assign(Image1.Picture.Bitmap);210 vBmp.PixelFormat:=pf24bit;211212 vGrayArray:=GetThresholdValue(vBmp,vX,vY);213for y:=0to vBmp.Height-1do214begin215 vP:=vBmp.ScanLine[y];216 vRow:=y div vLengthY;217 vRowMod:=y div vLengthY;218if vRow<vY then219begin220if vRowMod>0then221 vRow:=vRow+1;222end;223for x:=0to vBmp.Width-1do224begin225 vCol:=x div vLengthx;226 vColMod:=x div vLengthx;227if vCol<vX then228begin229if vColMod>0then230 vCol:=vCol+1;231end;232 vGray:=(77*vP[3*x+2] + 149*vP[3*x+1] + 29*vP[3*x]) shr8;233if vGray>vGrayArray[vCol,vRow] then234begin235 vP[3*x+2]:=255;236 vP[3*x+1]:=255;237 vP[3*x]:=255;238end239else240begin241 vP[3*x+2]:=0;242 vP[3*x+1]:=0;243 vP[3*x]:=0;244end;245end;246end;247 Image2.Picture.Assign(vBmp);248 vBmp.Free;249end;250251procedure TForm1.EditXChange(Sender: TObject);252begin253 Label6.Caption:='总块数:'+inttostr(StrToIntDef(EditX.Text ,0)*strtointDef(EditY.Text,0));--------unit结束--------Form开始1object Form1: TForm12 Left = 5133 Top = 3264 Width = 9105 Height = 5286 Caption = 'Form1'7 Color = clBtnFace8 Font.Charset = DEFAULT_CHARSET9 Font.Color = clWindowText10 Font.Height = -1111 = 'MS Sans Serif'12 Font.Style = []13 OldCreateOrder = False14 PixelsPerInch = 9615 TextHeight = 1316object Image1: TImage17 Left = 818 Top = 1619 Width = 42520 Height = 33721 Center = True22 Proportional = True23 Stretch = True24end25object Image2: TImage26 Left = 44827 Top = 1628 Width = 42529 Height = 33730 Center = True31 Proportional = True32 Stretch = True33end34object Label1: TLabel35 Left = 1636 Top = 36037 Width = 38538 Height = 2539 AutoSize = False40 Caption = '图⽚宽x⾼:'41end42object Label2: TLabel43 Left = 52844 Top = 36045 Width = 27346 Height = 1347 Alignment = taCenter48 AutoSize = False49 Caption = '按块求出阈值'50end51object Label3: TLabel52 Left = 45753 Top = 38154 Width = 7355 Height = 1356 Caption = '输⼊X x Y块:'57end58object Label4: TLabel59 Left = 53360 Top = 38161 Width = 2462 Height = 1363 Alignment = taRightJustify64 AutoSize = False65 Caption = 'X:'66end67object Label5: TLabel68 Left = 62069 Top = 38070 Width = 2171 Height = 1772 Alignment = taRightJustify73 AutoSize = False74 Caption = 'Y:'75end76object Label6: TLabel77 Left = 70478 Top = 38379 Width = 18580 Height = 1381 AutoSize = False82 Caption = '总块数:'83end84object Label7: TLabel85 Left = 51286 Top = 44087 Width = 37788 Height = 4589 AutoSize = False90 Caption = '理应是块数分的越多,越准确!本⼈这个呈抛物线的感觉,'#13#10'有⼀个最优的块数,算了先不找原因了,抛砖引⽟,哈哈哈'91 WordWrap = True92end93object Button1: TButton94 Left = 1695 Top = 41696 Width = 16197 Height = 2598 Caption = 'Button1_加载图⽚'99 TabOrder = 0100 OnClick = Button1Click101end102object Button2: TButton103 Left = 232104 Top = 416105 Width = 177106 Height = 25107 Caption = 'Button2_⼆值化_默认阈值'108 TabOrder = 1109 OnClick = Button2Click110end111object Button4: TButton112 Left = 560113 Top = 407114 Width = 297115 Height = 25116 Caption = 'Button4_分块求平均阈值,按块⼆值化'117 TabOrder = 2118 OnClick = Button4Click119end120object EditX: TEdit121 Left = 567122 Top = 378123 Width = 49124 Height = 21125 ImeName = '中⽂(简体) - 搜狗拼⾳输⼊法'126 TabOrder = 3127 Text = 'EditX'128 OnChange = EditXChange129end130object EditY: TEdit131 Left = 649132 Top = 379133 Width = 47134 Height = 21135 ImeName = '中⽂(简体) - 搜狗拼⾳输⼊法'136 TabOrder = 4137 Text = 'EditY'138 OnChange = EditXChange139end140object OpenPictureDialog1: TOpenPictureDialog141 Filter = 'Bitmaps (*.bmp)|*.bmp'142 Left = 72143 Top = 368144end145end------------Form结束。
Delphi图形图像处理
1.3.TPen Object(画笔对象)
应用程序常用TPen对象在画布上绘制各种 线段,笔的颜色在Color属性中定义。线段 宽度在Width属性中定义。Style属性定义 了线段的各种类型
2.2.Shape组件
Shape组件用于在窗体中绘制几何图形, 如椭圆,矩形和圆角矩形等。
属性: (1)Shape:绘制图形的形状。 (2)Brush:几何图形中填充的颜色。 (3)Pen:几何图形所使用的线行。
2.3.PaintBox组件
该组件是一个简单的画板,它为应用程序提供了可 在窗体的特定区域内画图的方法。它和Image组件 不同,Image组件是显示已经保存在文件中的图像, 而PaintBox组件需要应用程序直接在窗体上进行 绘制。一旦该组件加入窗体,应用程序就可以利用 OnPaint事件在画板上画图。
这是一个32位二进制数据。Graphic单元中还定 义了一些常用的颜色常量,这些常量或直接映射 成系统调色板中最相近的颜色,或映射成 Windows 控制面板中颜色部分的系统视频颜色。 直接映射成系统调色板中的颜色有: ClAqua,CLBlack,ClBlue,ClbkGrray,ClFuchso a......ClYellow
椭圆,(x1,y1)是矩形左上角的象素坐标, x2,y2是矩形右下角的象素坐标。如果矩形 形成一个区域,将出现一个椭圆。
见例子
线条
LineTo(x,y : Integer); LineTo从当前位置画一条线至(x,y)所指定 的位置,并把笔的位置移至(x ,y)。
在Delphi中实现图片的旋转、缩放
在Delphi中实现图片的旋转、缩放好长时间没有写东西了并不是因为前面的东西遭受了很多西红柿和鸡蛋而是自己实在没有什么真实的东西写出来供大家参考但是最近在帮一个朋友做一个项目的时候遇到了在delphi中对图像的简单处理于是不停的从网上找资料翻看csdn以前的帖子从我搜索的结果发现很多人会在各种项目中遇到类似的图片处理问题但是多数得到的答案似乎并不完整(因为很多都没有结帖也可能是个人习惯的问题呵呵希望大家读了我这个文章之后能够家开结帖速度)于是我把我遇到的问题和解决方案写在下面供大家参考同时欢迎大家继续拍砖在正式内容之前要把我要解决的问题写在前面同时也让读者有一个好的定位从而不会因为我在处理过程中的拙劣手段而感到恼火这里主要解决的问题是在Delphi中将用扫描仪扫描得到的图片进行度旋转从而得到适合使用的图片并且由于不能正确把握图片的大小因此要对图片进行简单的缩放而我的解决方法也完全是根据此要求进行因为对于效率图片处理之后的清晰度考虑的不是很多同时带来的好处就是程序看起来很简单首先我没有扫描仪因此我不知道使用扫描程序(已经提供)得到的图片是什么格式而在Delphi的帮助中说 A bitmap is a powerful graphics object used to create manipulate (scale scroll rotate and paint) and store images in memory and as files on a disk 所以我的第一步就是要把我的片转化为TBitmap来处理在转化格式的同时我将图片的实际大小改变以适合后面选取部分图像的需要函数如下procedure TMainForm ChangeImageFormate;var Bitmap : TBitmap;Zoom : Integer;beginBitmap := TBitmap Create; // trywith ImageCert do beginBitmap Assign(Picture Graphic); // Picture := nil; // Zoom := Max(Bitmap Width div Width Bitmap Height div Height)+ ; // Width := Bitmap Width div Zoom; // Height := Bitmap Height div Zoom; // Canvas StretchDraw(Rect( Width Height) Bitmap); // end;finallyBitmapFree;end; end;我想这段代码并不是很复杂ImageCert是一个TImage控件放在Form上唯一可能陌生的就是第八句但是大家可以从Delphi的帮助中得到很到说明我在这就不再翻译了(我的建议就是多看帮助)同时应该指出的是第三句作用是很关键的如果去掉这一句同时你的图片格式不是bmp的话就会出现只有bitmap才能才能修改的错误第二步就是实现图片的旋转因为程序要求只是每次旋转度即可因此这里也比较容易处理处理的手段就是按照像素进行替换实现过程如下procedure TMainForm RotateImage;var x y : Integer;TmpBitMap : TBitmap;beginTmpBitMap := TBitmap Create;tryTmpBitMap Assign(ImageCert Picture Graphic);with ImageCert do beginPicture Bitmap Height := TmpBitMap Width;Picture Bitmap Width := TmpBitMap Height;for x:= to Height dofor y:= to Width doCanvas Pixels[TmpBitMap Height x y] := TmpBitMap Canvas Pixels[y x];Height := TmpBitMap Width;Width := TmpBitMap Height;end;finallyTmpBitMap Free;end;end;这段程序也没有什么好讲的但是几个高度和宽度的设置令我是分的烦闷总是觉得多做的点什么但是却偏偏去不掉任何一行如果哪位有兴趣可以尝试一下最好把结果也告诉我一声而且在这个里面由于TImage和TBitmap都有各自的canvas 所以使用哪一个可能也是值得研究的但是由于时间有限就没有在尝试了至于在部分取图的过程中我是用了一个TShape 然后用将brush 的style设置成bsclear 在ImageCert的onMouseMove中安排这个TShap的位置这样做不是很灵敏因为当鼠标在TShape上面时则不会起到作用所幸影响不大同时我在TShape的OnMouseDown事件中取出TShape下面的部分图片这个时候如果你的图片没有做过缩放处理就会发现取出的图片和我们看到的位置不相符(当然是在TImage 没有正确显示图片大小的情况下)可以肯定这个方法不是很好的方法但是至少它解决了问题lishixinzhi/Article/program/Delphi/201311/24976。
Delphi的图形处理
Delphi的图形处理Delphi的图形处理......................................................................................................- 1 - 第一章图像处理在可视化编程中的作用及其应用价值.................................- 2 - 第二章图像处理函数.......................................................................................- 2 -2.1 为什么选择Delphi..............................................................................- 2 -2.2 Delphi中用于图形处理的类...............................................................- 2 -2.3 GDI及Canvas类简介.........................................................................- 4 -第三章基本图像处理算法.............................................................................- 13 -3.1柔化和锐化处理.........................................................................................- 13 -3.2 图像混合(透明度)效果..............................................................................- 19 -3.3 转为灰度图像............................................................................................- 22 -3.4 对比度调整和反色处理.............................................................................- 23 -3.5 亮度的调整................................................................................................- 25 -3.6 浮雕效果....................................................................................................- 28 -3.7 马赛克效果................................................................................................- 31 -第一章图像处理在可视化编程中的作用及其应用价值图像处理,是可视化编程的基础内容。
delphi中的图像处理
图像处理基本知识彩色变灰度把一图由彩色变成灰度,也就是把每个像素的RGB各分量变为相同的,就成了灰度图像了pf24bit 模式下用BMP 的ScanLine 可以读取每一行的RGB数据.得到的是一个指针字节顺序是B,G,R亮度Y = 0.229R + 0.587G + 0.114B这个公式相当重要.以后很多图像处理都要用到它.方法1:方法一很简单,把RGB各分量相加,计算平均值,再设为新的RGB方法2:找出RGB 各分量中最大的.再设成新的RGB 值方法3:根据工式: Y = 0.229R + 0.587G + 0.114B算出亮度.新的RGB 各分量都为这个值.(个人认为第三种方法比较科学)代码:(方法一. 其它方法类似)bmp := TBitmap.Create;Bmp.Assign(Image1.Picture.Bitmap);bmp.HandleType :=bmDIB;bmp.PixelFormat := pf24bit;for j := 0 to bmp.Height -1 dobeginp := bmp.ScanLine[j];for i := 0 to Bmp.Width - 1 dobegingray1 :=Byte( (p[i*3] + p[i*3+1] + p[i*3+2]) div 3);p[i*3] := gray1;p[i*3+1]:= gray1;p[i*3+2] := gray1;end;end;Image2.Picture.Bitmap.Assign(bmp);bmp.free;==============================二值化:与灰度不同,二值化只有两种颜色.一般在做一些识别时用得比较多.方法:1, 计算出像素的亮度, 定义一个亮度阈值.2. 亮度大于这个阈值的像素,颜色为白,小于这个阈值的像素,颜色为黑.=======================================亮度调节取各个像素的RGB值,按比例加/减一个增量.也许用亮度公式来算出这个比例,比较科学.按一定比例,把部分的RGB 提升,一部分下降.================================-====Gamma校正(不太明白用在哪里.)分别把RGB 设为Min(255, round(255 * Power((OldValue / 256), 0.45))); NewValue := 255 乘(OldValue /256) 的 0.45 次方======================反色各分量取反.======================爆光小于128的取反。
基于Delphi扫描线技术的快速图像处理
基于Delphi扫描线技术的快速图像处理……t GRAPHICSPROGRAM………………………………………………………………………………………基于Delphi扫描线技术的快速图像处理张字摘要:传统的图像处理一般采用像素点赋值的方法,处理速度慢,对于大型图像几乎无能为力,而Delphi扫描线方法是对图像的每一行进行扫描,获得各像素的内存地址.这种内存操作比常规的像素点赋值效率高很多,从而可以大大提高大型位图图像的处理速度.关键词:内存操作;图像处理;扫描线Borland公司推出的Windows编程工具Delphi以其高度优化的编译器,强大的面向特性而越来越受到广大编程爱好者青睐,在许多大型项目如大型数据库系统设计,纹织CAD等企业级解决方案上有独特的优势.Delphi开发图像处理软件一般有两种基本方法:第一种方法是利用Delphi已经封装好了的可视化控件库VCL中已有的控件,Delphi中定义的类,对象,方法等,如Tlmage控件的一系列方法,TBitmap类的Scanline方法等,这种方法开发难度较低,开发者易于掌握;第二种方法是利用原生API或者经过Delphi稍微封装的函数开发,这种方法的特点是代码运行效率更高,节约资源,速度快,但同时开发难度稍大些.1原理Delphi提供了Canvas.Pixels属性,可以在画布(Canvas)上直接访问某一点的像素值.但用这个属性来执行访问速度很慢.比如,如果使用Pixels属性来把一个位图旋转90o,这种方法对于小的位图处理效果还是不错的,但是对于大一些的位图就无法接受了.它唯一的好处是,Canvas.Pixels属性对于所有的像素大小f1~24位1处理的方法都是一样的.在Delphi 中,可以替代Canvas.Pixels属性的就是直接引用WindowsAPI 来访问像素点数据f例如GetDIBits),但用WindowsAPI的DIB (DeviceIndependentBitmap)来访问像素数据更为复杂.假如使用DIB数据.则必须经常把它转换到TBitmap.并以Tlmage来显示.Delphi中TBitmap的Scanline和PixelFormat属性就提供了一个更好的Canvas.Pixels属性的代替.在Delphi的帮助中可以知道对Scanline的解释如下:propertyScanLine【Row:Integer]:Pointer;其中Row为位图图像的行号,返回的是一个指向位图像素数据的指针.通过Scanline可以获取某一行的所有像素点的信息,方便而且高速. 经测试,Scanline的速度为Canvas.PixelsIx]『y1Y方法的20倍以上.Delphi的Scanline包含了像素点的数据,但在访问像素数据以前,必须知道在内存中PixelFormat属性对Scanline属性的设计.因为不同的PixelFormat属性代表不同的位图格式,因而就有不同的Scanline方法.PixelFormat已在Graphics.pas 中定义了.其中包括pfCustom,pfDeviee,pflbit,pf4bit,pfSbit,pfl5bit.pf16bit.pf24bit和pf32bit.操作pf8bit位图相对容易,因为它的每个像素正好占一个字节,能够在pByteArray中直接访问.不过此时Seanline的值表示的是调色板上颜色的索引.调色板上包含了确切的R,G,B色.对于pf24bit的位图,首先定义一个类型:TypepRGBTripIeArray=TRGBTrIpIeArray:TRGBTripIeArray:ARRAY【0..32767】OFTRGBTriple;由于24bit的位图一个像素点是3个字节,不含调色板信息,所有的字节信息就是颜色信息,而由于pf32bit的位图一个像素点代表4个字节,Borland公司为此定义了一个类型(在Windows.pas下面1:pRGBQuad=q-RGBQuad;TRGBQuad=PACKEDRECORDrgbBlue:BYTE;rgbGreen:BYTE:rgbRed:B丫rE:rgbReserved:BYTE在颜色上.TRGBQuad和TRGBTriple是一样的.两者都用24位来记录颜色信息,8位红色,8位绿色,8位蓝色. TRGBQuad有更大一些的空间区域——"alpha"通道f在苹果机上较多采用).alpha通道在某些应用程序上用来传送灰度掩码信息,但现在还没有alpha通道相关的定义.要使用pf32bit 的Scanline就相当于要像使用单值动态数组一样来使用TBitmap.在测试中,用pf32bit的Scanline要比pf24bit快5%. 这就是32位属性的特点.所以用pf32bitSeanline有一些优势, 但是对于pt32bit来说,却没有那么多足够的空间来保存Scanline的值.一般在程序中将位图的格式设置为pf24bit就足够了…………………………………………………………实用第一智慧密集2图像的滤镜处理图像的滤镜处理可以用卷积运算来解决,卷积时使用一个奇数维的矩阵来表示.该矩阵体现在程序中就是模板概念.区域中的每个像素分别与模板中相应的元素相乘,相乘之和除以某个系数即为区域中心像素新值.不同的模板可以得到不同的效果.滤镜所用模板采用3x3矩阵,也可以采用5x5的矩阵,维数越大,处理时间越久.在采用模板操作时必须解决两个问题:一个是边界点问题,一般可以忽略第一列和最后一列像素的操作.或者直接进行边界像素的拷贝:还有一个是越界问题.必须保证中心像素点的各分量在0~255范围.为此定义一个存取模板矩阵值的数组v,长度为9,对于不同的滤镜效果,只需改变模板的矩阵值,而无需改动该处理过程.同时创建两个位图对象bmpl,bmp2,处理的思路是将Image控件上的位图分别加载到两个位图对象bmpl,bmp2中,其中从bmpi获取要处理的像素的信息,从bmp2获取要处理的像素的8个相邻像素信息.这样做的好处是从bmp2获取的是原始的未修改的信息,最后将bmpl显示于Image控件上.部分核心代码如下:V arbmp1.bmp2:TBitmap;//定义位图对象p1,p2,p3,p4:pByteArray;//定义字节指针j,j,z:integer;v:array[0..8】ofinteger;//定义模板数组beginz:=1://力口权后要除的系数bmpl:=TBitmap.Create;//l~Jj建位图对象1bmp2:=TBitmap.Create;//~U建位图对象2//力Ⅱ载位图到对象1中bmp1.Assign(image1.Picture.Bitmap);||格式转为24bitbmp1.PixeIFormat:=pf24bit;//力口载位图到对象2中|Q2.Assign(image1.Picture.Bitmap);//格式转为24bitbmp2.PixelFormat:=pf24bit;forj:=1tobmp1.height-2dobegin//扫描位图对象1第j行pl:=bmp1.ScanLine[j];∥扫描位图对象2的第卜1行p2:=bmp2.ScanLine[j一1】://扫描位图对象2的第1行p3:=bmp2.ScanLine[j];,/扫描位图对象2的第+1行p4:=bmp2.ScanLine[j+l】:fori:=1tobmp1.Width-2do与begin∥计算第个像素的红色分量p1【3i+2]:=min(255,max(O,((y【O】p213(i-1)+21+y[1lp213i+2】+y【2】p213(i+1)+2】+y【3】p313《i-1)+2】+yf4Jp313i+2】+yf5】p313(i+1)+21十yf6】p4[3(i-1)+2】+y【7lp413i+2】+y【8】p413(i+1)+2】))))//计算第i个像素的绿色分量p1【3i+1】:=min(255,max(0.((y【0Jp2【3({一1)+1l+y【1】p213i+11+y【2】p213(i+1)+1】+y【3】p313(i-1)+1】+Y【4】p313i+1l+y【5】p3[3(i+1)+1】+y【6】p4[3(i-1)+1】+y[7lp413i+1】+yl8lp413(i+1)+11))divz))://{十算第i个分量的蓝色分量p1【3il:=min(255,max(0,((y【O】p213(i-1)】+y【1lp213.】+y【2】p213(i十1)】+y【3】p3(i-1)】+y【4】p313i】+y{5】p313(1+ 1)】+y【6】p413(i-1)】+y【7lp4【3I】十yf81p4【3{i+1)】))": end;end;//将用模板处理后的位图重新显示Image1.Picture.Bitmap.Assign(Bmp1)Bmp1.free;//~放位图对象资源Bmp2.free;end;对于一幅24位的真彩色位图.代码中巧妙地利用Scanline获得了相邻三行像素的内存的起始地址,并由此取得特定像素点的R,G,B3个分量,其速度比用逐个的像素点操作快将近20倍,程序中的max和min函数有效地防止了中心像素点的越界可能.为了达到不同的滤镜效果,可以改变权系数数组Y,也就是改变模板矩阵Q.3图像的90.-决速旋转处理传统方法是将位图数据源像素信息赋予目的位置像素,最简单的方法就是采用Canvas.Pixel【x,y]赋值方式实现,这种方法的缺点是对于大型位图其实现速度非常慢.而扫描线方法可以获得旋转前位图和旋转后位图对应点的像素内存地址,通过把旋转前某点的像素值赋给旋转后对应点以达到整幅图像的旋转.这种基于内存的操作速度极快,核心代码如下:V araStream:TMemorystream;//定义内存流header:TBITMAPINFO;//定义位图信息头dc:hDC;//定义设备DCP:^THelpRGB;//定义一个THelpRGB类型的指针X,Y,b,h:Integer;RowOut:pRGBArray;//字节数组指针Begin∥创建一个内存流对象aStream:=TMemoryStream.Create;/y设置流的大小aStream.SetSizefBitmap.HeightBitmap.Width……GRAPHICSPROGIl 姗…………………………………………………………………………………………4):dc:=GetDC(O)//获得设备DCP:=aStream.Memory;//获得流的位置指针GetDIBits(dc,Bitmap.Handle,0,itmap.Height,Pheader,dib_RGB—Colors);ReleaseDC(O.dc);//释放设备DCb:=bitmap.Height;∥旋转前位图的高度h:=bitmap.Width;//旋转前位图的宽度bitmap.Width:=b:说//旋转后位图的宽度bitmap.height:=h:∥旋转后位图的高度forY:=0to(h一1)dObegin∥获得第Y行像素信息,这个是最重要的一步,节省时间row0ut:=Bitmap.ScanLine[y];∥获得内存指针P:=aStream.Memory;//将内存指针P位置增加Yinc(p,y):for×::0to(b-1)dobegin∥读取像素信息并且赋予相应位置rowout[x1:=p^.rgb;∥将内存指针P位置增加hinc(p,h);end;end;aStream.Free;//释放流资源end;4实验结果对比将一幅1024x768的24bit位图分别用Scanline方法和Canvas.Pixelfx,y】赋值方法进行旋转和高斯滤波,所用时问对比如表1所示.表1Scanline的方法和Canvas.Pixel【x,y】赋值方法处理时间比较Scanline疗法can,asPixe1[x.y]赋值方法实验名称所_刳时"1j所Hj时问高斯滤波13O270590.旋转l503240由表l也可以看出,采用Canvas,Pixellx,Y】方法的时间是Scanline方法的近20倍.其他的诸如位图的亮度,色度,饱和度等处理时间比较,Canvas.Pixel【x,y】方法的时间也接近Scanline方法时间的20倍.5结语Delphi的扫描线方法通过对位图图像的逐行扫描得到像素点的内存地址信息.所有的图像处理策略都在内存中实现.速度很快,这种优化方法对点阵图像的处理效果非常适合.对于大型位图图像,速度也很理想,用Scanline方法进行图像处理速度是像素点赋值速度的20倍以上.因此,Scanline方法越来越受到Delphi图像处理程序员的推崇.参考文献[1】MARCOCantu,王辉,李澎东,等译.Delphi从入门到精通[M】.北京:电子工业出版社,2002.[2】王华,梁志刚,王众,等.Delphi编程实例与技巧fM】.北京:机械工业出版社,2002.【3]阮秋琦.数字图像处理学【M】.北京:电子l[业出版社, 2002.【4]刘俊,王华.Delphi数字图像处理高级编程[M],北京:科学出版社.2003.(收稿日期:2009—12—26)升级到Windows7的好时机新一代操作系统受到业界好评近日,微软新一代操作系统Windows7自去年lO月份正式上市以来,凭借其优秀的整体性能和对生产力的明显促动,引发了众多用户的积极关注和采购热潮.其主流操作系统的地位已经广为市场接受.面对不断增长的企业用户对Windows7的需求,微软出台了一系列旨在推动Windows7企业客户的部署/使用的优惠措施,使企业客户可以在采用Windows7的新技术的过程中的各个环节.都能得到微软的针对性的支持和服务,还能以优惠的价格尽快迁移到Windows7最新数据表明,自Windows7正式发布至今,微软已经销售了超过9000万套许可,成为微软历史上上市以来销。
delphi tpngimage 用法
delphi tpngimage 用法TPNGImage 是 Delphi 中用于处理 PNG 图像的类,提供了一系列方法和属性来加载、保存和操作 PNG 图像。
下面是一些常用的 TpngImage 的用法示例:1. 加载 PNG 图像文件:```delphivarPngImage: TPngImage;beginPngImage := TPngImage.Create;tryPngImage.LoadFromFile('image.png');// 处理图像finallyPngImage.Free;end;end;```2. 保存 PNG 图像文件:```delphivarPngImage: TPngImage;beginPngImage := TPngImage.Create;try// 创建或加载图像// PngImage.LoadFromFile('image.png'); // 处理图像PngImage.SaveToFile('output.png');finallyPngImage.Free;end;end;```3. 访问图像宽度和高度:```delphivarPngImage: TPngImage;Width, Height: Integer;beginPngImage := TPngImage.Create;tryPngImage.LoadFromFile('image.png'); Width := PngImage.Width;Height := PngImage.Height;finallyPngImage.Free;end;end;```4. 处理图像的像素数据:```delphivarPngImage: TPngImage;X, Y: Integer;PixelColor: TColor;beginPngImage := TPngImage.Create;tryPngImage.LoadFromFile('image.png');for Y := 0 to PngImage.Height - 1 dobeginfor X := 0 to PngImage.Width - 1 dobegin// 获取像素颜色PixelColor := PngImage.Canvas.Pixels[X, Y];// 处理像素数据end;end;finallyPngImage.Free;end;end;```以上是一些 TPngImage 的常用用法示例,根据具体需求可以调用其他方法和属性来实现更多功能的操作。
Delphi编程_图形处理
7.2 画布的属性
Pen PenPos Brush Font Pixels CopyMode
7.2.1 Pen
绘图所用的画笔 主要控制绘图时的线条颜色、线型、粗细 主要属性
• Color
确定画笔的颜色
• Width
确定画笔的线条的宽度
• Mode
确定画笔的颜色和画布颜色组合的模式
9.1.1 画布的属性 一、Pen 表9-1 画笔的Mode 例:Draw_pmNot Draw_pmNot 二、PenPos 画笔当前的位置
三、Brush 画刷,填充画布上的区域和图形。 画刷的Style属性。 例:Brush 四、Font 五、Pixels
六、CopyMode 一个画布从另一个画布复制。 CopyMode的效果由三个因素决定: 1)原图像中的象素 2)目标图象中的象素 3)目标画刷的图案 例:CopyMode
9.1.2 画布常用的方法 Arc—画弧 Chord—画弓形 PolyLine— PolyLine—画折线 Polygone—画多边形 Rectangle—画矩形 FillRect—填充一个矩形 CopyRect—复制另一画布中的矩形区
9.3 绘制和刷新
Windows的绘制和刷新机制 例:Draw_pmNot Draw_pmNot 1)移动窗口 2)最大化窗口 3)最小化窗口再打开 4)用其他窗口遮盖本窗口的一部分
在窗口改变、移动或是被覆盖时,系统 会发送WM_PAINT消息,要求窗口刷新, 窗体调用OnPaint事件处理程序。 另一方面,窗口只重绘无效的部分。 例:DrawRefresh 1)Update:通知窗口重绘无效区 2)Invalidate 3)Update Rect:设定无效区
TextOut—绘制字符串 例:滚动显示文本
Delphi7 图形图像编程
(2)Brush属性
①Color属性 用来设置填充色,取值及含义与Pen的Color属性一样。 ②Style属性 该属性用来设置填充样式。图12-1是Brush颜色值为 clBlack时的Style属性值及其代表的样式。
图12-1 Brush对象的Style属性值及其代表的填充样式
(3)Pixels属性
图12-7 程序设计界面
图12-8 程序运行界面(一)
图12-9 程序运行界面(二)
12.2.2 典型实例二:照片自动展示程序
【实例题目】 制作一个照片自动展示程序,程序启动后将循环 显示照片,每张照片在屏幕上停留0.5秒。当用户单击 图片时将显示一个提示框,询问用户是否停止展示, 如果用户回答【是】将停止展示,回答【否】将接着 展示。程序的设计界面如图12-10所示,程序的运行 界面如图12-11所示。程序的运行界面如图12-11所示。 运行时如果单击照片,将会出现如图12-12所示的退 出提示框,在该提示框窗口上选中【Yes】按钮将退 出图片展示程序,单击【No】将继续展示。
图12-4 程序设计界面
图12-5 程序运行界面
2.TImage组件
TImage组件主要用于显示和处理图像,能够显示 BMP、JPEG、ICO、WMF、EMF等多种格式的图片。 它的主要属性如下: (1)Canvas属性 (2)Picture属性 例如,有下列语句: Image1.Picture.LoadFromFile('D:\A1.JPG'); 该语句的作用是把“D:\A1.JPG”图像文件显示在 TImage组件中。
该属性的声明如下: property C1ipRect:TRect;
(6)CopyMode属性
该属性用于设置从其他画布拷贝图像的方式
DELPHI基础教程:Delphi图形图像编程(二)[2]
DELPHI基础教程:Delphi图形图像编程(二)[2]另外一个问题是我们希望得到的是鼠标按钮按下和松开这两点所形成的图形但OnMouseMove却把鼠标轨迹上各点与起始点所形成的所有图形画在屏幕上这同样是我们不希望看到的为了解决这些问题程序定义了鼠标的三个事件procedure TForm FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X Y: Integer)beginDrawing := True;Image Canvas MoveTo(X Y)Origin := Point(X Y)MovePt := Origin;OriginPanel Caption := Format( Origin: (%d %d) [X Y])end;procedure TForm FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X Y: Integer)beginif Drawing thenDrawShape(Origin Point(X Y) pmCopy)Drawing := False;end;procedure TForm FormMouseMove(Sender: TObject; Shift: TShiftState; XY: Integer)beginif Drawing thenbeginDrawShape(Origin MovePt pmNotXor)MovePt := Point(X Y)DrawShape(Origin MovePt pmNotXor)end;MovePt用来记录鼠标当前位置当下次鼠标移动时就能在上次鼠标绘制的图形上画一个形状大小一样的图形并把画笔颜色设置成PmNotXor 使上次绘制的图形颜色变成了屏幕颜色从而达到橡皮擦的效果将画笔画刷的Style属性设置成用户希望的值可实现对画笔和画刷风格的选择procedure TForm SetBrushStyle(Sender: TObject)beginwith Image Canvas Brush dobeginif Sender = SolidBrush then Style := bsSolidelse if Sender = ClearBrush then Style := bsClearelse if Sender = HorizontalBrush then Style := bsHorizontal else if Sender = VerticalBrush then Style := bsVerticalelse if Sender = FDiagonalBrush then Style := bsFDiagonal else if Sender = BDiagonalBrush then Style := bsBDiagonal else if Sender = CrossBrush then Style := bsCrosselse if Sender = DiagCrossBrush then Style := bsDiagCross;end;procedure TForm SetPenStyle(Sender: TObject)beginwith Image Canvas Pen dobeginif Sender = SolidPen then Style := psSolidelse if Sender = DashPen then Style := psDashelse if Sender = DotPen then Style := psDotelse if Sender = DashDotPen then Style := psDashDotelse if Sender = DashDotDotPen then Style := psDashDotDot else if Sender = ClearPen then Style := psClear;end;end;图像对象概述TGraphic对象TGraphic对象是TBitmap TIcon Tmetafile对象的基类如果知道图像的具体类型(如位图图标元文件)则应将图像贮存在相应类型的对象中(如TBitmap TIcon Tmetafile)否则应该使用可贮存任何图像类型的TPicture对象TPicture对象TPicture对象可以保存位图图标或元文件 Graphic属性中包括图像的类型图像的高度和宽度分别定义在Height Width属性中调用LoadFromFile方法可以从文件中装载一幅图像procedure TForm FormCreate(Sender: TObject)beginBitBtn Glyph LoadFromFile( TARTAN BMP )end;要保存一个位图则要用SaveToFile方法要把图像复制到剪切板可以调用TClipboard对象的Assign方法TImage部件TImage部件用以在窗体中显示图像它的Picture 属性保存着要显示的图像这是一个TPicture对象AutoSize Stretch属性是用来调节部件与图像的大小的当AutoSize 为真值时TImage部件将根据它所包含的图像的大小来调整自身的大小当AutoSize为假值时不论图像有多大部件将保持设计时的大小如果部件比图像小那么只有一部分图像是可见的当Stretch为真值时位图像将根据部件的大小调整自身的大小当部件大小改变时元文件也做相应变化 Stretch属性对图标没有作用TBitmap Object(位图对象)位图对象包含一个位图图像有HBITMAP HPALETE句柄可自动管理调色板位图对象也有画布属性位图的Palette属性用来控制位图的颜色映射它包括种可显示的颜色如果应用程序用前景色绘制位图Palette 属性的颜色将被加入Windows系统调色板其它颜色被映射到系统调色板已存在的颜色如果应用程序用自己的颜色绘制位图而其它程序已占有系统调色板位图的颜色将被映射到系统调色板中如果Monochrome属性设置成假位图将显示成彩色反之显示成黑白色调用Draw和StretchDraw方法可在画布上绘制位图图像对象的应用本章例程中单击(文件|浏览)菜单项将弹出一个图像浏览窗体如果用户在窗体中选择文件列表框的图形文件窗体右上角的图像部件上将出现此文件所代表的图像若选择雕刻效果按钮中检查框窗体中的加速按钮和位图按钮上将出现位图以下代码是将图像文件装载至图像部件上procedure TImageForm FileListBox Click(Sender: TObject)varFileExt: string[ ];beginFileExt := UpperCase(ExtractFileExt(FileListBox Filename))if (FileExt = BMP ) or (FileExt = ICO ) or (FileExt = WMF )thenbeginImage Picture LoadFromFile(FileListBox Filename)Label Caption := ExtractFilename(FileListBox Filename)if (FileExt = BMP ) thenbeginLabel Caption := Label Caption +Format((%d x %d) [Image Picture Height Image PictureWidth])ViewForm Image Picture Bitmap := Image Picture Bitmap;ViewAsGlyph(FileExt)end;if FileExt = ICO then Icon := Image Picture Icon;if FileExt = WMF thenViewForm Image Picture Metafile := Image Picture Metafile;end;end;这个过程首先判断文件类型如果是图像文件则将图像装载至图像部件上并在标签上列出文件名称如果是位图文件还将显示其大小lishixinzhi/Article/program/Delphi/201311/25244。
基于Delphi的JPEG图像处理
procedure TForm1.Button1Click(Sender: TObject)?
Var
jpg1.compressD
Jpg1: TJPEGImageD
jpg1.SaveTofile(' c:\jpg.jpg' )D
Bmp2: TBitmapD
finally
Begin
jpg1.free;
Bmp2:= TBitmap.CreateD
3 结束语
J2EE 提供了简单、实用、标准化、分布式的 WEB 编程 方法,掌握这些方法会使程序开发者事半功倍。
参考文献 [1] 何桥,李肃义. Java 程序设计简明教程[M]. 北京:中国
水利水电出版社,2004. [2] 蔡剑,景楠. Java web 应用开发- J2EE 和 Tomcat[M]. 北
的 PicturePath 字段上,并可通过组件查看 Image1 在用户界
面中显示所选图像。
Image1.Picture.LoadFromFile(filename)? Adotable1.fieldbyname(' PicturePath' ).AsString:=filename?
(2)显示图像,首先从 picture 表中 PicturePath 字段
(7)Web 服务技术:是通过互联网进行远程应用服务
收稿日期:2007- 07- 05 * 刘建培 广东商学院教育技术中心实验师(广州 510320)
ing 设置为真,解压缩才能递增显示。 1.2 TJPEGImage 的主要方法
(1)Assign 方法。拷贝 JPEG 图像对象并且使它与内部 JPEG 数据源对象建立联系。如果要显示 JPEG 图像,可以调 用 Assign 方法把 JPEG 图像赋值给位图,然后显示。
delphi tpngimage 用法
delphi tpngimage 用法摘要:1.Delphi Tpngimage 简介2.Delphi Tpngimage 用法详解3.Delphi Tpngimage 的优点与不足正文:【Delphi Tpngimage 简介】Delphi Tpngimage 是一款由Borland 公司开发的图像处理组件,主要用于在Delphi 和C++Builder 开发环境下进行图片操作。
该组件提供了丰富的图像处理功能,如图像显示、保存、转换、裁剪、缩放、旋转等,极大地简化了开发者在图像处理领域的开发难度。
【Delphi Tpngimage 用法详解】Delphi Tpngimage 的使用方法主要包括以下几个步骤:1.首先,需要在项目中引入Tpngimage 组件。
打开Delphi 项目,在“Component”(组件)窗口中,找到Tpngimage 并拖拽到窗体上。
2.对Tpngimage 组件进行属性设置。
Tpngimage 组件有许多可设置的属性,如Image(图片)、SaveToFile(保存到文件)、LoadFromFile(从文件加载)等。
通过设置这些属性,可以实现对图片的各种操作。
3.为Tpngimage 组件编写事件处理程序。
Tpngimage 组件提供了一系列事件,如OnLoad(加载)、OnSave(保存)、OnPaint(绘制)等。
通过编写事件处理程序,可以响应组件的各种操作。
以保存图片为例,以下是使用Delphi Tpngimage 的详细步骤:1.在窗体上添加一个Tpngimage 组件。
2.设置Tpngimage 组件的Image 属性,加载需要保存的图片。
3.为Tpngimage 组件添加一个SaveToFile 事件处理程序。
4.在SaveToFile 事件处理程序中,使用Tpngimage 组件的SaveToFile 方法,将图片保存到指定的文件路径。
【Delphi Tpngimage 的优点与不足】Delphi Tpngimage 组件的优点主要体现在以下几个方面:1.功能丰富:Tpngimage 组件提供了丰富的图像处理功能,可以满足大部分开发者的需求。
基于DELPHI的图象压缩处理
JPEG的编码流程图: JPG的解码流程图: JPEG的解码流程图: 的解码流程图
BMP转换为JPEG: BMP转换为JPEG: 转换为
先设计好闪现窗体(窗体名字为flashform), 先设计好闪现窗体(窗体名字为flashform),但是保 flashform),但是保 存单元文件时,我用的是Flash,并运行, Flash,并运行 存单元文件时,我用的是Flash,并运行,直至看到了 效果 然后将Form1修改为Main,将单元文件由Unit1.pas 然后将Form1修改为Main,将单元文件由Unit1.pas修 Form1修改为Main,将单元文件由Unit1.pas修 Radar.pas,再运行 看到效果后,可以运行一下, 再运行, 改为 Radar.pas,再运行,看到效果后,可以运行一下, 再看看有没有闪现窗体和刚才设计的各种组件。 再看看有没有闪现窗体和刚才设计的各种组件。雷 达图像处理===图标为雷达图===成功!===== ===图标为雷达图===成功!=====我为各 达图像处理===图标为雷达图===成功!=====我为各 个菜单加了图标, panel设计的工具栏 设计的工具栏, 个菜单加了图标,用panel设计的工具栏,不加状态栏 了==== 接着就设计About对话框,然后运行看效果( 接着就设计About对话框,然后运行看效果(当然要 About对话框 在主窗体的相关按钮上添加相应的代码) 在主窗体的相关按钮上添加相应的代码),另外还要 在该对话框上添加关闭的代码
2. 霍夫曼编码压缩 3. LZW压缩方法 LZW压缩方法 4. 算术压缩方法
DCT压缩算法分析与实现 DCT压缩算法分析与实现
系统模块总图: 系统模块总图:
DCT压缩算法: DCT压缩算法: 压缩算法
Delphi扫描线的快速图像处理
B r n 公 司推出 的 Widw 编 程工具 D lh 以其高度优 ol d a nos ep i 化 的编译器 、强大 的面 向特 性而越 来越受 到广 大编程 爱好 者 青 睐 ,在许多大型项 目如大型数 据库系统设计 、纹织 C D等 A 企业级解决方案上有独特 的优势 。D lh 开发 图像处理软件一 ep i 般有两 种基本方法 : 第一种方 法是利 用 D lh 已经封装好 了的 e i p
摘 要 : 统 的 图像 处 理 一 般 采 用 像 素 点 赋 值 的 方 法 ,处 理 速 度 极 慢 , 于大 型 图像 几 乎 无 能 为 力 ,而 D lh 扫 描 线 传 对 e i p
方法是对 图像 的每一行进行扫描 ,获得各像素的 内存地 址。这种 内存操作 比常规 的像 素点赋值效率 高很 多,从 而可
以 大 大提 高 大 型位 图 图像 的 处 理 速 度 。
关键 词 : 内存操 作 ; 图像 处 理 ;扫描 线
F s ma e P o e sn a e n S a l e o l h at I g r c s i g B s d o c n i fDep i n
速 。经 测试 ,S al e的速度 为 C n a. xl x 【]方法 的 cni n a vs ie 】 Y P s【 y
2 0倍 以 上 。D lh 的 Sa l e包 含 了 像 素 点 的 数 据 , 在 访 问 e i p cni n 但
像 素数 据以前 ,必须 知道 在内存中 Pxlo t i F r 属性 对 S al e e ma c n n i
t pe d o ma e pr c s ig h s b e r a l mpr e . he s e fi g o e sn a e n g e ty i ov d K e o ds y w r :me r pe ai n; i g r ce sn mo y o r to ma e p o si g; s a lne c ni
Delphi中图像的像素级操作
Delphi中图像的像素级操作Delphi中图像的像素级操作华软源码一般的可视性编程语言,如VB本身只具有图像的一般显示功能, 加上简单的图像伸缩处理, 在进行一些图像复杂的特技显示时必须借助于Windows的有关API 函数。
但Delphi为用户提供了更为完善的图像处理能力, 依靠它本身的功能完全可以实现图像的像素级操作?疚慕樯芰薉elphi中像素级图像操作的基本原理、应用和实例。
一、基本原理在Delphi中有很多控件具有CANVAS属性, 即所谓的画布, 利用这一属性可以在控件的表面进行图形图像处理工作, 其中有一个CopyRect命令, 具体参数格式:Copyrect(Dest:TRect;Canvas:Tcanvas;Source:TRect);其中:Dest:目标画布矩形 Canvas:源画布 Source:源矩形,其功能是把图像从一个源矩形RECT内,复制到目标矩形RECT内, 复制的图像具有自动伸缩性质。
从这个命令的表面看只能进行图像的全部或部分复制功能,其实如果把矩形RECT定义成只有一个像素大小, 即可以从源图像中取出一个像素点, 即进行图像的像素级操作, 比如:Rect(0,0,1,1)可指定某图像源的左上角第一个像素。
二、像素级操作的应用图像的像素级操作可广泛应用在图像的特技显示效果制作工作中, 并且可以实现较为复杂的图像处理工作, 举例如下:1.图像的旋转: 在Delphi中利用其他方法显示图像时,比如利用图像框IMAGE 或者DRAW命令, 只能按原图的方向显示, 进行图像的旋转显示必须以像素为单位进行处理,重新安排像素的排列位置, 比如按先横向后纵向的方式读取原图像,然后按先纵向后横向的方式写像素,最终将形成旋转90度的图像,按同样的原理可形成旋转180度或270度的图像。
2.图像尺寸的改变: 图像尺寸的改变在Windows 中好象并不需要像素级操作, 利用图像框的伸缩性可以简单地完成这一工作, 但利用像素操作改变图像尺寸是图像放大或缩小操作的根本, 并且可以具有更高的精确和更高的灵活性?热绾嶙菹蚓扛粢坏闳∫幌袼? 连续写在目标画布上, 即可使图像缩小到原来的四分之一;而读出一点像素后, 在目标画布上连续写两点以上, 即可实现图像的放大显示。
Delphi中使用DirectDraw技术进行图形处理
Delphi中使用DirectDraw技术进行图形处理DirectDraw是一套名为DirectX复杂工具的一部分,DirectX是由许多不同的技术组成,比如:DirectDraw、Direct3D、DirectSound、DirectPlay、DirectInput和DirectSetup等。
其中的每一种技术都是集中了几种处多媒体的技术或游戏的技术,像声音播放、3D图形、网络播放、硬件设备如鼠标和强制反馈等等。
不过,在本章中将只介绍DirectDraw,并且这个主题很容易就会占用一章或更多的章节关于DirectX的其他技术内容,读者可以去参阅其他关于DirectX的书籍。
DirectDraw程序要求用户的系统必须有DirectDraw运行时的DLL,这些运行时文件(实际只是DLL的集合,可能许多机器已经安装了),还可以从Micorsoft的Web站点获取;该站点有各种各样的产品,包括游戏、Windows 98、将来的操作系统Windows NT 5等。
如果读者正在使用的是Windows NT 4,那么至少要用Service Pack 3(SP3)去升级,之后才能够访问作为SP3一部分的DirectDraw 3。
不要试图直接在Windows NT系统下安装运行时的DirectDraw,而应该安装最新的补丁(Service Pack),直接安装运行时的DirectDraw是针对Windows 95/98系统而言的。
确定一个系统是否安装了DirectDraw的一个方法是查看Windows/System或Winnt/System32目录是否存在DDRAW.DLL和DSOUND.DLL,如果有,则说明系统已经安装了DirectDraw。
在可能的情况下,读者应该从Microsoft获取DirectDraw SDK,通常它可以从Microsoft 的Web站点下载得到,不过请注意,它至少有30M。
安装了SDK后,它在硬盘上创建一个名为DXSDK的目录,在这个目录之下是SDK目录,其中包含有各种各样的文档、用C/C++编写的示例文件和帮助文件。
Delphi实现计算机视觉常用图像处理算法
Delphi实现计算机视觉常用图像处理算法摘要:由于图像处理涉与到了大量的程序编制工作,因此,如何合理选择一种简洁高效的编程工具,减少研究工作中的复杂性,就成为了计算机数字图像处理中不可回避的问题。
本文就利用Delphi实现对计算机视觉中常用图像处理方法。
关键词:计算机视觉;数字图像处理;DelphiThe Algorithms for Image Processing ofComputerVision Implemented in Delphi Abstract:Image processing involves lots ofprogramming. Hence how to select a programming toolwith simplicity andhigh efficiency became an unavoidable problem in computer-based digital image processing. For reference, this articleimplemented the image processing algorithms in common usewith Delph.iKey words:computer vision; digital image processing; Delphi1 引言计算机视觉[1]是采用各种成象系统代替视觉器官作为输入手段,并通过计算机技术来完成替代大脑完成处理和解释任务的一门学科,其最终研究目标就是使计算机能象人那样通过视觉观察和理解世界,具有自主适应环境的能力。
在计算机视觉的发展过程中,图像处理、模式识别、图像理解这一系列相关学科的发展对其有着至关重要的推动作用。
本文中,就将如何利用Delphi开发工具对计算机视觉中应用较多的一些数字图像处理方法进行实现进行详细讨论。
1 Delphi实现技术在Delphi中,专门定义了一组对象和部件用以绘制图形[2],完成一些简单的图像功能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
见例子
画矩形
StretchDraw StretchDraw(Const Rect : TRcct : Graphic : TGraphic); 此方法在Rect参数指定的矩形内画一图像。图像 延伸改变大小以适应矩形。 Rectangle Rectangle(X1,y1,x2,y2 : Integer); Rectangle方法在画布上用当前画刷绘制矩形, (x1,y1)是矩形的左上角,(x2,y2)是矩形的右下 角。
三.图像对象概述 3.1. TGraphic对象
TGraphic对象是 TBitmap ,TIcon,Tmetafile对象的基类。 如果知道图像的具体类型( 如位图, 图标 元文件) , 则应将图像贮存在相应类型的 对象中( 如TBitmap,TIcon,Tmetafile), 否则应该使用可贮存任何图像类型的 TPicture对象。
把点连成线
Polygon Polygon(Points : array of TPrint); Polygon方法在画布上绘制一系列的点,各点依 次连成线,最后将首尾两点相接形成一个区域, 并用当前笔刷填充此区域。 Polyline Polyline(Ports : array of TPort); Polyline方法在画布上用当前画笔绘制一系列的 点,各点依次连成线。
Tbrush对象方法
(1)Assign:向另一个对象赋值 (2)Create:创建一个TBrush对象实例。 (3)Destroy:释放一个TBrush对象实例。 (4)OwnHandle:用来确保对更基本的Qbrush 类实例的权限。当需要接受QBrush handle使用 或销毁权限时需要用到这个过程。 (5)ReleaseHandle:用来把TBrush 从 QBrush handle中分离出来,当需要把TBrush handle 给一段程序或一个类时,用到这个函数。
2.2.Shape组件
Shape组件用于在窗体中绘制几何图形, 如椭圆,矩形和圆角矩形等。 属性: (1)Shape:绘制图形的形状。 (2)Brush:几何图形中填充的颜色。 (3)Pen:几何图形所使用的线行。
2.3.PaintBox组件
该组件是一个简单的画板,它为应用程序提供了可 在窗体的特定区域内画图的方法。它和Image组件 不同,Image组件是显示已经保存在文件中的图像, 而PaintBox组件需要应用程序直接在窗体上进行 绘制。一旦该组件加入窗体,应用程序就可以利用 OnPaint事件在画板上画图。 属性: (1)Anchors:用来制定在运行过程中,当父组件(如 窗体或Panel组件)是可调时,它相对于父组件边 缘的位置。 (2)BoundsRect:指定组件的矩形边界,用其父 组件的坐标系来表示。 (3)Canvas:绘图。 (4)Color:组件的背景颜色。 (5)Constaints:强制组件的大小。
见例子
线条
LineTo(x,y : Integer); LineTo从当前位置画一条线至(x,y)所指定 的位置,并把笔的位置移至(x ,y)。 MoveTo(x,y : Integer); MoveTo 将笔的当前位置设置到点(x,y)处, 笔的当前位置在PenPos属性中,改变笔的 当前位置使用MoveTo方法
讲解要点
一.画布技术 (1)TCanvas Object(画布对象) (2)TBrush Object(画刷对象) (3)TPen Object(画笔对象) (4)TColor Object(颜色对象) 二.图形图像控件 (1)Image组件 (2)Shape组件 (3)PaintBox组件 三.图像对象概述 (1)TGraphic对象 (2)TPicture对象 (3)TImage部件 (4)TBitmap Object(位图对象) 四.案例 (1)放大图片 (2)图片倒置 (3)正弦曲线
见例子
复制位图
Brushcopy Brushcopy(const Dest : TRect;Bitmap : TBitmap;const Source TRect;Color : TColor); Brushcopy方法把位图的一部分复制到画布的某 个矩形区域,并用画笔的当前颜色替换位图的颜 色。参数Dest定义画布的一个矩形区域,该矩形 用以填充位图,Bitmap定义位图;Source定义 位图中的矩形区域,该区域上的位图将被复制; Color定义画笔中,用以替换位图的颜色。
பைடு நூலகம்
1.3.TPen Object(画笔对象)
应用程序常用TPen对象在画布上绘制各种 线段,笔的颜色在Color属性中定义。线段 宽度在Width属性中定义。Style属性定义 了线段的各种类型 Mode属性定义线段的颜色。可结合当前的 颜色、屏幕颜色或它们反转值,对线段的 颜色重新定义,但不改变Color属性。
画刷对象用以填充图形,如用画刷颜色或 图案对矩形或椭圆进行填充。TBrush拥有 一个画刷句柄(HBrush) 画刷的颜色定义在Color属性中。画刷还有 一个Bitmap属性,该属性只能在运行时得 到,画刷可使用位图填充图形以产生特殊 效果。位图大小为8个象素点长,高8个象 素点宽。Style属性定义了画刷填充图形的 风格
见壁纸的例子
附:画布对象的一些属性
常见属性 (1)Brush:画布使用的刷子,通过它设 置填充那个的颜色和图案 (2)CanvasOrientaion:设置画布坐标 (3)copyMode:设置拷贝图像的方式 (4)Font:画布中使用的字体 (5)Pen:画布的画笔
1.2.TBrush Object(画刷对象)
一.画布技术 1.1. TCanvas Object(画布对象)
TCanvas对象是一个用于绘图的表面,在这个区 域上,程序可实现各种绘图功能,很多部件(如 TIMage,TMemo)的Canvas属性就是TCanvas 对象。在部件上绘制图形就是在部件的画布上绘 制。TCanvas的Brush,Pen,Font属性分别是 TBrush,TPen,TFont对象,它们用于定义绘制图 形的风格。关于TBrush,TPen对象,下节中将详 细介绍。 TCanvas有对象很多方法,可完成常用的绘图功 能,现将方法及功能简介如下:
注:见delphi的TShape控件属性
1.4.TColor Object(颜色对象)
TColor类型用于定义一个对象的颜色。很多部件 的颜色属性就是TColor 类型, 在Graphics单元 中TColor定义如下:TColor = (COLOR_ENDCOLORS + 1)..$02FFFFF; 这是一个32位二进制数据。Graphic单元中还定 义了一些常用的颜色常量,这些常量或直接映射 成系统调色板中最相近的颜色,或映射成 Windows 控制面板中颜色部分的系统视频颜色。 直接映射成系统调色板中的颜色有: ClAqua,CLBlack,ClBlue,ClbkGrray,ClFuchso a......ClYellow
画一段弧线
Arc(x1,y1,x2,y2,x3,y3,x4,y4 : Integer); Arc方法在椭圆上画一段弧,椭圆由 (x1,y1),(x2,y2) 两点所确定的椭圆所决定。弧 的起点是椭圆圆周和椭圆中心与(x3,y3)连线的 交点。弧矩形终点是椭圆圆周和椭圆中心与 (x4,y4)连线的交点,以逆时针方向画弧。 Chord(x1,y1,x2,yx,x3,y3,x4,y4 : Integer);
四.案例
4.1.放大图片 4.2.颠倒图片 4.3.正弦曲线
3.3. TImage部件(见2.1节) 3.4. TBitmap Object(位图对象)
位图对象包含一个位图图像,有 HBITMAP,HPALETE句柄,可自动管理调 色板。位图对象也有画布属性。 bitbmp:TBitmap;//定义位图对象 bitmap:=TBitmap.Creat; //创建位图 对象 bitmap.LoadFromfile(‘filename’);//加 载位图 bitmap.Free;//释放
见例子
复制画布对象上的图像
CopyRect CopyRect(Dest : TRect;Canvas : TCanvas; Source TRect); 此方法从另一个画布对象上复制部分图像 到该画布。Canvas表示源画布,Source 是源画布上要复制的图像区域。Dest表示 目标画布上将接受复制图像的矩形区域。
Delphi图形图像处理
讲解人:汤磊 2008-07-28
内容提要
在Delphi中,专门定义了一组对象和部件 用以绘制图形,完成一些简单的图像功能。 利用这些对象、部件的方法,可以方便地 绘制各种常用图形;通过设置它们的属性, 能得到不同风格的图形。另外,通过对鼠 标事件的定义,可以方便的设计图形绘制 程序。
3.2. TPicture对象
TPicture对象可以保存位图、图标或元文件。 Graphic属性中包括图像的类型;图像的高度和 宽度分别定义在Height,Width属性中;调用 LoadFromFile方法,可以从文件中装载一幅图 像: procedure TForm1.FormCreate(Sender: TObject); begin BitBtn1.Glyph.LoadFromFile('TARTAN.BMP' ); end;
二.图形图像控件 2.1.Image组件
Image组件是一个容器组件,它在应用程序窗口 中提供一个矩形域,用于显示和输出位图、图标、 图元文件或用户自定义的图形文件。在应用程序 运行时它是不可见的。 该组件的属性: (1)Canvas:该属性指出了Timage进行绘图操 作的平面。 (2)Picture:显示的图像。 (3)AutoSize:确定图像是否自动调节大小。 (4)Center:图像是否居中显示 (5)Stretch:图像是大小是否随组件大小变化。