Solved

Changing the palette for a bitmap

Posted on 1998-10-03
10
352 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
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.

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
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



0
 
LVL 12

Accepted Solution

by:
rwilson032697 earned 40 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.
0
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 
LVL 5

Author Comment

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

Author Comment

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

Expert Comment

by:inter
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
  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
ID: 1341661
Thanks inter!
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1341662
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
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?
0
 
LVL 5

Expert Comment

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

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

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

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
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…

776 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