Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 881
  • Last Modified:

logical palette borland builder

I am trying to see the affect of changing the palette used by an TImage in borland builder.  My code is below.  Why does the image not change?

void display_logical_palette(void)
{

typedef struct{
   TLogPalette    lPal;
   TPaletteEntry  dummy[256];
} LogPal;

int i;
TCanvas  *canvas = frmMain->imgMain->Canvas;

// create a logical palette
     LogPal SysPal;
     SysPal.lPal.palVersion = 0x300;
     SysPal.lPal.palNumEntries = 256;
GetSystemPaletteEntries(canvas->Handle,0,256,SysPal.lPal.palPalEntry);

// specify what colors the palette contains
     for(i=20; i<240; i++)
     {
          SysPal.lPal.palPalEntry[i].peRed      = 255;
          SysPal.lPal.palPalEntry[i].peGreen    = i;
          SysPal.lPal.palPalEntry[i].peBlue     = 255-i;
     }

   if(NULL == (frmMain->fPalette = CreatePalette(&SysPal.lPal)))
   {
      MessageBox(NULL, "CreatePalette", "doh", MB_OK );
   }

   if(NULL == SelectPalette(canvas->Handle, frmMain->fPalette, NULL))
   {
      MessageBox(NULL, "SelectPalette", "doh", MB_OK );
   }

   int num;//number of entries in the logical palette mapped to the system palette

   num = RealizePalette(canvas->Handle);
   if(num == GDI_ERROR)
      MessageBox(NULL, "RealizePalette", "doh", MB_OK );
   else
   {
      char msg[16];
      sprintf(msg, "%d", num);
      MessageBox(NULL, msg, "doh", MB_OK );     // reports zero colors mapped
   }

   frmMain->imgMain->Refresh();

}
0
lirtua
Asked:
lirtua
  • 3
  • 2
1 Solution
 
AlexVirochovskyCommented:
Here is a code snippet that changes the palette:

LOGPALETTE* myPalette;
Graphics::TBitmap *myBitmap;

randomize();
myPalette = (LOGPALETTE*)new char[sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * 256];
myPalette->palVersion = 0x300;
myPalette->palNumEntries = 256;

for (int i = 0; i < 256; ++i) {
myPalette->palPalEntry[i].peRed =(short)i ;
myPalette->palPalEntry[i].peGreen = (short)random(50);
myPalette->palPalEntry[i].peBlue = (short)random(200);
myPalette->palPalEntry[i].peFlags = PC_RESERVED;
}

myBitmap = new Graphics::TBitmap;
try{
myBitmap->LoadFromFile("factory.bmp");
myBitmap->Palette = ::CreatePalette(myPalette);
Image1->Canvas->Draw(0,0,myBitmap);
}
catch(...){
Application->MessageBox("Could not load bitmap file",NULL,MB_OK);
delete myBitmap;
myBitmap = NULL;
};

delete myBitmap;
delete[] myPalette;
myBitmap = NULL;
myPalette = NULL;
}

0
 
lirtuaAuthor Commented:
The code you provided ran just fine in my project, but the bmp was not displayed with the changed palette.  I tried your code in two places, first, the form activate function, then in a button click function.  I suspected there may need to be a call to selectpalette but did not attempt this.  

Let me be a bit more clear about the intention of my original question.  I would like to obtain the palette that is currently used for a bit map that has been loaded.  Then I would like to change that palette.  And finally, I would like to display the bitmap in the new palette.

The code I provided captures the original palette, I believe, as I have printed the palette and it appears correct.  As to the changing and re-loading, it does not display, so something is wrong.

0
 
AlexVirochovskyCommented:
Next is code , based on other idea:
simple read file in memory, change palette and save
back. Work only for 256 colors(8 bits to pixel)
For 2/4 bits to pixel must make small changes.
for 24 bits on pixel no palette.

void __fastcall TForm1::Button1Click(TObject *Sender)
{                            //read file
   FILE *fIn = fopen("test001.bmp", "rb");
   int len = filelength(fIn->fd);
   char *buff = new char [len+1];
   fread(buff,len,1,fIn);
   fclose(fIn);
                            //make pakette
   BITMAPFILEHEADER bmfHdr;
   BITMAPINFOHEADER bi;         // bitmap header
   memcpy(&bmfHdr,buff, sizeof(bmfHdr));
   memcpy(&bi, buff+sizeof(bmfHdr), sizeof(bi));
   if (bi.biBitCount == 8)//256 colors in Palettee
     {  //make palette
        randomize();
        int palSize = sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 256;
        LOGPALETTE* myPalette = (LOGPALETTE*)new char[palSize];
        myPalette->palVersion = 0x300;
        myPalette->palNumEntries = 256;

        for (int i = 0; i < 256; ++i)
          {
            myPalette->palPalEntry[i].peRed =(short)i ;
            myPalette->palPalEntry[i].peGreen = (short)random(50);
            myPalette->palPalEntry[i].peBlue = (short)random(200);
            myPalette->palPalEntry[i].peFlags = PC_RESERVED;
          }
         //copy palette to bitmap
       memcpy(buff+ sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER),
               myPalette + sizeof(LOGPALETTE),sizeof(PALETTEENTRY) * 256);
       FILE *fOut = fopen("test002.bmp", "wb");
       fwrite(buff,len,1,fOut);
       fclose(fOut);
       delete [] myPalette;
     }
   delete [] buff;
}

Alex
0
 
AlexVirochovskyCommented:
I hope, my code helped you. Alex
0
 
lirtuaAuthor Commented:
Yes it was helpful - thanks Alex.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now