Board index » delphi » Converting TBitmap to greyscale

Converting TBitmap to greyscale


2005-09-22 12:42:27 AM
delphi74
Is there a simple way to do this please? Thanks. And to save bandwidth,
sincere thanks to all who answered any previous posts by me here.
 
 

Re:Converting TBitmap to greyscale

Here's one way :
type
TRGBArray = array[0..0] of TRGBTriple;
pRGBArray = ^TRGBArray;
procedure GreyScale(Src : TBitmap);
var
Lum, x, y : integer;
SrcLine : pRGBArray;
SrcGap : integer;
begin
Src.PixelFormat := pf24bit;
SrcLine := Src.ScanLine[0];
SrcGap := Integer(Src.ScanLine[1]) - Integer(SrcLine);
{$ifopt R+} {$define RangeCheck} {$endif} {$R-}
for y := 0 to pred(Src.Height) do begin
for x := 0 to pred(Src.Width) do begin
Lum := (SrcLine[x].rgbtRed * 77 + SrcLine[x].rgbtGreen * 151 +
SrcLine[x].rgbtBlue * 28) shr 8;
SrcLine[x].rgbtRed := Lum;
SrcLine[x].rgbtGreen := Lum;
SrcLine[x].rgbtBlue := Lum;
end; {for}
SrcLine := pRGBArray(Integer(SrcLine) + SrcGap);
end; {for}
{$ifdef RangeCheck} {$R+} {$undef RangeCheck} {$endif}
end; {GreyScale}
Andrew
"Eric Carlson" <XXXX@XXXXX.COM>writes
Quote
Is there a simple way to do this please? Thanks. And to save bandwidth,
sincere thanks to all who answered any previous posts by me here.

 

Re:Converting TBitmap to greyscale

Eric Carlson writes:
Quote

Is there a simple way to do this please? Thanks. And to save bandwidth,
sincere thanks to all who answered any previous posts by me here.
The other poster gave you code to create a greyscale image.
However it will NOT necessarily 'save bandwidth'.
For the greyscale code given still utilises a 24bit bitmap.
To reduce the 'bandwidth' you will also need to reduce the color depth.
To get a resonable greyscal, an 8bit bitmap is used.
The following code will generate an 8bit greyscale image (BMPGrey) from
an original bitmap.
PRORCDURE GreyScale(BMPOrig: TBitmap);
CONST PaletteVersion = $0300;
VAR index,i,j: INTEGER;
RowB1,RowB2: pByteArray;
LogicalPalette: TMaxLogPalette;
BMPGrey: TBitmap;
begin
BMPOrig.PixelFormat:= pf24Bit;
Application.ProcessMessages;
BMPGrey:= TBitMap.Create;
BMPGrey.HandleType:= bmDIB;
BMPGrey.PixelFormat:= pf8Bit;
BMPGrey.Width:= BMPOrig.Width;
BMPGrey.Height:= BMPOrig.Height;
// 1. Create palette first.
LogicalPalette.palVersion:= PaletteVersion;
LogicalPalette.palNumEntries:= 256;
FOR i := 0 TO 255 DO
BEGIN
LogicalPalette.palPalEntry[i].peRed := i;
LogicalPalette.palPalEntry[i].peGreen := i;
LogicalPalette.palPalEntry[i].peBlue := i;
LogicalPalette.palPalEntry[i].peFlags := PC_RESERVED;
END;
BMPGrey.Palette:= CreatePalette(pLogPalette(@LogicalPalette)^);
// 2. Assign Scanline value;
FOR j:= 0 TO BMPGrey.Height-1 DO
BEGIN
RowB1:= BMPGrey.Scanline[j];
RowB2:= BMPOrig.Scanline[j];
FOR i:= 0 TO BMPGrey.Width-1 DO
BEGIN
index:= (RowB2[i*3]+RowB2[i*3+1]+RowB2[i*3+2]) DIV 3
// or Colour TV conversion is 29%R + 59%G + 11% B
// index:= Byte((RowB2[i*3]*77+ RowB2[i*3+1]*151+
RowB2[i*3+2]*28) shr 8);
RowB1[i]:= index;
END
END;
BMPOrig.Assign(BMPGrey);
BMPGrey.Free;
END;
--
Charles Hacker
Lecturer in Electronics and Computing
School of Engineering
Griffith University - Gold Coast
Australia
 

Re:Converting TBitmap to greyscale

"Charles Hacker" <XXXX@XXXXX.COM>writes
Quote
Eric Carlson writes:
>
>Is there a simple way to do this please? Thanks. And to save bandwidth,

The other poster gave you code to create a greyscale image.

However it will NOT necessarily 'save bandwidth'.
That was exactly what a project I am working on needed, big thanks.
I am wondering how you could vary things a little though. If you assume a
plain TBitmap takes up 100% or the byte count, and your greyscale code gets
it to say the min,1%, is there a way to adapt it to reduce the colors in
between to say return 50% of the bytecount?
 

Re:Converting TBitmap to greyscale

Anders Almquist writes:
Quote

That was exactly what a project I am working on needed, big thanks.
I am wondering how you could vary things a little though. If you assume a
plain TBitmap takes up 100% or the byte count, and your greyscale code gets
it to say the min,1%, is there a way to adapt it to reduce the colors in
between to say return 50% of the bytecount?
There are many ways.
EFG has already given a number of examples of this.
Take a look at:
www.efg2.com/Lab/Library/Delphi/Graphics/Color.htm
Specifically the Color Reduction, Color Quantization
--
Charles Hacker
Lecturer in Electronics and Computing
School of Engineering
Griffith University - Gold Coast
Australia