[常用滤镜效果] 对于浮雕效果,大家一般也看过些相关代码,但一般不支持角度变化!这里根据角度的不同,在一个像素周围的8个像素中取不同的两个运算得到新颜色值,用这个值和它求差值实现浮雕效果。用到了线性插值的思想,没有使用浮点运算! //浮雕 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<SrcBmp.Width - 1) or not (((AzimuthChange>=-180) and (AzimuthChange<-135)) or ((AzimuthChange>=90) and (AzimuthChange<=180))) then begin Inc(SrcRGB1); end; if (j<SrcBmp.Width - 1) or not (((AzimuthChange>=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; SrcRow:pRGBTriple; SrcNextRow:pRGBTriple; SrcPreRow:pRGBTriple; Value:Integer; procedure IncRow; begin Inc(SrcPreRow); Inc(SrcRow); Inc(SrcNextRow); end; procedure DecRow; begin Inc(SrcPreRow,-1); Inc(SrcRow,-1); Inc(SrcNextRow,-1); end; begin SrcBmp.PixelFormat:=pf24Bit; for i := 0 to SrcBmp.Height - 1 do begin if i > 0 then SrcPreRow:=SrcBmp.ScanLine[i-1] else SrcPreRow := SrcBmp.ScanLine[i]; SrcRow := SrcBmp.ScanLine[i]; if i < SrcBmp.Height - 1 then SrcNextRow:=SrcBmp.ScanLine[i+1] else SrcNextRow:=SrcBmp.ScanLine[i]; for j := 0 to SrcBmp.Width - 1 do begin if j > 0 then DecRow; Value:=SrcPreRow.rgbtRed+SrcRow.rgbtRed+SrcNextRow.rgbtRed; if j > 0 then IncRow; Value:=Value+SrcPreRow.rgbtRed+SrcRow.rgbtRed+SrcNextRow.rgbtRed; if j < SrcBmp.Width - 1 then IncRow; Value:=(Value+SrcPreRow.rgbtRed+SrcRow.rgbtRed+SrcNextRow.rgbtRed) div 9; if j < SrcBmp.Width - 1 then DecRow; SrcRow.rgbtRed:=value; if j > 0 then DecRow; Value:=SrcPreRow.rgbtGreen+SrcRow.rgbtGreen+SrcNextRow.rgbtGreen; if j > 0 then IncRow; Value:=Value+SrcPreRow.rgbtGreen+SrcRow.rgbtGreen+SrcNextRow.rgbtGreen; if j < SrcBmp.Width - 1 then IncRow; Value:=(Value+SrcPreRow.rgbtGreen+SrcRow.rgbtGreen+SrcNextRow.rgbtGreen) div 9; if j < SrcBmp.Width - 1 then DecRow; SrcRow.rgbtGreen:=value; if j > 0 then DecRow; Value:=SrcPreRow.rgbtBlue+SrcRow.rgbtBlue+SrcNextRow.rgbtBlue; if j > 0 then IncRow; Value:=Value+SrcPreRow.rgbtBlue+SrcRow.rgbtBlue+SrcNextRow.rgbtBlue; if j < SrcBmp.Width - 1 then IncRow; Value:=(Value+SrcPreRow.rgbtBlue+SrcRow.rgbtBlue+SrcNextRow.rgbtBlue) div 9; if j < SrcBmp.Width - 1 then DecRow; SrcRow.rgbtBlue:=value; IncRow; 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; |