...invert an image?
Author: JaZz
function InvertBitmap ( MyBitmap : TBitmap ): TBitmap ;
var
x , y : Integer ;
ByteArray : PByteArray ;
begin
MyBitmap . PixelFormat := pf24Bit ;
for y := 0 to MyBitmap . Height - 1 do
begin
ByteArray := MyBitmap . ScanLine [ y ];
for x := 0 to MyBitmap . Width * 3 - 1 do
begin
ByteArray [ x ] := 255 - ByteArray [ x ];
end ;
end ;
Result := MyBitmap ;
end ;
procedure TForm1 . Button1Click ( Sender : TObject );
begin
Image1 . Picture . Bitmap := InvertBitmap ( Image1 . Picture . Bitmap );
Image1 . Refresh ;
end ;
---------------------------------------
我们首先需要知道图象显示的一些理论,计算机是用像素显示图像的,每个像素有像素深度值,每个像素包含的信息是不同的数字。
例如,图像的像素深度是8位,则每个像素可以储存256种颜色。每位可有两个值(0 或 1),于是就有2x2x2x2x2x2x2x2 = 256。
现在有24位和32位像素深度的图像,我只说明这种图像怎样实现反色。
在RGB颜色模式(R=红, G=绿, B=蓝)下的24位像素深度的图像中,包含3个颜色通道,每个通道各占8位,于是每个通道有256个可能值。3个颜色通道合起来显示最终图像。
理论已够了,我们可以利用以下过程实现:
procedure InvertImage(const AnImage:TImage);
var
BytesPorScan: integer;
vi_width, vi_height: integer;
p: pByteArray;
begin
//仅在24位或32位色下有效
If not (AnImage.Picture.Bitmap.PixelFormat in[pf24Bit, pf32Bit])then
raise exception.create(''Error, Format File not soported!'');
try
BytesPorScan := Abs(Integer(AnImage.Picture.Bitmap.ScanLine[1])-
Integer(AnImage.Picture.Bitmap.ScanLine[0]));
except
raise exception.create(''Error'');
end;
//翻转每个像素的RGB数值
for vi_height := 0 to AnImage.Picture.Bitmap.Height - 1 do
begin
P := AnImage.Picture.Bitmap.ScanLine[vi_height];
for vi_width := 0 to BytesPorScan - 1 do
P^[vi_width] := 255-P^[vi_width];
end;
AnImage.Refresh;
最重要的是for循环的部分。