全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1415
推到 Plurk!
推到 Facebook!

32bit給8bit

答題得分者是:senso
encoref70036
一般會員


發表:29
回覆:47
積分:15
註冊:2011-05-18

發送簡訊給我
#1 引用回覆 回覆 發表時間:2011-08-07 16:13:46 IP:111.253.xxx.xxx 訂閱
你好~
我想把32位元給8位元
我建了一個空白調色盤 然後給Bitmap8使用 然後把32位元的圖片給空白調色盤 結果是空白影像
// 定義調色盤結構
typedef struct {
TLogPalette lpal;//請問這個是做什麼用的?
TPaletteEntry dummy[256];//請問這個是做什麼用的?
} LogPal;
Graphics::TBitmap *Bitmap32 = new Graphics::TBitmap();
Bitmap32->Assign(Child->Image1->Picture);
Bitmap32->PixelFormat = pf32bit;//設定圖檔為32位元
// 建立灰階調色盤
LogPal Palette8;
Palette8.lpal.palVersion = 0x300;
Palette8.lpal.palNumEntries = 256;
for(int Index = 0; Index < 256; Index )
{
Palette8.lpal.palPalEntry[Index].peRed = (unsigned char)Index;
Palette8.lpal.palPalEntry[Index].peGreen = (unsigned char)Index;
Palette8.lpal.palPalEntry[Index].peBlue = (unsigned char)Index;
Palette8.lpal.palPalEntry[Index].peFlags = (unsigned char)0;
}
//建立完調色盤的內容,要產生給TBitmap的調色盤則用
Graphics::TBitmap *Bitmap8 = new Graphics::TBitmap();
Bitmap8->PixelFormat=pf8bit; // 指定為 8bpp 的BMP
Bitmap8->Width=Bitmap32->Width;// 你的影像寬度
Bitmap8->Height=Bitmap32->Height;// 你的影像高度
Bitmap8->Palette=CreatePalette(&Palette8.lpal);// 建立灰階調色盤
HPALETTE hPal=Bitmap8->ReleasePalette();
GetPaletteEntries(hPal, 0, 256, Palette8.lpal.palPalEntry);

for (int y = 0;y < Bitmap32->Height;y )
{
ptr32 = (Byte*)Bitmap32->ScanLine[y];
ptr8 = (Byte*)Bitmap8->ScanLine[y];
for (int x = 0;x < Bitmap32->Width;x )
{
Palette8.lpal.palPalEntry[ptr8[x]].peBlue = ptr32[4*x];
Palette8.lpal.palPalEntry[ptr8[x]].peGreen = ptr32[4*x 1];
Palette8.lpal.palPalEntry[ptr8[x]].peRed = ptr32[4*x 2];
Palette8.lpal.palPalEntry[ptr8[x]].peFlags = NULL;
}
}
SetPaletteEntries(hPal, 0, 256,Palette8.lpal.palPalEntry);
Bitmap8->Palette=hPal;
Child->Image1->Picture->Assign(Bitmap8);
請問哪裡寫錯呢?
senso
高階會員


發表:5
回覆:126
積分:226
註冊:2003-11-27

發送簡訊給我
#2 引用回覆 回覆 發表時間:2011-08-08 18:04:36 IP:61.219.xxx.xxx 訂閱
1.
typedef struct {
TLogPalette lpal;
TPaletteEntry dummy[256];
} LogPal;

Windows.hpp
typedef tagLOGPALETTE TLogPalette;

wingdi.h
typedef struct tagLOGPALETTE {
WORD palVersion;
WORD palNumEntries;
PALETTEENTRY palPalEntry[1];
} LOGPALETTE;
參考 http://webmail.vh.com.tw/Microsoft/1/16.htm
第一個欄位通常設為0x0300,表示相容Windows 3.0。
第二個欄位設定為調色盤表中的項目數。
LOGPALETTE結構中的第三個欄位是一個PALETTEENTRY結構的陣列,此結構也是一個調色盤項目。

老實說我以前沒摸過調色盤,看到這串文有興趣才開始找資料的
另我比較好奇的是為什麼dummy[256],實際上用到的好像也只有tagLOGPALETTE中的那一個和dummy中的前255個PALETTEENTRY
Windows.hpp也有定義一個TMaxLogPalette,palPalEntry陣列是256,也是可以拿來用...

2.
Bitmap8->Palette=CreatePalette(&Palette8.lpal);// 建立灰階調色盤
下面這兩行不用了,調色盤都建完了還Get做啥...
//HPALETTE hPal=Bitmap8->ReleasePalette();
//GetPaletteEntries(hPal, 0, 256, Palette8.lpal.palPalEntry);
當然下面也不用Set....
也是可以用PALETTEENTRY greyPal[256]配GetPaletteEntries和SetPaletteEntries啦
那就不用CreatePalette和LogPal

3.
你想對你剛建好的調色盤做什麼阿,要改的是bmp的data,你new完後都沒改data當然空白影像
直接把RGB轉灰階就是剛才建好的調色盤的index了
然後填入pf8bit的bmp的data
for (int y = 0;y < Bitmap32->Height;y )
{
ptr32 = (Byte*)Bitmap32->ScanLine[y];
ptr8 = (Byte*)Bitmap8->ScanLine[y];
for (int x = 0;x < Bitmap32->Width;x )
{ //這只是簡單的算法,你換成RGB轉灰階的公式也可以
ptr8[x] = (Byte)(((int)ptr1[j*4]
(int)ptr1[j*4 1]
(int)ptr1[j*4 2] )/3);
}
}


編輯記錄
senso 重新編輯於 2011-08-08 04:08:04, 註解 無‧
senso 重新編輯於 2011-08-08 04:11:32, 註解 無‧
encoref70036
一般會員


發表:29
回覆:47
積分:15
註冊:2011-05-18

發送簡訊給我
#3 引用回覆 回覆 發表時間:2011-08-08 23:43:05 IP:111.253.xxx.xxx 訂閱
可以把32位元彩色給8位元彩色嗎?
senso
高階會員


發表:5
回覆:126
積分:226
註冊:2003-11-27

發送簡訊給我
#4 引用回覆 回覆 發表時間:2011-08-09 09:04:45 IP:61.219.xxx.xxx 訂閱
直接Bitmap32->PixelFormat = pf8bit;就可以了
encoref70036
一般會員


發表:29
回覆:47
積分:15
註冊:2011-05-18

發送簡訊給我
#5 引用回覆 回覆 發表時間:2011-08-09 11:18:56 IP:111.253.xxx.xxx 訂閱
這樣顏色好像會失真 好像不能把32位元彩色給8位元彩色 感謝您
編輯記錄
encoref70036 重新編輯於 2011-08-08 21:27:47, 註解 無‧
senso
高階會員


發表:5
回覆:126
積分:226
註冊:2003-11-27

發送簡訊給我
#6 引用回覆 回覆 發表時間:2011-08-09 13:52:19 IP:61.219.xxx.xxx 訂閱
8bit一張圖就只有256種顏色....

這讓我想到之前有人問BMP存成JPG如何不失真
encoref70036
一般會員


發表:29
回覆:47
積分:15
註冊:2011-05-18

發送簡訊給我
#7 引用回覆 回覆 發表時間:2011-08-09 14:14:18 IP:111.253.xxx.xxx 訂閱
好像就是我問的 呵呵 不過bmp存gif可以用抖動、顏色轉換 把顏色變到256色以內
Subject: Re: 24Bit->256 Color GIF/PNG

var
GIF: TGIFImage;
Bitmap: TBitmap;
begin
GIF := TGIFImage.Create;
Bitmap := TBitmap.Create;
try
Bitmap.LoadFromFile('manycolors.bmp');
GIF.ColorReduction := rmQuantizeWindows;////顏色轉換
//GIFImage.ColorReduction := rmQuantize;
GIF.DitherMode := dmFloydSteinberg;//抖動模式
GIFImage.Compression := gcLZW;//壓縮
GIF.Assign(Bitmap);
GIF.SaveToFile('256colors.gif');
finally
Bitmap.Free;
GIF.Free;
end;
end;
編輯記錄
encoref70036 重新編輯於 2011-08-09 00:21:57, 註解 無‧
系統時間:2017-10-24 17:23:20
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!