[亮度、对比度、饱和度的调整] 以下代码用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; SrcRow, DestRow: pRGBTriple; begin for i := 0 to SrcBmp.Height - 1 do begin SrcRow := SrcBmp.ScanLine[i]; DestRow := DestBmp.ScanLine[i]; for j := 0 to SrcBmp.Width - 1 do begin if ValueChange>=0 then begin if SrcRow.rgbtRed >= 128 then DestRow.rgbtRed := Min(255, SrcRow.rgbtRed + (Abs(128 - SrcRow.rgbtRed) * ValueChange) div 128) else DestRow.rgbtRed := Max(0, SrcRow.rgbtRed - (Abs(128 - SrcRow.rgbtRed) * ValueChange) div 128); if SrcRow.rgbtGreen >= 128 then DestRow.rgbtGreen := Min(255, SrcRow.rgbtGreen + (Abs(128 - SrcRow.rgbtGreen) * ValueChange) div 128) else DestRow.rgbtGreen := Max(0, SrcRow.rgbtGreen - (Abs(128 - SrcRow.rgbtGreen) * ValueChange) div 128); if SrcRow.rgbtBlue >= 128 then DestRow.rgbtBlue := Min(255, SrcRow.rgbtBlue + (Abs(128 - SrcRow.rgbtBlue) * ValueChange) div 128) else DestRow.rgbtBlue := Max(0, SrcRow.rgbtBlue - (Abs(128 - SrcRow.rgbtBlue) * ValueChange) div 128); end else begin if SrcRow.rgbtRed >= 128 then DestRow.rgbtRed := Max(128, SrcRow.rgbtRed + (Abs(128 - SrcRow.rgbtRed) * ValueChange) div 128) else DestRow.rgbtRed := Min(128, SrcRow.rgbtRed - (Abs(128 - SrcRow.rgbtRed) * ValueChange) div 128); if SrcRow.rgbtGreen >= 128 then DestRow.rgbtGreen := Max(128, SrcRow.rgbtGreen + (Abs(128 - SrcRow.rgbtGreen) * ValueChange) div 128) else DestRow.rgbtGreen := Min(128, SrcRow.rgbtGreen - (Abs(128 - SrcRow.rgbtGreen) * ValueChange) div 128); if SrcRow.rgbtBlue >= 128 then DestRow.rgbtBlue := Max(128, SrcRow.rgbtBlue + (Abs(128 - SrcRow.rgbtBlue) * ValueChange) div 128) else DestRow.rgbtBlue := Min(128, SrcRow.rgbtBlue - (Abs(128 - SrcRow.rgbtBlue) * ValueChange) div 128); end; Inc(SrcRow); Inc(DestRow); 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; 如果有些图像处理的基础,这些代码都比较好理解,主要是三原色的值不要超过(0-255)的范围,有些朋友没有注意这问题,当超过范围后,会出现些难看的“色斑”! [颜色调整] //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; 关于灰度化,我的另一篇文章中进行了详细的探讨! |