[常用滤镜效果]
这里根据角度的不同,在一个像素周围的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 Dec(SrcRGB1);
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
Dec(SrcRGB1);
Dec(SrcRGB2);
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
Dec(SrcRGB1);
Dec(SrcRGB2);
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 Dec(SrcRGB2);
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
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
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
Dec(SrcPreRow);
Dec(SrcRow);
Dec(SrcNextRow);
end;
begin
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
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;