Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17


Changing the palette for a bitmap

Posted on 1998-10-03
Medium Priority
Last Modified: 2013-12-03
procedure TCharSet.GetChar(DestCanvas :TCanvas; DestRect :TRect;
                           CharIndex :Integer;
                           ForeColor, BkgColor :TColor);
var i,j :integer;
    SourceRect :TRect;
  SourceRect := RectIndex[CharIndex];
  With DestCanvas do
    for i := 0 to 15 do
      for j := 0 to 15 do
        if CSBitmap.Canvas.Pixels[SourceRect.Left + i, SourceRect.Top + j] = 0
          then Pixels[DestRect.Left + i, DestRect.Top + j] := BkgColor
        else Pixels[DestRect.Left + i, DestRect.Top + j] := ForeColor;

CSBitmap is a bitmap containing the whole character set.  RectIndex contains any array of rectangles used to extract a specific character from the bitmap.  DestCanvas and DestRect specify where I want to copy the character (in my program it will be called from a StringGrid OnDrawCell event).

The bitmap in CSBitmap is stored using a palette of 16 colors, but only two colors are used (palette indexes of 0 and 1, I believe).

Anyway, this does exactly what I want to do, but too slow.  I believe that if I change the palette of the bitmap accordingly, I can just use CopyRect instead of manually checking each of the pixels.

For example, if I could do something like this:

CSBitmap.Palette[0] := BkgColor;
CSBitmap.Palette[1] := ForeColor;
CopyRect, etc.

I know that is not the syntax for changing the colors in the palette.  I looked at the help file for info on palettes and found it very confusing.  I do not want to create or select a palette, I just want to change the values in it.

How do I do this?

Also, is there an even faster way to do it than CopyRect?

Question by:scrapdog
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 2

Expert Comment

ID: 1341655
Hi, you can use BrushCopy method to do this lighting fast as follows:
With the same function header above, the following code replaces all the blacks with the white(or if we do not assign Brush.Color it replaces with the default brush color.

   SourceRect := RectIndex[CharIndex];
   // replace the clBlack with color you want to replace with
   DestCanvas.Brush.Style = bsSolid;
   DestCanvas.Brush.Color = clWhite;
   DestCanvas.BrushCopy(DestRect, CSBitmap, SourceRect, clBlack);

Author Comment

ID: 1341656
Thanks for the info inter.  I was never aware of the BrushCopy function.  (I posted a reply to this a few days ago but it must not registered)

Anyway, the problem with this is that it can only copy one color.  I need to change two colors;  one to the foreground color of the character, and one to the background of the character.

Brushcopy does work fine for one color.  But it can not be called twice in a row, because then the first color I changed would get unchanged.  Therefore, I believe the only way I can do this is to change the palette of the bitmap, and then use CopyRect.

If you have ever used the program Modplug Tracker, you will see string grids with custom characters.  These string grids seem to function quite well.  Maybe the whole way I am going about this is wrong.  I created a bitmap with 256 characters, and want to extract a certain portion to place in the OnDrawCell event.  

I would appreciate it if someone could show me how to change the colors of the palette in the bitmap.  The bitmap (i think it is a 16 or 256 color palette) uses only two colors-black and white.

Or if someone can show me how those custom charsets are done in programs like Modplug Tracker so quickly, and I can apply my own charset to it, I will award more points.

Thanks, Scrappy

LVL 12

Accepted Solution

rwilson032697 earned 80 total points
ID: 1341657
Use CreatePalette to create the palette you need, then assign the HPALETTE this gives back to you to the Palette property of CSBitmap.
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.


Author Comment

ID: 1341658
Can you give me a little more details on CreatePalette (i.e. the calling convention)?

I didn't see too many docs on it in my help file...

Author Comment

ID: 1341659
Also, is the type HPALETTE a pointer to a palette, an object, or is it the palette structure itself?  I am asking because I need to know if I need to deallocate/destroy the previous palette.

Expert Comment

ID: 1341660
Hi there, here is the routine for 16 bit, please study it and try to embed it to your program

  { My Logical Palette definition}
  TMyPalette = packed record
    palVersion: Word;
    palNumEntries: Word;
    palPalEntry: array[0..15] of TPaletteEntry; //we assume 16 color palette

procedure ChangePalette(CSBitmap : TBitmap;ForeColor, BkgColor :TColor);
  MyPal : TMyPalette;
  MyPal.palVersion := $0300;
  MyPal.palNumEntries := 16;
  // initialy black out all pallette
  FillChar(MyPal.palPalEntry, SizeOf(MyPal.palPalEntry), 0);
  // set palette 0 as bkground and 1 foreground -or vice versa?
  MyPal.palPalEntry[0] := ColorToRGB(BkgColor);
  MyPal.palPalEntry[0] := ColorToRGB(ForeColor);
  //Assign it
  CSBitmap.Palette := CreatePalette(MyPal);

regards, igor

Author Comment

ID: 1341661
Thanks inter!
LVL 12

Expert Comment

ID: 1341662

I assume you graded this 'C' because I didn't get back to you (until now) with responses to your CreatePalette and HPALETTE comments and inter gave you the details you needed.

You could have waited a day or two more (until I returned to work - its the weekend here - where my primary email is and replied) before dishing that out. Would you still grade C with the answers to those comments?



Author Comment

ID: 1341663
If you had posted what inter did, I would have given an A.  Maybe I could have waited a few days for you to answer, but how was I to know?

Expert Comment

ID: 1341664
Hey guys, these are simple issues, as all we agreed upon the thing is cooperation and getting things done... - sorry but I feel as if I wear a responsibility to deceive the grading-
Anyway, there is a mistake in code -sorry I could just catch one day later-
SECOND palette index would be 1.
love to work you all

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Suggested Courses

715 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