How do I loop through all pixels on a TBitmap and get the pixel colors?

149 views Asked by At

I'm trying to loop through all the pixels on a TBitmap image and then display all the colors in a TMemo component.

I have a simple GUI with a TImage that contains the image that I want to loop through all pixels with and then a TButon that has a click event that will do the looping. Then also obviously the TMemo to display them into:

Delphi Form Designer

I've tried a lot of different code to loop through the Bitmap Pixels, but here's the latest code that I tried:

procedure TForm1.Button1Click(Sender: TObject);
var
  BitmapData: TBitmapData;
begin
  Memo1.Lines.Clear;
  var Bitmap := Image1.Bitmap;
  try
    if Bitmap.Map(TMapAccess.ReadWrite, BitmapData) then
    begin
      try
        for var Y := 0 to Bitmap.Height - 1 do
        begin
          for var X := 0 to Bitmap.Width - 1 do
          begin
            var PixelColor := BitmapData.GetPixel(X, Y);
            Memo1.Lines.Add('X: ' + X.ToString + ' | Y: ' + Y.ToString + ' | ' + AlphaColorToString(PixelColor))
          end;
        end;
      finally
        Bitmap.Unmap(BitmapData);
      end;
    end;
  finally
    Bitmap.Free;
  end;
end;

The above code gives me an out of memory exception:

Project raised exception class EOutOfMemory with message 'Out of memory'.


Can someone help me with code to loop through each pixel on a TBitmap and get the TAlphaColor of that pixel please?

1

There are 1 answers

0
Tom Brunberg On

Although it doesn't surprise me, that you get an out of memory error, there is a more severe problem in your code. The out of memory error you avoid by not printing out useless data in a TMemo. There might of course be very good reasons to print out a small amount of pixel colors. Your code to print the colors, works, if you just keep it from exhausting memory.

The more severe problem though is that you delete the Image1.bitmap, although Image1 is the owner and wants to hold on to it.

Remove Bitmap.Free from the end of your Button1Click procedure, as well as the outermost try..finally..end. The role of your var Bitmap is only to act as a convenient local reference to the Image1.Bitmap, not to take ownership.