GPGAさんのコードを参考にして、パレット変更のプログラムを作成しました
以下ソースコードです
#include "DxLib.h"
#include <vector>
bool GetPalette(const char* pBuffer, std::vector<unsigned char>& palette);
bool SetPalette(char* pBuffer, const std::vector<unsigned char>& palette);
bool ConvertPalette(std::vector<unsigned char>& palette);
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
// 初期化
ChangeWindowMode(TRUE);
if (DxLib_Init() == -1) {
return 1;
}
SetDrawScreen(DX_SCREEN_BACK);
// 画像読み込み
std::vector<char> bmpbuf;
{
int fh = FileRead_open("test.bmp");
bmpbuf.resize(FileRead_size("test.bmp"));
FileRead_read(&bmpbuf[0], bmpbuf.size(), fh);
FileRead_close(fh);
}
// 画像初期化
int iHandle[2];
std::vector<unsigned char> palette;
GetPalette(&bmpbuf[0], palette);
iHandle[0] = CreateGraphFromMem(&bmpbuf[0], bmpbuf.size());
ConvertPalette(palette);
SetPalette(&bmpbuf[0], palette);
iHandle[1] = CreateGraphFromMem(&bmpbuf[0], bmpbuf.size());
// 表示
DrawGraph(0, 0, iHandle[0], 0);
DrawGraph(64, 0, iHandle[1], 0);
ScreenFlip();
WaitKey();
DxLib_End();
return 0;
}
/*!
* @brief BMPのパレットを取得
*
* @param pBuffer BMP画像の先頭のアドレスを指定します。
* @param palette 取得するパレットバッファを指定します。
*
* @return 正常に取得した場合は true を返します。
*/
bool GetPalette(const char* pBuffer, std::vector<unsigned char>& palette)
{
BITMAPFILEHEADER header;
BITMAPINFOHEADER info;
std::memcpy(&header, pBuffer, sizeof(header));
pBuffer += sizeof(header);
if (header.bfType != 0x4d42) {
// ビットマップではない
return false;
}
std::memcpy(&info, pBuffer, sizeof(info));
pBuffer += sizeof(info);
if (info.biBitCount != 8) {
// 256色ではない
return false;
}
palette.resize(256 * 3);
for (int i = 0; i < 256; ++i) {
const int bmpidx = i * sizeof(RGBQUAD);
const int palidx = i * 3;
palette[palidx + 0] = pBuffer[bmpidx + 2]; // 赤
palette[palidx + 1] = pBuffer[bmpidx + 1]; // 緑
palette[palidx + 2] = pBuffer[bmpidx + 0]; // 青
}
return true;
}
/*!
* @brief BMPのパレットを設定
*
* @param pBuffer BMP画像の先頭のアドレスを指定します。
* @param palette 設定するパレットバッファを指定します。
*
* @return 正常に設定した場合は true を返します。
*/
bool SetPalette(char* pBuffer, const std::vector<unsigned char>& palette)
{
BITMAPFILEHEADER header;
BITMAPINFOHEADER info;
std::memcpy(&header, pBuffer, sizeof(header));
pBuffer += sizeof(header);
if (header.bfType != 0x4d42) {
// ビットマップではない
return false;
}
std::memcpy(&info, pBuffer, sizeof(info));
pBuffer += sizeof(info);
if (info.biBitCount != 8) {
// 256色ではない
return false;
}
for (int i = 0; i < 256; ++i) {
const int bmpidx = i * sizeof(RGBQUAD);
const int palidx = i * 3;
pBuffer[bmpidx + 2] = palette[palidx + 0]; // 赤
pBuffer[bmpidx + 1] = palette[palidx + 1]; // 緑
pBuffer[bmpidx + 0] = palette[palidx + 2]; // 青
}
return true;
}
bool ConvertPalette(std::vector<unsigned char>& palette)
{
int ph;
char palBuf[1024];
ph = FileRead_open("palette1.txt");
while(FileRead_eof(ph) == 0)
{
FileRead_gets(palBuf, 1023, ph);
int original_R, original_G, original_B;
int convert_R, convert_G, convert_B;
sscanf_s(palBuf, "%d,%d,%d=%d,%d,%d;", &original_R, &original_G, &original_B, &convert_R, &convert_G, &convert_B);
for(int i=0; i<256; i++){
if(palette[i * 3 + 0]==original_R && palette[i * 3 + 1]==original_G && palette[i * 3 + 2]==original_B){
palette[i * 3 + 0]=convert_R;
palette[i * 3 + 1]=convert_G;
palette[i * 3 + 2]=convert_B;
}
}
}
return true;
}
そのうち、ConvertPalette関数を指定したファイル名により読み取るパレットファイルを変更できるように直したいです