Solved

Changing the palette for a bitmap

Posted on 1998-10-03
10
350 Views
Last Modified: 2013-12-03
procedure TCharSet.GetChar(DestCanvas :TCanvas; DestRect :TRect;
                           CharIndex :Integer;
                           ForeColor, BkgColor :TColor);
var i,j :integer;
    SourceRect :TRect;
begin
  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;
end;

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?


scrappy
0
Comment
Question by:scrapdog
  • 5
  • 3
  • 2
10 Comments
 
LVL 5

Expert Comment

by:inter
Comment Utility
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.

begin
   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);
end;
0
 
LVL 5

Author Comment

by:scrapdog
Comment Utility
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



0
 
LVL 12

Accepted Solution

by:
rwilson032697 earned 40 total points
Comment Utility
Use CreatePalette to create the palette you need, then assign the HPALETTE this gives back to you to the Palette property of CSBitmap.
0
 
LVL 5

Author Comment

by:scrapdog
Comment Utility
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...
0
 
LVL 5

Author Comment

by:scrapdog
Comment Utility
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.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 5

Expert Comment

by:inter
Comment Utility
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
  end;

procedure ChangePalette(CSBitmap : TBitmap;ForeColor, BkgColor :TColor);
var
  MyPal : TMyPalette;
begin
  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);
end;

regards, igor
0
 
LVL 5

Author Comment

by:scrapdog
Comment Utility
Thanks inter!
0
 
LVL 12

Expert Comment

by:rwilson032697
Comment Utility
Scrapdog...

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?

Raymond.

0
 
LVL 5

Author Comment

by:scrapdog
Comment Utility
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?
0
 
LVL 5

Expert Comment

by:inter
Comment Utility
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
igor
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
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…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
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…

743 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

17 Experts available now in Live!

Get 1:1 Help Now