Solved

D3 Palettes - how do I get them to work?

Posted on 1997-07-06
22
391 Views
Last Modified: 2012-05-04
I keep struggling with this one thing over and over.

I am making a small 256-colour game, and I want to use a custom palette, but I don't understand how I am to get my Delphi 3.0 form to apply it. All my bitmaps use exactly the same palette, and when I load them in an image box, they are drawn correctly. But when I copy them from a hidden TImage to a visible empty TImage or TPaintBox, the colours turn out in the standard Windows 16 colours.

I have tried typing the following in the paint event of my form, but to no avail:

      SelectPalette(Handle, HiddenSource.Picture.Bitmap.Palette, False);
      RealizePalette(Handle);

How do I get my own custom palette to be used all over the form?

Thanks in advance for any answer.
0
Comment
Question by:JosefG
  • 8
  • 8
  • 5
  • +1
22 Comments
 
LVL 1

Expert Comment

by:bcrotaz
ID: 1338310
I know the feeling.  I've spent 2 years on this one.
0
 

Author Comment

by:JosefG
ID: 1338311
Adjusted points to 150
0
 
LVL 1

Expert Comment

by:bcrotaz
ID: 1338312
With the frequency this one is asked and not answered well, 1500 points might be better!!!
0
 

Author Comment

by:JosefG
ID: 1338313
Adjusted points to 215
0
 
LVL 1

Expert Comment

by:bcrotaz
ID: 1338314
he he he!
0
 
LVL 2

Expert Comment

by:icampbe1
ID: 1338315
When you say 'copied' to the visible Timage, what do you mean?  I believe that if you use the assign method then it should work.  If this is OK then I'll turn this into an answer, OK?

Ian C.

0
 

Author Comment

by:JosefG
ID: 1338316
When I say 'copy', I mean that I use the CopyRect function to copy a portion of the hidden TImage to the visible TImage or TPaintBox. The strange thing is that it worked all right in Delphi 2, as far as I can remember...
0
 
LVL 1

Expert Comment

by:bcrotaz
ID: 1338317
He is right.
If you use the Assign method, you copy the bitmap and palette.
However, with what you (and I) are going, with a CopyRect, the palette does not get copied.  You can copy the palette:
Image1.Picture.Bitmap.Palette:=SourceBmp.Palette;
BUT This references the palette.  So if you destroy SourceBmp, the palette in Image1 goes too.
0
 

Author Comment

by:JosefG
ID: 1338318
I noticed an error I made while entering the question. Instead of

SelectPalette(Handle, HiddenSource.Picture.Bitmap.Palette, False);
RealizePalette(Handle);

the example should read

SelectPalette(Canvas.Handle, HiddenSource.Picture.Bitmap.Palette, False);
RealizePalette(Canvas.Handle);

Still, the problem remains the same...
0
 
LVL 3

Accepted Solution

by:
mirek071497 earned 210 total points
ID: 1338319
Ohh. Why You can't use BitBlt and bitmaps ?

Here is example for You.

First Create Form, Place on them PaintBox and Button.
Then to OnClick (TButton) add following code.

procedure TForm1.Button1Click(Sender: TObject);
var
  Bmp     : HBitmap;
  NewDC   : HDC;
  MyPal   : HPalette;
  MyLPal  : PLogPalette;
begin
  { create palette (this is mono palette)}
  GetMem(MyLPal, (SizeOf(TLogPalette) + SizeOf(TPaletteEntry)*256));
  MyLPal^.PalVersion := $0300;
  MyLPal^.palNumEntries:=256;
  for i:=0 to 255 do
  begin
    MyLPal^.palPalEntry[i].peRed   := i;
    MyLPal^.palPalEntry[i].peGreen := i;
    MyLPal^.palPalEntry[i].peBlue  := i;
    MyLPal^.palPalEntry[i].peFlags := 0;
  end;
  MyPal := CreatePalette(MyLPal^);
  FreeMem(MyLPal, (SizeOf(TLogPalette) + SizeOf(TPaletteEntry)*256));
  { create DC for hidden writing }
  NewDC := CreateCompatibleDC( PaintBox2.Canvas.Handle );
  { select new palette }
  DeleteObject(SelectPalette( NewDC,MyPal,false));
  RealizePalette( NewDC );
  { create bitmap (work without too!) }
  Bmp := CreateCompatibleBitmap( PaintBox2.Canvas.Handle, XSize, YSize );

  { draw on Hidden DC for example from memory image of pixels }
{ This is My Example You must add here You'r Own
  SetDIBits( NewDC, Bmp, 0, YSize, @ByteBits, ByteInfo^, DIB_RGB_Colors );
  SelectObject( NewDC, Bmp ); }

  { copy from Hidden DC to PaintBox
  BitBlt( PaintBox2.Canvas.Handle, 0, 0, XSize, YSize, NewDC, 0, 0, SrcCopy );
  DeleteObject( Bmp );
  DeleteDC( NewDC );
end;


If You have any comments please submit comment or mail to me
mirek@izabell.itcomp.tpnet.pl

0
 

Author Comment

by:JosefG
ID: 1338320
By looking at your example, I assume you are creating a bitmap in memory, the same way you would in a C++ program. As Delphi is a "visual" development tool, I thought I could just place the source bitmap in a TImage component on my form, with the visible property set to False. I then wanted to copy a portion of this bitmap to a visible TPaintBox on my form.

You will see what I mean if you create a new project with a TImage, a TPaintBox and a TButton. Set the Visible property of the TImage to False (or true, the effect is in fact the same), and set its Picture to a 256 colour bitmap.

Then type the following in the eventhandler of your command button:
  BitBlt( PaintBox1.Canvas.Handle, 0, 0, 100, 100, Image1.Canvas.Handle, 0, 0, SrcCopy );

You should see the image appears, but only in 16 colours (not my 256).

Although your example code is rather detailed, I'm not sure I understood all the turns and twists in it, and what part corrects the palette problem.

As far as i understand, the problem lies in applying the palette in my 256-colour bitmap to the form. The form does not seem to want to apply any palette I give it, no matter how I do it, and what palette I use...
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 3

Expert Comment

by:mirek071497
ID: 1338321
1.I made project with TPicture and paint box, then I load in design time bitmap. When i execute BitBlt Bitmap was correctly copied.

2.Tell me more what you try doing. If You for example need changed You'r palette then You must rather use Memory bitmap not the bitmap in TPicture. TPicture is component for handlign any kind of graphics and there are more functions.

3.You must assign correct palette to source bitmap not to form.

4.If You need working on palette You must use WinApi.

5.If You describe short problem I write code and submit it here.
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1338322
I try comment my code

begin
  { here I create pallete description}
  GetMem(MyLPal, (SizeOf(TLogPalette) + SizeOf(TPaletteEntry)*256));
  MyLPal^.PalVersion := $0300; { this is always $0300}
  MyLPal^.palNumEntries:=256;  { how many items in palette define}
  for i:=0 to 255 do
  begin { here I set RGB values for every new pallete entry }
    MyLPal^.palPalEntry[i].peRed := i;
    MyLPal^.palPalEntry[i].peGreen := i;
    MyLPal^.palPalEntry[i].peBlue := i;
    MyLPal^.palPalEntry[i].peFlags := 0; { if you don't need palette animation set to 0 }
  end;
  MyPal := CreatePalette(MyLPal^); { here i create GDI object (HPalette) }
  { description is no loger needed because palette was created }
  FreeMem(MyLPal, (SizeOf(TLogPalette) + SizeOf(TPaletteEntry)*256));
  { create DC for hidden writing }
  NewDC := CreateCompatibleDC( PaintBox2.Canvas.Handle );
  { select new palette for NewDC and Delete previous }
  DeleteObject(SelectPalette( NewDC,MyPal,false));
  { after select You must realize palette because You don't know What colors Windows can display now }
  RealizePalette( NewDC );

  { here you cand draw on Hidden DC }

  { copy from Hidden DC to PaintBox }
  BitBlt( PaintBox2.Canvas.Handle, 0, 0, XSize, YSize, NewDC, 0, 0, SrcCopy );
  DeleteDC( NewDC ); { HDC must be deleted }
end;

0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1338323
Sorry, I must travell tomorrow and I return on Thursday.
Mail to me directly so I can answerr you'r questions or correct you'r code.
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1338324
hello. I just arrived. Do you need any help ?
0
 

Author Comment

by:JosefG
ID: 1338325
I'll get back to the subject in some days. Unfortunately I'm too busy right now to try out your suggestion. See you! (read you).
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1338326
Hi Josef!
Do you busy now ?
0
 

Author Comment

by:JosefG
ID: 1338327
Really, I'm not sure whether you have understood my problem. I'll try to clarify it: Why does a 256-colour bitmap only display in 16 colours when copied from one TImage to another?

I tried your code by typing:

      { here I create pallete description}
  GetMem(MyLPal, (SizeOf(TLogPalette) + SizeOf(TPaletteEntry)*256));
  MyLPal^.PalVersion := $0300; { this is always $0300}
  MyLPal^.palNumEntries:=256; { how many items in palette define}
  for i:=0 to 255 do
  begin { here I set RGB values for every new pallete entry }
    MyLPal^.palPalEntry[i].peRed := i;
    MyLPal^.palPalEntry[i].peGreen := i;
    MyLPal^.palPalEntry[i].peBlue := i;
    MyLPal^.palPalEntry[i].peFlags := 0; { if you don't need palette animation set to 0 }
  end;
  MyPal := CreatePalette(MyLPal^); { here i create GDI object (HPalette) }
  { description is no loger needed because palette was created }
  FreeMem(MyLPal, (SizeOf(TLogPalette) + SizeOf(TPaletteEntry)*256));
  { create DC for hidden writing }
  NewDC := CreateCompatibleDC( PaintBox2.Canvas.Handle );
  { select new palette for NewDC and Delete previous }
  DeleteObject(SelectPalette( NewDC,MyPal,false));
  { after select You must realize palette because You don't know What colors Windows can display now }
  RealizePalette( NewDC );

  { here you cand draw on Hidden DC }
  SelectObject(NewDC,Image1.Picture.Bitmap.Handle);

  { copy from Hidden DC to PaintBox }
  BitBlt( PaintBox2.Canvas.Handle, 0, 0, 100, 100, NewDC, 0, 0, SrcCopy );
  DeleteDC( NewDC ); { HDC must be deleted }

The result still appeared in 16 colours...

I'm not sure how I'm supposed to treat the newly created palette object, so maybe I'm doing something wrong here...
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1338328
Hi JosefG.
I think so you must have any other mistake because w made simple form with 2 TImage and 1 TButton. Then load 256color image from Windows directory and write proc for ButtonClick

procedure TForm1.Button1Click(Sender: TObject);
begin
  BitBlt( Image2.Canvas.Handle, 0, 0, Image2.Width, Image2.Height, Image1.Canvas.Handle, 0, 0, SrcCopy );
end;

I try with Image1 visible and invisible - All Work's Fine !!!

But when i edit this image with ImageEditor then palette was demaged, but by ImageEditor not by my program.

I can send to You my simple project with 256color bitmap as example or you must send to me you'r example wich not working ! I can't find any other solution.


0
 
LVL 1

Expert Comment

by:bcrotaz
ID: 1338329
I've seen this same problem in Delphi 1, but that was a long time ago...
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1338330
Hi all experts !

Josef send me example which work's on My delphi2 but don't work on his Delphi3. Mayby any of us meet with this problem.
I havn't now delphi3 so i can't test this.
0
 

Author Comment

by:JosefG
ID: 1338331
Mirek's solution is to realise the palette right before using the copyrect method (in the same procedure).
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now