//浮雕
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
;
|
图像基本处理方法
最新推荐文章于 2018-08-09 08:40:10 发布