Color to grayscale image

Dear Sirs:

How I can change an image (TBitMap or TJPEGImage) to grayscale. There is some functions API that do this.

Best regards.
mbrlaserAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DragonSlayerCommented:
something like this?

procedure GrayScale(b: TBitmap);
var
  i, j, Colr : Integer;
  sl : pRGBArray;  // Scanline
begin
  if b.PixelFormat <> pf24bit then begin
    ShowMessage('Not a 24Bit color bitmap!');
    Exit;
  end;
  for j:=0 to b.Height-1 do begin
    sl := b.ScanLine[j];
    for i:=0 to b.Width-1 do begin
      Colr:=HiByte(sl[i].rgbtRed * 77 + sl[i].rgbtGreen * 151 +
sl[i].rgbtBlue * 28);
      sl[i].rgbtRed := Colr;
      sl[i].rgbtGreen := Colr;
      sl[i].rgbtBlue := Colr;
    end;
  end;
end;

alternatively, look at
http://www.efg2.com/Lab/Library/UseNet/2002/0719.txt
http://www.efg2.com/Lab/Library/UseNet/1999/0311a.txt

for 256 colored bitmaps whereby you need to set the palette for it as well.
DragonSlayerCommented:
here's another one: (excerpt from http://www.advdelphisys.com/graphics/ads_Bitmap.html)

Function BitmapToGrayscale(
  Bitmap : TBitmap
  ): Boolean;
Var
  Jpeg    : TJPEGImage;
Begin
  Result := False;
  If Bitmap = nil Then Exit;
  Try
    Jpeg    := TJPEGImage.Create();
    Try
      Jpeg.Assign(Bitmap);
      Jpeg.CompressionQuality := 100;
      Jpeg.Compress;
      Jpeg.Grayscale := True;
      Bitmap.Canvas.Draw(0,  0,  Jpeg);
      Result := True;
    Finally
      Jpeg.Free;
    End;
  Except
    Result := False;
  End;
End;

Function BitmapToGrayscale(
  BitmapSource: TBitmap;
  BitmapOut   : TBitmap
  ): Boolean; OverLoad;
Var
  Bitmap : TBitmap;
Begin
  Bitmap := TBitmap.Create();
  Try
    Result := BitmapToGrayscale(Bitmap);
    If Result Then BitmapOut.Assign(Bitmap);
  Finally
    Bitmap.Free;
  End;
End;

Function BitmapToGrayscale(
  BitmapSourceFile: String;
  BitmapOutFile   : String
  ): Boolean; OverLoad;
Var
  Bitmap      : TBitmap;
Begin
  Result      := False;
  Try
    If Not FileExists(BitmapSourceFile) Then Exit;
    Bitmap    := TBitmap.Create();
    Try
      Bitmap.LoadFromFile(BitmapSourceFile);
      Result := BitmapToGrayscale(Bitmap);
      If Result Then
      Begin
        If FileExists(BitmapOutFile) Then DeleteFile(BitmapOutFile);
        Bitmap.SaveToFile(BitmapOutFile);
      End;
    Finally
      Bitmap.Free;
    End;
  Except
    Result := False;
  End;
End;

Function BitmapToGrayscale(
  BitmapFile: String
  ): Boolean; OverLoad;
Begin
  Result :=
    BitmapToGrayscale(
      BitmapFile,  //BitmapSourceFile: String;
      BitmapFile  //BitmapOutFile   : String
                );//): Boolean; OverLoad;
End;

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
pcsentinelCommented:
This gives a really good render

procedure MakeGrey(Bmp: TBitmap);
const
      GreyR = 11;
      GreyG = 59;
      GreyB = 30;
var
  lx: integer;
  ly: integer;
  lc: longint;
begin
  if Bmp.Empty then
    Exit;
  for lx := 0 to Bmp.Width do
  begin
    for ly := 0 to Bmp.Height do
    begin
      lc := Bmp.Canvas.Pixels[lx, ly];
      lc := (GetRValue(lc) * GreyR + GetGValue(lc) * GreyG +
            GetBValue(lc) * GreyB) div (GreyR + GreyG + GreyB);
      Bmp.Canvas.Pixels[lx, ly] := RGB(lc, lc, lc);
    end;
  end;
end;

call it with

  MakeGrey(lBmp);

passing in the bitmap you want greyed

regards

DragonSlayerCommented:
You might want to use scanline instead of pixel (see my code above) because scanline is *much* faster, very noticable if you are working on a large bitmap.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.