//浮雕 procedure Emboss(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 then SrcRGB1 := 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) 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 < - 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 >= 45 ) and (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 ; procedure Emboss(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 begin PRGB^.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; 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 begin if PRGB^.rgbtRed< 128 then PRGB^.rgbtRed := not PRGB^.rgbtRed ; if PRGB^.rgbtGreen< 128 then PRGB^.rgbtGreen := not PRGB^.rgbtGreen; if PRGB^.rgbtBlue< 128 then PRGB^.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 ] else SrcNextRGB:=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 then IncRGB; 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 ; //锐化 procedure Sharpen(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 begin rowOut := Bmp . ScanLine[i]; Inc(rowOut,Height - j); rowOut^ := rowIn^; Inc(rowIn); end ; end ; Bitmap . Assign(Bmp); end ; //旋转180度 procedure Rotate180( 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[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 ; //任意角度 function RotateBitmap(Bitmap:TBitmap;Angle: Integer ;BackColor:TColor):TBitmap; var i,j,iOriginal,jOriginal,CosPoint,SinPoint : integer ; RowOriginal,RowRotated : pRGBTriple; SinTheta,CosTheta : Extended ; AngleAdd : integer ; begin Result:=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 begin SinPoint:=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- 1 ) and (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 ; //垂直翻转 procedure FlipVert( 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[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( 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 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); if SrcRGB . 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 then DestRGB . rgbtBlue := Max( 128 , SrcRGB . rgbtBlue + ValueChange) else DestRGB . 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调整 procedure RGBChange(SrcBmp,DestBmp:TBitmap;RedChange,GreenChange,BlueChange: integer ); var SrcRGB, DestRGB: pRGBTriple; i,j: integer ; 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 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 for X := 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 ; |