Recent

Author Topic: Convert a picture to Gray  (Read 8716 times)

fpauw

  • New Member
  • *
  • Posts: 11
Convert a picture to Gray
« on: December 20, 2019, 12:39:20 pm »
I am trying to convert a color bitmap to a gray image.

The code works partly but The image is deformed. This only happens with BMP with a JPG it is ok %)
What do I miss.

Code: Pascal  [Select][+][-]
  1.  
  2. procedure TForm1.Button1Click(Sender: TObject);
  3. Var
  4.   ScanData: PRGBQuad;
  5.   ValR, ValG, ValB: Byte;
  6.   X, Y : Integer;
  7.   Mono: Double;
  8. begin
  9.   if openpicturedialog1.Execute then
  10.      Begin
  11.        Image1.Picture.LoadFromFile(openpicturedialog1.FileName);
  12.      end;
  13.  
  14.   Image7.Picture.Bitmap.Height := Image1.Height;
  15.   Image7.Picture.Bitmap.Width := Image1.Width;
  16.  
  17.   For Y:=0 To Image1.Height-1 Do
  18.   Begin
  19.     ScanData := Image1.Picture.Bitmap.ScanLine[Y];
  20.     For X:=0 To Image1.Width-1 Do
  21.     Begin
  22.       //   X, Y, TotalTime, DistCurve: Integer;Point to the pixel location
  23.       // Get RGB value of the pixel
  24.       ValR := ScanData^.rgbRed;
  25.       ValG := ScanData^.rgbGreen;
  26.       ValB := ScanData^.rgbBlue;
  27.  
  28.       //START Convert to gray
  29.       mono := (0.2125 * ValR) + (0.7154 * ValG) + (0.0721 * ValB);
  30.       Image7.Canvas.pixels[X,Y]:=StringToColor(IntToStr(Round(mono)*256*256+Round(mono)*256+Round(mono)));
  31.  
  32.       Inc(ScanData);
  33.     end;
  34.   end;
  35. end;
  36.  
« Last Edit: December 20, 2019, 12:41:04 pm by fpauw »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11448
  • FPC developer.
Re: Convert a picture to Gray
« Reply #1 on: December 20, 2019, 12:52:42 pm »
Make sure your BMP is the good format, 24 or 32-bit RGB(A)?

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: Convert a picture to Gray
« Reply #2 on: December 20, 2019, 12:55:53 pm »
The code in lines 14 and 15 (of the posted code snippet) is not necessary and in my opinion the reason for the issue because it forces the bitmap size to be equal to the size of the Image control. Suppose you loaded a photo of 6000x4000 (24 MPixel) into a TImage of 100x100 then this code would truncate the photo to this tiny size - certainly not what you want.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Convert a picture to Gray
« Reply #3 on: December 20, 2019, 01:53:02 pm »
Hi!

What the hell do you code complicated stuff in line 30?

Simplify it

Code: Pascal  [Select][+][-]
  1. Var monoByte : byte;
  2.  
  3. ....
  4. MonoByte := round(0.2125 * ValR + 0.7154 * ValG + 0.0721 * ValB);
  5. Image7.Canvas.pixels[X,Y]:= RBGtoColor(monoByte, monoByte,monoByte);
  6.  

Winni

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: Convert a picture to Gray
« Reply #4 on: December 20, 2019, 02:46:01 pm »
Adjusting to the sensitivity of the eye on the three base colors? https://en.wikipedia.org/wiki/Grayscale

lainz

  • Hero Member
  • *****
  • Posts: 4468
    • https://lainz.github.io/
Re: Convert a picture to Gray
« Reply #5 on: December 20, 2019, 02:54:30 pm »
Adjusting to the sensitivity of the eye on the three base colors? https://en.wikipedia.org/wiki/Grayscale

He means line 30 , this line

Code: Pascal  [Select][+][-]
  1. Image7.Canvas.pixels[X,Y]:=StringToColor(IntToStr(Round(mono)*256*256+Round(mono)*256+Round(mono)));

Replacing with

Code: Pascal  [Select][+][-]
  1. Image7.Canvas.pixels[X,Y]:= RBGtoColor(monoByte, monoByte,monoByte);

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Convert a picture to Gray
« Reply #6 on: December 20, 2019, 03:33:14 pm »
Thanx @lainz!

And @wp: I don't get you. I know that stuff described in wikipedia. Since 40 years.

Winni

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: Convert a picture to Gray
« Reply #7 on: December 20, 2019, 04:57:18 pm »
And @wp: I don't get you. I know that stuff described in wikipedia. Since 40 years.
Sorry. Careful reading is not by best strength...

fpauw

  • New Member
  • *
  • Posts: 11
Re: Convert a picture to Gray
« Reply #8 on: December 23, 2019, 08:32:46 am »
Make sure your BMP is the good format, 24 or 32-bit RGB(A)?

Thanks after converting the BMP to 32-bit the issue is gone!

fpauw

  • New Member
  • *
  • Posts: 11
Re: Convert a picture to Gray
« Reply #9 on: December 23, 2019, 11:39:48 am »
Hi!

What the hell do you code complicated stuff in line 30?

Simplify it

Code: Pascal  [Select][+][-]
  1. Var monoByte : byte;
  2.  
  3. ....
  4. MonoByte := round(0.2125 * ValR + 0.7154 * ValG + 0.0721 * ValB);
  5. Image7.Canvas.pixels[X,Y]:= RBGtoColor(monoByte, monoByte,monoByte);
  6.  

Winni

Thanks I tried this but than I get

unit1.pas(63,35) Error: Identifier not found "RBGtoColor"

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Convert a picture to Gray
« Reply #10 on: December 23, 2019, 11:44:58 am »
Thanks I tried this but than I get

unit1.pas(63,35) Error: Identifier not found "RBGtoColor"

Because it is RGBToColor(), not RBGToColor(). A simple typo :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

fpauw

  • New Member
  • *
  • Posts: 11
Re: Convert a picture to Gray
« Reply #11 on: December 23, 2019, 11:49:12 am »
Thanks I tried this but than I get

unit1.pas(63,35) Error: Identifier not found "RBGtoColor"

Because it is RGBToColor(), not RBGToColor(). A simple typo :)

Thanks It works :D

fpauw

  • New Member
  • *
  • Posts: 11
Re: Convert a picture to Gray
« Reply #12 on: December 23, 2019, 02:09:37 pm »
Now I try to speed it up with writing it back with a ScanLine. But than I get the error "Raised exception class 'External:SIGSEGV"

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. Var
  3.   ScanData, ResultData: PRGBQuad;
  4.   ValR, ValG, ValB: Byte;
  5.   X, Y: Integer;
  6.   monoByte : byte;
  7. begin
  8.   if openpicturedialog1.Execute then
  9.      Begin
  10.        Image1.Picture.LoadFromFile(openpicturedialog1.FileName);
  11.      end;
  12.  
  13.   Image7.Picture.Bitmap.Height := Image1.Height;
  14.   Image7.Picture.Bitmap.Width := Image1.Width;
  15.  
  16.   For Y:=0 To Image1.Height-1 Do
  17.   Begin
  18.     ScanData := Image1.Picture.Bitmap.ScanLine[Y];
  19.     ResultData := Image7.Picture.Bitmap.ScanLine[Y];
  20.     For X:=0 To Image1.Width-1 Do
  21.     Begin
  22.       //   X, Y, TotalTime, DistCurve: Integer;Point to the pixel location
  23.       // Get RGB value of the pixel
  24.       ValR := ScanData^.rgbRed;
  25.       ValG := ScanData^.rgbGreen;
  26.       ValB := ScanData^.rgbBlue;
  27.  
  28.       MonoByte := round(0.2125 * ValR + 0.7154 * ValG + 0.0721 * ValB);
  29.  
  30.       ResultData^.rgbRed   :=monoByte;
  31.       ResultData^.rgbGreen :=monoByte;
  32.       ResultData^.rgbBlue  :=monoByte;
  33.  
  34.       Inc(ScanData);
  35.       Inc(ResultData);
  36.     end;
  37.   end;
  38. end;
  39.  

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: Convert a picture to Gray
« Reply #13 on: December 23, 2019, 02:36:08 pm »
Setting width and height of the destination bitmap (Image7.Picture.Bitmap) equal to the size of the source control (Image1) is not correct because the source bitmap (Image1.Picture.Bitmap, or more general: Image1.Picture) may have a different size than the source control.

Try this instead of lines 13 and 14:
Code: Pascal  [Select][+][-]
  1. Image7.Picture.Bitmap.Width := Image1.Picture.Width;
  2. Image7.Picture.Bitmap.Height := Image1.Picture.Height;
  3.  
  4. // or: combine both in
  5. Image7.Picture.Bitmap.SetSize(Image1.Picture.Width, Image1.Picture.Height);
« Last Edit: December 23, 2019, 02:37:59 pm by wp »

fpauw

  • New Member
  • *
  • Posts: 11
Re: Convert a picture to Gray
« Reply #14 on: December 23, 2019, 02:58:24 pm »
Setting width and height of the destination bitmap (Image7.Picture.Bitmap) equal to the size of the source control (Image1) is not correct because the source bitmap (Image1.Picture.Bitmap, or more general: Image1.Picture) may have a different size than the source control.

Clear Thanks!

But I have still the  "Raised exception class 'External:SIGSEGV" error...


 

TinyPortal © 2005-2018