您的位置:首页 > 编程语言 > Delphi

DELPHI中图片处理若干小问题

2008-10-07 14:41 309 查看
1. delphi中TColor格式
TColor类使用四个字节表示颜色,用十六进制表示就是 $PPBBGGRR 高 8 位指明使用的调色板(允许 0-2),次高 8 位指明颜色中蓝(绿)色的亮度(允许0-254),次低 8 位指明绿(蓝)色的亮度(允许0-254),低 8 位指明红色的亮度(允许0-254)。
对于调色板,0 表示 使用系统的调色板,1 表示使用与当前调色板最匹配的调色板,2 表示使用与当前设备的逻辑调色板最接近的颜色。
对于颜色的亮度,数值约大表示亮度越高。

2. TColor和RGB颜色转换
有三个API可以从颜色值中取出R/G/B三个分量,
R:=GetRValue(Color);
G:=GetGValue(Color);
B:=GetBValue(Color);
而另外一个API可以将R/G/B三分量合成一个颜色值,就是RGB函数,返回COLORREF
Color:=RGB(R,G,B);

一般地,GetRValue的参数可以直接用TCOLOR类型数据,但某些情况下,TCOLOR值小于0时(我尚不知何种情况下会为负数),需要转换,delphi提供了一个函数ColorToRGB,该函数定义如下:

function ColorToRGB(Color: TColor): Longint;

begin

if Color < 0 then

Result := GetSysColor(Color and $000000FF) else

Result := Color;

end;

根据TCOLOR的结构原始类型是longint,红色是$000000ff,绿色是$0000ff00,蓝色是$00ff0000,利用and运算,我们可以将三原色的数值分离出来。如下:

var

colour:TColor; r,g,b:byte;

begin

colour:=clsilver;

r:=(colour and $000000ff);

g:=(colour and $0000ff00);

b:=(colour and $00ff0000);

end;

3. BMP模式转换
TBitmap中有个PixelFormat属性,官方解释如下:
pfDevice The bitmap is stored as a device-dependent bitmap.
pf1bit The bitmap is a device-independent bitmap with one bit per pixel (black and white palette) //黑白
pf4bit The bitmap is a device-independent bitmap that uses a 16-color palette. //16色
pf8bit The bitmap is a device-independent bitmap that uses a 256color palette. //256 色
pf15bit The bitmap is a device-independent true-color bitmap that uses 15 bits per pixel (RGB compression).
pf16bit The bitmap is a device-independent true-color bitmap that uses 16 bits per pixel (bitfield compression).

pf24bit The bitmap is a device-independent true-color bitmap that uses 24 bits per pixel. //24位真彩色
pf32bit The bitmap is a device-independent true-color bitmap that uses 32 bits per pixel (RGB compression).//32位真彩色
pfCustom The bitmap uses some other format. TBitmap does not support pfCustom.

因此,将Bitmap.PixelFormat修改成pf8bit就可以简单的将bmp转为256色。设置该属性的函数定义如下:

procedure TBitmap.SetPixelFormat(Value: TPixelFormat);

const

BitCounts: array [pf1Bit..pf32Bit] of Byte = (1,4,8,16,16,24,32);

var

DIB: TDIBSection;

Pal: HPalette;

DC: HDC;

KillPal: Boolean;

begin

if Value = GetPixelFormat then Exit;

case Value of

pfDevice:

begin

HandleType := bmDDB;

Exit;

end;

pfCustom: InvalidGraphic(@SInvalidPixelFormat);

else

FillChar(DIB, sizeof(DIB), 0);

DIB.dsbm := FImage.FDIB.dsbm;

KillPal := False;

with DIB, dsbm, dsbmih do

begin

bmBits := nil;

biSize := sizeof(DIB.dsbmih);

biWidth := bmWidth;

biHeight := bmHeight;

biPlanes := 1;

biBitCount := BitCounts[Value];

Pal := FImage.FPalette;

case Value of

pf4Bit: Pal := SystemPalette16;

pf8Bit: //设置成256色。

begin

DC := GDICheck(GetDC(0));

Pal := CreateHalftonePalette(DC);

KillPal := True;

ReleaseDC(0, DC);

end;

pf16Bit:

begin

biCompression := BI_BITFIELDS;

dsBitFields[0] := $F800;

dsBitFields[1] := $07E0;

dsBitFields[2] := $001F;

end;

end;

try

CopyImage(Handle, Pal, DIB);

PaletteModified := Pal <> 0;

finally

if KillPal then DeleteObject(Pal);

end;

Changed(Self);

end;

end;

end;

若自己写算法修改像素值实现,普遍使用如下公式:
Gray = R*0.299 + G*0.587 + B*0.114
  而实际应用时,希望避免低速的浮点运算,所以需要整数算法。
Gray = (R*299 + G*587 + B*114 + 500) / 1000
  RGB一般是8位精度,现在缩放1000倍,所以上面的运算是32位整型的运算。注意后面那个除法是整数除法,所以需要加上500来实现四舍五入。由于该算法需要32位运算,所以该公式的另一个变种很流行:
Gray = (R*30 + G*59 + B*11 + 50) / 100

如下算法经过测试通过,delphi7 +winxp,窗体上一个TImage,长宽各40像素,内装QQbmp头像一张,一个Tbitbtn。

procedure TForm1.BitBtn1Click(Sender: TObject);

var i,j,r :integer;tmp:TColor;rgbcolor:array[1..3] of byte;

begin

for i:=0 to 39 do begin

for j:=0 to 39 do begin

with self.Image1.Picture.Bitmap.Canvas do begin

tmp:= Pixels[i,j];

rgbcolor[1]:=GetRValue( tmp);

rgbcolor[2]:=GetGValue( tmp);

rgbcolor[3]:=GetBValue( tmp);

r:=(rgbcolor[1]*299+rgbcolor[2]*587+rgbcolor[3]*114+ 500) div 1000;

Pixels[i,j]:=rgb(r,r,r);

end;

end;

end;

end;

点击按钮后qq头像变灰,达到QQ下线后的灰头像效果。

===================================

非注明转载的文章和blog在未特殊声明情况下一般为本人原创或整理,版权 lonefox 所有,

http://blog.csdn.net/boythl

欢迎转载,但请注明出处,保留作者和版权信息。

===================================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: