-1

我正在尝试分析 .Jpeg 图像 600x600,但这样做我希望它告诉我 RED 值高于 230 和 Green 值高于 200 的位置。现在我正在进行这个项目,但迭代时间太长整个图像,并得到像素颜色(Color= + inttostr(RGB))的奇怪值。谁能帮我一把?

type
  PRGBTripleArray = ^TRGBTripleArray;
  TRGBTripleArray = array[0..4095] of TRGBTriple;

procedure TForm2.Button1Click(Sender: TObject);
var
  RGB: Byte;
  X, Y: Integer;
  R, G, B: Byte;
  Bitmap1: TBitmap;
  ColorRGB: LongInt;
  Pixels: PRGBTripleArray;
begin
  Memo1.Lines.Clear;
  Bitmap1 := TBitmap.Create;
  try
    Bitmap1.Assign(Image1.Picture.Graphic);

    for Y := 0 to Bitmap1.Height - 1 do
    begin
      Pixels:= Bitmap1.ScanLine[Y];

      Memo1.Lines.Add('======================');
      Memo1.Lines.Add('Line # ' + IntToStr(Y));
      Memo1.Lines.Add('======================');

      for X := 0 to Bitmap1.Width - 1 do
      begin
        ColorRGB := ColorToRGB(Bitmap1.Canvas.Pixels[x, y]);
        R := GetRValue(ColorRGB);
        G := GetGValue(ColorRGB);
        B := GetBValue(ColorRGB);
        RGB:= R*G*B;

        Memo1.Lines.Add(
                'line='    + IntToStr(Y)
              + ' row='    + IntToStr(X)
              + ' Colour=' + IntToStr(RGB)
              + ' Red='    + IntToStr (R) // red
              + ' Green='  + IntToStr (G) // blue
              + ' Blue='   + IntToStr (B) // green
        )
      end;
    end;
  finally
    Bitmap1.free;
  end;
end;

end.
4

1 回答 1

3

If you want to log every pixel of your bitmap, which has red channel value greater than 230 and green value greater than 200, you might use the following. Don't forget to use BeginUpdate, EndUpdate pair for TMemo.Lines to lock potential frequent updating.

Anyway, you are still mixing two bitmap pixel access techniques together. Do not use Canvas.Pixels for large pixel array manipulation; it's very inefficient. Use only ScanLine for that:

type
  PRGBTripleArray = ^TRGBTripleArray;
  TRGBTripleArray = array[0..4095] of TRGBTriple;

procedure TForm1.Button1Click(Sender: TObject);
var
  C: TColor;
  X: Integer;
  Y: Integer;
  Bitmap: TBitmap;
  Pixels: PRGBTripleArray;
begin
  Bitmap := TBitmap.Create;
  try
    Bitmap.Assign(Image1.Picture.Graphic);

    Memo1.Lines.BeginUpdate;
    try
      for Y := 0 to Bitmap.Height - 1 do
      begin
        Pixels := Bitmap.ScanLine[Y];
        for X := 0 to Bitmap.Width - 1 do
        begin
          if (Pixels[X].rgbtRed > 230) and (Pixels[X].rgbtGreen > 200) then
          begin
            C := RGB(
              Pixels[X].rgbtRed,
              Pixels[X].rgbtGreen,
              Pixels[X].rgbtBlue
            );
            Memo1.Lines.Add(
              '===============' + sLineBreak +
              'Pixel[' + IntToStr(X) + '; ' + IntToStr(Y) + ']' + sLineBreak +
              'Color: ' + ColorToString(C) + sLineBreak +
              'Red channel: ' + IntToStr(Pixels[X].rgbtRed) + sLineBreak +
              'Green channel: ' + IntToStr(Pixels[X].rgbtGreen) + sLineBreak +
              'Blue channel: ' + IntToStr(Pixels[X].rgbtBlue)
            );
          end;
        end;
      end;
    finally
      Memo1.Lines.EndUpdate;
    end;
  finally
    Bitmap.Free;
  end;
end;
于 2013-02-26T19:43:54.710 回答