Board index » delphi » Displaying 24-bit color images in 256-color environment

Displaying 24-bit color images in 256-color environment

Here's a sample program showing the problem that Delphi has in
accurately displaying most 24-bit color images on a 256-color
(8-bit) display.  Any help or comments about this would be
appreciated.
______________________________________________________________

{
  This example paints three TPaintBoxes in three different ways to show
  the treatment of 24-bit .BMPs with only 256 colors available.

    1)  With Lead Tools DLL via Delphi  (works very well)
    2)  With Delphi trying to select and realize the bitmap's palette
(doesn't work)
    3)  With Delphi using StretchDIBits (doesn't work)

  Method 1 also stretches the image to fit into the PaintBox.  Methods 2
and
  3 do not.  All three methods work equally well with 16 bit (high) or
  32 bit (true) color.  Method 1 has failed consistently on cheap machines,
  or on more expensive ones -- like a Dell Dimension XPS P166.

  The file used in all three cases is 400 x 300 pixels x 8 bits Red, Green
  and blue = a  .BMP file with 360,054 bytes.

  I would like native Delphi to take care of the image retrieval and
  display -- Why is Lead Tools needed?  Will Delphi 3 handle display of
  24-bit .BMPs in 256-color environment any better?

Quote
}

unit ShowForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls,
   LeadUnit;  {Lead Tools DLL interface}

type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    PaintBox2: TPaintBox;
    PaintBox3: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure PaintBox1Paint(Sender: TObject);  {For Lead Tools}
    procedure PaintBox2Paint(Sender: TObject);  {For Delphi method 1}
    procedure PaintBox3Paint(Sender: TObject);  {For Delphi method 2}
  private
    { Private declarations }
    Bitmap1:  BitmapHandle;        {Lead Tools}
    Bitmap2:  TBitmap;                {Delphi}
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  {Lead Tools}
  L_InitBitmap(@Bitmap1, 0, 0, 0);
  L_LoadBitmap('C:\Projects\DCS\Bitmaps\Strawberries\strb_0.bmp', @Bitmap1,
0, ORDER_BGR);

  {Delphi}
  BitMap2 := TBitMap.Create;
  BitMap2.LoadFromFile('C:\Projects\DCS\Bitmaps\Strawberries\strb_0.bmp')
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  {Lead Tools}
  L_FreeBitmap(@Bitmap1);

  {Delphi}
  BitMap2.Free;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
  VAR
    OldPalette     :  HPalette;
    ImagePalette   :  HPalette;
    SourceRectangle:  TRect;
    TargetRectangle:  TRect;
begin
  {Lead Tools -- This works great}

  ImagePalette := L_CreatePaintPalette(PaintBox1.Canvas.Handle, @BitMap1);
  IF   ImagePalette > 0
  THEN BEGIN
    OldPalette := SelectPalette(PaintBox1.Canvas.Handle, ImagePalette,
FALSE);
    RealizePalette (PaintBox1.Canvas.Handle)
  END;

  SourceRectangle := Rect(0,0, Bitmap1.Width, Bitmap1.Height);
  TargetRectangle := Rect(0,0, Paintbox1.Width, Paintbox1.Height);

  L_PaintDC(PaintBox1.Canvas.Handle,
            @BitMap1,
            @SourceRectangle,
            @SourceRectangle,
            @TargetRectangle,
            @TargetRectangle,
            SRCCOPY);

  OldPalette := SelectPalette(PaintBox1.Canvas.Handle, OldPalette, FALSE);
  IF   OldPalette > 0
  THEN DeleteObject (OldPalette)

end;

procedure TForm1.PaintBox2Paint(Sender: TObject);
  VAR
    OldPalette     :  HPalette;
begin
  {
    Delphi:  Based on Ray Lischner's "Drawing a bitmap in a paint box" from
    pp. 436-437 of "Secrets of Delphi 2" (without error trapping from
book).
    This method shows an image but does not show the right colors.
  }

  OldPalette := SelectPalette(PaintBox2.Canvas.Handle, BitMap2.Palette,
FALSE);
  RealizePalette (PaintBox2.Canvas.Handle);

  PaintBox2.Canvas.Draw(0,0, Bitmap2);

  IF    OldPalette <> 0
  THEN  SelectPalette(PaintBox2.Canvas.Handle, OldPalette, FALSE);

end;

procedure TForm1.PaintBox3Paint(Sender: TObject);
  VAR
    Info     :  PBitmapInfo;
    InfoSize :  Integer;
    Image    :  Pointer;
    ImageSize:  Integer;
    Data     :  Pointer;
begin
  {
     Use Bitmap2 to draw on PaintBox3 using StetchDIBits -- similar to
     "Calling StretchDIBits to draw a bitmap on a memory bitmap," p. 437,
     "Secrets of Delphi 2" by Ray Lischner.  (Error trapping deleted to
     clarify what is going on.

     This puts the same image on the screen as before -- the colors are
     still very wrong from the original 24-bit color image in a 256 color
     environment.
  }

  WITH Bitmap2 DO
  BEGIN
    GetDIBSizes(Handle, InfoSize, ImageSize);
    Data := GlobalAllocPtr(GMem_Fixed, InfoSize + ImageSize);

    Info := Data;
    Image := PChar(Data) + InfoSize;

    GETDIB (Handle, Palette, Info^, Image^);

    WITH  Info^.bmiHeader DO
      StretchDIBits(PaintBox3.Canvas.Handle, 0, 0, Width, Height,
         0,0, biWidth, biHeight, Image, Info^, Dib_RGB_Colors, SRCCOPY);

    GlobalFreePtr (Data)
  END
end;

end.

_________________________________________________

Earl F. Glynn          EarlGl...@WorldNet.att.net
EFG Software              913/859-9557  Voice/Fax
   Scientific/Engineering/Medical Applications
             Overland Park, KS  USA

 

Re:Displaying 24-bit color images in 256-color environment


On 19 Mar 1997 07:23:45 GMT, "Earl F. Glynn"

Quote
<EarlGl...@worldnet.att.net> wrote:
>Here's a sample program showing the problem that Delphi has in
>accurately displaying most 24-bit color images on a 256-color
>(8-bit) display.  Any help or comments about this would be
>appreciated.

The problem is Windows, not Delphi. A 24-bit color bitmap potentially
has 16 million colors. The task of deciding which 236 of those colors
to display is not a trivial one. That Windows and video drivers handle
this situation at all is remarkable. To expect them to handle it well
is asking for a lot. That's why several companies sell commercial
solutions to this problem. If it were easy, would Lead and others be
able to charge so much for their libraries?

--
Ray Lischner, Tempest Software, Inc., Corvallis, Oregon, USA
Author of Secrets of Delphi 2 (http://www.tempest-sw.com/secrets/)

Re:Displaying 24-bit color images in 256-color environment


Hi,
Our graphics VCL's, DLL's and OCX's not only handle various formats like
gif and jpeg, but auto color mapping as well; including doing optimum
palettes for groups of images.
Trial VCL, DLL:
  ftp://www.pegasusimaging.com/pub/IMAGN/IMWT16D.EXE (16 bit)
  ftp://www.pegasusimaging.com/pub/IMAGN/IMWT32D.EXE (32 bit)
Registration $299.
Good luck,
jack

Quote
Ray Lischner wrote:

> On 19 Mar 1997 07:23:45 GMT, "Earl F. Glynn"
> <EarlGl...@worldnet.att.net> wrote:

> >Here's a sample program showing the problem that Delphi has in
> >accurately displaying most 24-bit color images on a 256-color
> >(8-bit) display.  Any help or comments about this would be
> >appreciated.

> The problem is Windows, not Delphi. A 24-bit color bitmap potentially
> has 16 million colors. The task of deciding which 236 of those colors
> to display is not a trivial one. That Windows and video drivers handle
> this situation at all is remarkable. To expect them to handle it well
> is asking for a lot. That's why several companies sell commercial
> solutions to this problem. If it were easy, would Lead and others be
> able to charge so much for their libraries?

> --
> Ray Lischner, Tempest Software, Inc., Corvallis, Oregon, USA
> Author of Secrets of Delphi 2 (http://www.tempest-sw.com/secrets/)

--
********************************************************************
Jack Berlin - 813-875-7575 x303  FAX 813-875-7705 jber...@jpg.com
http://www.jpg.com/ - Pegasus Imaging Corp - the BETTER JPEG people!
********************************************************************

Other Threads