Delphi 获取图片颜色值、RGB、颜色差值
delphi 获取图片某一像素的颜色值
前言:在VCL里有GetPixel函数,可直接用,在FMX里直接用这个函数没有定义,在FMX的library中找这个函数在FMX.Graphics.TBitmapData.GetPixel中
结果我引用FMX.Graphics不行,引用FMX.Graphics.TBitmapData也不行,然后我就郁闷了半天。
后来我声明了一个TBitmapData变量,结果可以使用该函数了,我欣喜若狂…
在窗体上放一个Image,在Image的OnMouseUp事件中取出鼠标点击那点的像素
procedure TForm2.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
var
vBitMapData: TBitmapData;
color: TAlphaColor;
begin
if Image1.Bitmap.Map(TMapAccess.Write, vBitMapData) then
begin
color := vBitMapData.GetPixel(Round(X), Round(Y)); // 获取像素 返回类型为TAlphaColor
ShowMessage(IntToHex(color, 1)); //为十六进制的颜色值
end;
Image1.Bitmap.Unmap(vBitMapData);
end;
delphi 获取颜色值的RGB
前面获取到一个像素点的颜色值后(十六进制),比如说(黄色):FFD1C04C(共八位),我自认为前面两位代表透明度,其它顺序为R-G-B, 没想到顺序是G-B-R
下面为从十六进制解析RGB的函数:(这里是把FF当成了R)
function TForm2.HexColorToRGB(s: string): string; // 传进来的是颜色值
var
i: Integer;
R,G,B: Byte;
begin
i := s.ToInteger;
R := i and $FF;
G := (i shr 8) and $FF;
B := (i shr 16) and $FF;
// Result := Format('%.2x,%.2x,%.2x',[R,G,B]); // 返回十六进制的RGB
Result := Format('%.2d,%.2d,%.2d',[R,G,B]); // 返回RGB: 76,192,209
end;
我在画图上的颜色编辑器上输入R:76, G:192,B:209,画布上面显示的是蓝色,我又郁闷…
后来我把这三个数打错顺序输入,结果发现192,209,76才是原来的颜色,位数不是按RGB的顺序,而是按BRG的顺序,郁闷死我了
至少我在XE中结果是这样的。
function TForm2.HexColorToRGB(s: string): string; // 传进来的是颜色值
var
i: Integer;
R,G,B: Byte;
begin
i := s.ToInteger;
B := i and $FF;
R := (i shr 8) and $FF;
G := (i shr 16) and $FF;
// Result := Format('%.2x,%.2x,%.2x',[R,G,B]); // 返回十六进制的RGB
Result := Format('%.2d,%.2d,%.2d',[R,G,B]); // 返回RGB 192,209,76
end;
所以需要把原来函数的顺序变一下。
delphi 获取两个颜色差值
前面说了已经获取到颜色值了,现在需要比较两个颜色的差值。
两个颜色的根据RGB的差来取,有两种情况:
1.(R的平方+G的平方+B的平方)开根号,再两个颜色值相减获取差值。
2.(((R1-R2)的平方) + ((R1-R2)的平方) + ((R1-R2)的平方))开根号,即为差值
第一种情况差值比第二种情况差值小。
function TForm2.GetDoubleRGB(S1: string; S2: string): Integer; // 情况2
var
ss1, ss2: TStrings;
R1, G1, B1, R2, G2, B2, sum: Integer;
begin
ss1 := TstringList.create;
ss2 := TstringList.create;
ss1.CommaText := s1;
ss2.CommaText := s2;
R1 := ss1[0].ToInteger;
G1 := ss1[1].ToInteger;
B1 := ss1[2].ToInteger;
R2 := ss2[0].ToInteger;
G2 := ss2[1].ToInteger;
B2 := ss2[2].ToInteger;
sum := sqr(R1-R2) + sqr(G1-G2) + sqr(B1-B2);
Result := Round(sqrt(sum));
end;
function TForm2.GetSumRGB(S: string): Integer; // 情况1
var
ss: TStrings;
R, G, B, sum: Integer;
begin
ss := TstringList.create;
ss.CommaText := s;
R := ss[0].ToInteger;
G := ss[1].ToInteger;
B := ss[2].ToInteger;
sum := sqr(R) + sqr(G) + sqr(B);
Result := Round(sqrt(sum));
end;
在Image的OnMoseMove事件中先获取一点对比颜色值放在Edit1中,再以鼠标移动的坐标作为对比放在Edit2中。
procedure TForm2.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Single);
var
vBitMapData: TBitmapData;
sum, cl1, cl2: Integer;
color: TAlphaColor;
begin
if (Edit1.Text <> '') and (Edit2.Text <> '') then
begin
if Image1.Bitmap.Map(TMapAccess.Write, vBitMapData) then
begin
color := vBitMapData.GetPixel(Round(X), Round(Y));
Edit2.Text := HexColorToRGB('$' +IntToHex(color, 1));
CLB2.Color := color;//颜色组件
cl1 := GetSumRGB(Edit1.Text);
cl2 := GetSumRGB(Edit2.Text);
sum := cl1 - cl2;
if sum < 0 then sum := sum * -1;
Edit3.Text := sum.ToString;
end;
end;
Image1.Bitmap.Unmap(vBitMapData);
end;