---------------开发环境D7
图片要是bmp的,否则可能没有效果
--------------------------
左边的彩色的是原图,右边的是效果图(点击按钮3)
-----Unit开始
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, math;
type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Image2: TImage;
Button4: TButton;
Button5: TButton;
Button6: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);//RGB三个分量的平均值,把平局值赋值给RGB的三个分量
var
vP:PByteArray;
x,y:Integer;
vBmp:TBitmap;
gray:Integer;
begin
vBmp:=TBitmap.Create;
vBmp.Assign(Image1.Picture.Bitmap);
vBmp.PixelFormat:=pf24bit;//如果Image1.Picture.Bitmap不是24位的真彩BMP图片,请设置这个
for y:=0 to vBmp.Height -1 do
begin
vp:=vbmp.ScanLine[y];
for x:=0 to vBmp.Width-1 do
begin
gray:=(vp[3*x+2]+vp[3*x+1] +vp[3*x]) div 3; //RGB的平均值
vp[3*x+2]:=Byte(gray);
vp[3*x+1]:=Byte(gray);
vp[3*x]:=Byte(gray);
end;
end;
Image2.Picture.Bitmap:=vBmp;
vBmp.Free;
// for
end;
procedure TForm1.Button2Click(Sender: TObject); //RGB三个分量最大值代替原来的的RGB三个分量
var
vP:PByteArray;
x,y:Integer;
vBmp:TBitmap;
gray:Integer;
begin
vBmp:=TBitmap.Create;
vBmp.Assign(Image1.Picture.Bitmap);
vBmp.PixelFormat:=pf24bit;//如果Image1.Picture.Bitmap不是24位的真彩BMP图片,请设置这个
for y:=0 to vBmp.Height -1 do
begin
vp:=vbmp.ScanLine[y];
for x:=0 to vBmp.Width-1 do
begin
gray:=Max(vp[3*x+2],vp[3*x+1]);
gray:=Max(gray,vp[3*x]);
vp[3*x+2]:=Byte(gray);
vp[3*x+1]:=Byte(gray);
vp[3*x]:=Byte(gray);
end;
end;
Image2.Picture.Bitmap:=vBmp;
vBmp.Free;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
vP:PByteArray;
x,y:Integer;
vBmp:TBitmap;
gray:Integer;
begin
vBmp:=TBitmap.Create;
vBmp.Assign(Image1.Picture.Bitmap);
vBmp.PixelFormat:=pf24bit;//如果Image1.Picture.Bitmap不是24位的真彩BMP图片,请设置这个
for y:=0 to vBmp.Height -1 do
begin
vp:=vbmp.ScanLine[y]; //获取每行的像素
for x:=0 to vBmp.Width-1 do
begin
//利用YUV的颜色空间,求出Y的分量 ,公式:y=0.299R+0.587G+0.114B
//按这里把公式处理一下y=0.3R+0.59G+0.11B,再处理y=3/10 R+59/100 G+11/100 B
//Gray:=Round(vp[3*x+2]*0.3+vp[3*x+1]*0.59 +vp[3*x]*0.11);
//也许有人要说我多此一举,我只想说,浮点类型的计算其实比较复杂,这样处理一下,可能更快
//Gray:=Round((vp[3*x+2]*3)/ 10+(vp[3*x+1]*59) / 100 +(vp[3*x]*11) / 100);
//Gray:=(vp[3*x+2]*3) div 10+(vp[3*x+1]*59) div 100 +(vp[3*x]*11) div 100;
Gray:=(77 * vp[3*x+2] + 149 * vp[3*x+1] + 29 * vp[3*x]) shr 8 ;//这个感觉更好
{
解释一下这个shr 8,相当于除以256
77/256约等于0.3
149/256约等于0.58
29/256约等于0.11
}
//24位的真彩,一个像素占三个字节
vp[3*x+2]:=Byte(gray);//R
vp[3*x+1]:=Byte(gray);//G
vp[3*x]:=Byte(gray);//B
end;
end;
Image2.Picture.Bitmap:=vBmp;
vBmp.Free;
end;
procedure TForm1.Button4Click(Sender: TObject);
var
x,y,R,G,B:Integer;
vBmp:TBitmap;
gray:Integer;
vC:TColor;
begin
vBmp:=TBitmap.Create;
vBmp.Assign(Image1.Picture.Bitmap);
vBmp.PixelFormat:=pf24bit;//如果Image1.Picture.Bitmap不是24位的真彩BMP图片,请设置这个
for y:=0 to vBmp.Height -1 do
begin
for x:=0 to vBmp.Width-1 do
begin
vC:= vbmp.Canvas.Pixels[x,y]; //这样效率超级低,好慢
//WEB上的RGB刚好与这个相反
R:=vC and $FF;//R在低位
G:=(vC shr 8) and $FF;
B:=(vC shr 16)and $FF;
//利用YUV的颜色空间,求出Y的分量 ,公式:y=0.299R+0.587G+0.114B
//按这里把公式处理一下y=0.3R+0.59G+0.11B,再处理y=3/10 R+59/100 G+11/100 B
Gray:=(77 * R + 149 * G + 29 * B) shr 8 ;//这个感觉更好
//24位的真彩,一个像素占三个字节
vbmp.Canvas.Pixels[x,y]:=RGB(gray,gray,gray);
end;
end;
Image2.Picture.Bitmap:=vBmp;
vBmp.Free;
end;
procedure TForm1.Button5Click(Sender: TObject); //比前三个稍慢,但是比第四个快很多
var
x,y:Integer;
vBmp:TBitmap;
gray:Integer;
vP:PRGBTriple;
begin
vBmp:=TBitmap.Create;
vBmp.Assign(Image1.Picture.Bitmap);
vBmp.PixelFormat:=pf24bit;//
for y:=0 to vBmp.Height -1 do
begin
vP:=vbmp.ScanLine[y]; //获取每行的像素
for x:=0 to vBmp.Width-1 do
begin
Gray:=(77 * vP.rgbtRed + 149 * vp.rgbtGreen + 29 * vP.rgbtBlue) shr 8 ;
vbmp.Canvas.Pixels[x,y]:=RGB(gray,gray,gray);
inc(vP);
end;
end;
Image2.Picture.Bitmap:=vBmp;
vBmp.Free;
end;
procedure TForm1.Button6Click(Sender: TObject); //和第五个速度差不多
//array[0..32767] of Byte;
//array[0..16383] of Word;
type
PmyRGBArray=^TMyRGBArray;
TMyRGBArray=array[0..16383] of TRGBTriple;
var
x,y:Integer;
vBmp:TBitmap;
gray:Integer;
vP:PmyRGBArray;
begin
vBmp:=TBitmap.Create;
vBmp.Assign(Image1.Picture.Bitmap);
vBmp.PixelFormat:=pf24bit;
for y:=0 to vBmp.Height -1 do
begin
vP:=vbmp.ScanLine[y]; //获取每行的像素
for x:=0 to vBmp.Width-1 do
begin
Gray:=(77 * vP^[x].rgbtRed + 149 * vP^[x].rgbtGreen + 29 * vP^[x].rgbtBlue) shr 8 ;
vbmp.Canvas.Pixels[x,y]:=RGB(gray,gray,gray);
end;
end;
Image2.Picture.Bitmap:=vBmp;
vBmp.Free;
end;
end.
------Unit结束--
----------Form开始--------
//---图片请自行添加到Image1中(Image1.picture)
object Form1: TForm1
Left = 149
Top = 221
Width = 1201
Height = 705
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Image1: TImage
Left = 16
Top = 8
Width = 473
Height = 353
Center = True
Proportional = True
Stretch = True
end
object Image2: TImage
Left = 592
Top = 16
Width = 489
Height = 345
Center = True
Proportional = True
Stretch = True
end
object Button1: TButton
Left = 48
Top = 408
Width = 137
Height = 25
Caption = 'Button1_灰度方法1'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 48
Top = 464
Width = 137
Height = 25
Caption = 'Button2_灰度方法2'
TabOrder = 1
OnClick = Button2Click
end
object Button3: TButton
Left = 48
Top = 512
Width = 137
Height = 25
Caption = 'Button3_灰度方法3'
TabOrder = 2
OnClick = Button3Click
end
object Button4: TButton
Left = 280
Top = 408
Width = 177
Height = 25
Caption = 'Button4_不推荐这种方法'
TabOrder = 3
OnClick = Button4Click
end
object Button5: TButton
Left = 280
Top = 464
Width = 177
Height = 25
Caption = 'Button5_运用pRGBTriple'
TabOrder = 4
OnClick = Button5Click
end
object Button6: TButton
Left = 280
Top = 520
Width = 177
Height = 25
Caption = 'Button6_用TRGBTriple'
TabOrder = 5
OnClick = Button6Click
end
end
----------Form结束----------