Board index » delphi » Convert a Bitmap into a Black-And-White-Bitmap

Convert a Bitmap into a Black-And-White-Bitmap

Hello!

I've got a bitmap. The black (or lets better say the
"black-looking") should be converted into clblack, everything
else in clwhite.

So how can I distinguish between different black/gray-tones?
Lets say I want all pixels darker then clsilver to be interpreted as
clblack.

Can I somehow like this:
If Bitmap.Canvas.Pixels[X, Y]<clsilver then Bitmap.Canvas.Pixels[X,
Y]:=clblack; ?

Thanks,
Daniel

 

Re:Convert a Bitmap into a Black-And-White-Bitmap


On Thu, 18 Jan 2001 11:16:19 +0100, "Daniel Mller" <stryk...@gmx.de>
wrote:

First note that you should use TBitmap.Scanline instead of
TBitmap.Canvas.Pixels. (If you're dealing with a Canvas
other than TBitmap.Canvas you may need to use Pixels,
and if you're only modifying a few pixels it may not matter,
but if you're doing real image processing then you will
find that Scanline is incredibly fast, especially if you
do it right, while Pixels is extremely slow by comparison.)

Quote
>Hello!

>I've got a bitmap. The black (or lets better say the
>"black-looking") should be converted into clblack, everything
>else in clwhite.

>So how can I distinguish between different black/gray-tones?
>Lets say I want all pixels darker then clsilver to be interpreted as
>clblack.

>Can I somehow like this:
>If Bitmap.Canvas.Pixels[X, Y]<clsilver then Bitmap.Canvas.Pixels[X,
>Y]:=clblack; ?

You could do something like

var cutoff: integer;
begin
 cutoff:= GetRValue(clSilver)
          + GetGValue(clSilver)
          + GetBValue(clSilver);

and then

if GetRValue(Pixels[..]) + ... < cutoff then ...

I don't have an example of doing exactly this via Scanline
handy but here's how you can convert a bitmap to
grayscale using Scanline - should illustrate the tricky
bits:

type
    PRgbTriple = ^TRGBTriple;
    TRGBTriple = packed record
      B: byte;
      G: byte;
      R: byte;
    end;

    P24BitRow = ^T24BitRow;
    T24BitRow = array[0..1000000] of TRGBTriple;

//TNewBitmap is a TBitmap descendant:

procedure TNewBitmap.FixBug;
//long story...
begin
   Canvas.Pixels[0,0]:= Canvas.Pixels[0,0];
end;

procedure TNewBitmap.GrayScale;
var row, col: integer;
    theRow: P24BitRow;
    TempTriple: TRGBTriple;
    gray: integer;
begin
  PixelFormat:= pf24Bit;
  FixBug;
 for row:= 0 to Height - 1 do
 begin
  theRow:= Scanline[row];
    for col:=0 to Width - 1 do
      begin
        TempTriple:= theRow[col];
        with TempTriple do
        begin
          gray:= (B + G + R) div 3;
        end;
        with theRow[col] do
          begin
            B:= gray;
            G:= gray;
            R:= gray;
          end;
      end;
 end;
end;

Something like that with something different inside
the loop will give you a 24-bit black&white bitmap;
then you could set Monochrome or PixelFormat
or something to get an actual black&white bitmap.
(It might be more efficient to create a new
1-bit bitmap and fill it in. Or maybe not - with
that 1-bit bitmap each byte in the array Scanline
gives you is going to be 8 pixels, and you'll
have some work to do getting the bits out of
the byte.)

Quote
>Thanks,
>Daniel

Re:Convert a Bitmap into a Black-And-White-Bitmap


For an example see: http://www.efg2.com/Lab/Graphics/Colors/ColorRange.htm.

"David C. Ullrich" <ullr...@math.okstate.edu> schreef in bericht
news:3a670a5b.5569900@nntp.sprynet.com...

Quote
> On Thu, 18 Jan 2001 11:16:19 +0100, "Daniel Mller" <stryk...@gmx.de>
> wrote:

> First note that you should use TBitmap.Scanline instead of
> TBitmap.Canvas.Pixels. (If you're dealing with a Canvas
> other than TBitmap.Canvas you may need to use Pixels,
> and if you're only modifying a few pixels it may not matter,
> but if you're doing real image processing then you will
> find that Scanline is incredibly fast, especially if you
> do it right, while Pixels is extremely slow by comparison.)

> >Hello!

> >I've got a bitmap. The black (or lets better say the
> >"black-looking") should be converted into clblack, everything
> >else in clwhite.

> >So how can I distinguish between different black/gray-tones?
> >Lets say I want all pixels darker then clsilver to be interpreted as
> >clblack.

> >Can I somehow like this:
> >If Bitmap.Canvas.Pixels[X, Y]<clsilver then Bitmap.Canvas.Pixels[X,
> >Y]:=clblack; ?

> You could do something like

> var cutoff: integer;
> begin
>  cutoff:= GetRValue(clSilver)
>           + GetGValue(clSilver)
>           + GetBValue(clSilver);

> and then

> if GetRValue(Pixels[..]) + ... < cutoff then ...

> I don't have an example of doing exactly this via Scanline
> handy but here's how you can convert a bitmap to
> grayscale using Scanline - should illustrate the tricky
> bits:

> type
>     PRgbTriple = ^TRGBTriple;
>     TRGBTriple = packed record
>       B: byte;
>       G: byte;
>       R: byte;
>     end;

>     P24BitRow = ^T24BitRow;
>     T24BitRow = array[0..1000000] of TRGBTriple;

> //TNewBitmap is a TBitmap descendant:

> procedure TNewBitmap.FixBug;
> //long story...
> begin
>    Canvas.Pixels[0,0]:= Canvas.Pixels[0,0];
> end;

> procedure TNewBitmap.GrayScale;
> var row, col: integer;
>     theRow: P24BitRow;
>     TempTriple: TRGBTriple;
>     gray: integer;
> begin
>   PixelFormat:= pf24Bit;
>   FixBug;
>  for row:= 0 to Height - 1 do
>  begin
>   theRow:= Scanline[row];
>     for col:=0 to Width - 1 do
>       begin
>         TempTriple:= theRow[col];
>         with TempTriple do
>         begin
>           gray:= (B + G + R) div 3;
>         end;
>         with theRow[col] do
>           begin
>             B:= gray;
>             G:= gray;
>             R:= gray;
>           end;
>       end;
>  end;
> end;

> Something like that with something different inside
> the loop will give you a 24-bit black&white bitmap;
> then you could set Monochrome or PixelFormat
> or something to get an actual black&white bitmap.
> (It might be more efficient to create a new
> 1-bit bitmap and fill it in. Or maybe not - with
> that 1-bit bitmap each byte in the array Scanline
> gives you is going to be 8 pixels, and you'll
> have some work to do getting the bits out of
> the byte.)

> >Thanks,
> >Daniel

Re:Convert a Bitmap into a Black-And-White-Bitmap


hi,

on Thu, 18 Jan 2001 11:16:19 +0100, "Daniel Mller <stryk...@gmx.de>"
wrote in <946fpl$n2...@riker.addcom.de>:

[..]

Quote
> I've got a bitmap. The black (or lets better say the
> "black-looking") should be converted into clblack, everything
> else in clwhite.

> So how can I distinguish between different black/gray-tones?
> Lets say I want all pixels darker then clsilver to be interpreted as
> clblack.

> Can I somehow like this:
> If Bitmap.Canvas.Pixels[X, Y]<clsilver then Bitmap.Canvas.Pixels[X,
> Y]:=clblack; ?

[..]

i would do it with scanline instead of pixels.
that is much faster.

you should find a solution to this here:
http://www.efg2.com/Lab/ImageProcessing/

cu chris
--
Visit http://yazno.tripod.com/ieinstver/ , home of IEInstVer.
IEInstVer - The "IE Availability, Version & Information" Component.

Re:Convert a Bitmap into a Black-And-White-Bitmap


"David C. Ullrich" <ullr...@math.okstate.edu> schrieb im Newsbeitrag
news:3a670a5b.5569900@nntp.sprynet.com...

Thanks for your coding, but I left my procedure with "pixels", because
scanline is not really faster, because I'm only reading a 32x32 small
bitmap.

Daniel

Re:Convert a Bitmap into a Black-And-White-Bitmap


"M.H. Avegaart" <avegaartNOS...@mccomm.nl> schrieb im Newsbeitrag
news:94743e$slv$1@porthos.nl.uu.net...
Quote
> For an example see:

http://www.efg2.com/Lab/Graphics/Colors/ColorRange.htm.

I will have a look at it.

Daniel

Other Threads