读取像素并找到特定的RGB

时间:2014-06-27 11:31:48

标签: delphi

我想加载一个图像,并读取像素以找到某个RGB,但是然后检查下一个像素以确保它们匹配,并且我位于位图的正确位置。

我知道下面的代码是错误的,但我不确定如何纠正它。我也知道像素并不是读取像素的最快方法。

谢谢你们!

procedure RGB(Col: TColor; var R, G, B: Byte);
var
  Color: $0..$FFFFFFFF;
begin
  Color := ColorToRGB(Col);
  R := ($000000FF and Color);
  G := ($0000FF00 and Color) Shr 8;
  B := ($00FF0000 and Color) Shr 16;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  x,y : Integer;
  ColorN: TColor;
  R, G, B: Byte;
begin
  for Y := 0 to Image1.Picture.Bitmap.Height -1 do
  begin
    for X := 0 to Image1.Picture.Bitmap.Width -1 do
    begin
      inc(i);
      ColorN := Image1.Canvas.Pixels[x, y];
      RGB(ColorN, R, G, B);
      //Memo1.Lines.Append('Line: '+IntToStr(i)+' Y: '+IntToStr(Y)+' X: '+IntToStr(X)+' R: '+IntToStr(R)+' G: '+IntToStr(G)+' B: '+IntToStr(B));
      if (IntToStr(R) = '235') and (IntToStr(G) = '235') and (IntToStr(B) = '235') then //Y: 500 X: 587
      begin
        //Image1.Canvas.MoveTo(X,Y);
        //Image1.Canvas.LineTo(X,Y);
        ColorN := Image1.Canvas.Pixels[x +1, y];
        RGB(ColorN, R, G, B);
      end;
      if (IntToStr(R) = '232') and (IntToStr(G) = '232') and (IntToStr(B) = '232') then //RGB:232,232,232 Y: 500 X: 588
      begin
        ColorN := Image1.Canvas.Pixels[x +1, y];
        RGB(ColorN, R, G, B);
        ShowMessage('Test1');
      end;
      if (IntToStr(R) = '231') and (IntToStr(G) = '231') and (IntToStr(B) = '231') then //RGB: 231,231,231 Y: 500 X: 589
      begin
        ColorN := Image1.Canvas.Pixels[x +1, y];
        RGB(ColorN, R, G, B);
        ShowMessage('Test2');
      end;
      if (IntToStr(R) = '230') and (IntToStr(G) = '230') and (IntToStr(B) = '230') then //RGB: 230,230,230 Y: 500 X: 590
      begin
        ShowMessage('Test3');
      end;
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  b: TBitmap;
begin
  Image1.Picture.LoadFromFile('E:\Delphi Projects\Detect(XE6)\screen\1.png');
  b := TBitmap.Create;
  b.Assign(Image1.Picture.Graphic);
  Image1.Picture.bitmap := b;
  FreeAndNil(b);
end;

1 个答案:

答案 0 :(得分:3)

此代码中存在几个大问题:

  1. 只需检查IntToStr(R) = '235'
  2. ,而不是R=235,而不是if ColorN=C_Gray235
  3. 不是单独检查R,G和B,而是更容易检查C_Gray235 = #00EBEBEB; if (GetPixel(x, y) = C_Gray235) and (GetPixel(x+1, y) = C_Gray232) and (GetPixel(x+2, y) = C_Gray231) and (GetPixel(x+3, y) = C_Gray230) then begin //do stuff here end;
  4. 对于整个应用程序,我会使用单个if:

    for x := 0 to myBitmap.Width - 4

    请注意for循环应该是{{1}}(如果你的线路上剩下少于4个像素,那么就无法成功。实际上,如果你试图访问,你甚至可以获得一个AV它们,取决于你获得像素的方式)。

    现在,如果位图已经是24位或32位位图,则可以通过使用Bitmap.ScanLine [iLine]来提高性能......