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

請問15、16位元圖片的問題

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


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

發送簡訊給我
#1 引用回覆 回覆 發表時間:2011-09-05 21:57:46 IP:114.26.xxx.xxx 訂閱
請問RGB565就是指16位元、RGB555就是15位元嗎?  所以RGB565給32位元 就是R左移3位元、G左移2位元、B左移3位元嗎?
我用這個網址的程式http://delphi.ktop.com.tw/board.php?cid=168&fid=921&tid=92869
把一張24bit的圖片轉成16位元圖片後存起來 再用下面程式打開
下面是我寫的 好像錯了
[code cpp]
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(OpenDialog1->Execute())
{
Image1->Picture->Bitmap->LoadFromFile(OpenDialog1->FileName);
}
Graphics::TBitmap *bmp32 = new Graphics::TBitmap();
Graphics::TBitmap *bmp565 = new Graphics::TBitmap();
Byte *ptr;
TRGBTriple *RGB_565Ary;
bmp565->LoadFromFile(OpenDialog1->FileName);
int w=bmp565->Width;
int h=bmp565->Height;
bmp565->PixelFormat=pf16bit;
bmp32->PixelFormat=pf32bit;
bmp32->Height=h;
bmp32->Width=w;
for (int y=0;y {
ptr =(Byte*)bmp32->ScanLine[y];
RGB_565Ary = (TRGBTriple *)bmp565->ScanLine[y];
for (int x=0;x {
ptr[4*x 2]=RGB_565Ary[x].rgbtRed<<3;//這樣是否為8bit
ptr[4*x 1]=RGB_565Ary[x].rgbtGreen<<2;//這樣是否為8bit
ptr[4*x]=RGB_565Ary[x].rgbtBlue<<3;//這樣是否為8bit
}
}
Image1->Picture->Bitmap->Assign(bmp32);
}
[/code]
結果圖片顯示出來如下圖

原圖如下:

請問是為什麼呢?

編輯記錄
encoref70036 重新編輯於 2011-09-06 00:00:29, 註解 無‧
senso
高階會員


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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2011-09-06 10:37:07 IP:61.219.xxx.xxx 訂閱
1.原圖如果已經是pf16bit就不用再轉了
bmp565->LoadFromFile(OpenDialog1->FileName);
bmp565->PixelFormat=pf16bit; //不知道為什麼設pf16bit 會亂掉,設pf15bit 可以正常轉過去
自己寫code或其他方式先弄成pf16bit 吧

一時記錯了~修掉~
編輯記錄
senso 重新編輯於 2011-09-05 20:40:48, 註解 無‧
senso 重新編輯於 2011-09-05 20:46:40, 註解 無‧
encoref70036
一般會員


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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2011-09-06 13:20:36 IP:114.26.xxx.xxx 訂閱
我因為找不到16位元的圖 所以先用版上那個24bit轉16bit先轉成16bit的圖片
然後我想把16位元給32位元 就是上面的程式 你說把pf16bit改成pf15bit嗎? 我改了 還是跟上圖一樣的影像

我之前也有寫24bit轉16bit 也是跟我這次的程式差不多 也是失敗了 也是出現很奇怪的影像 程式碼如下
[code cpp]
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(OpenDialog1->Execute())
{
Image1->Picture->Bitmap->LoadFromFile(OpenDialog1->FileName);
}
Graphics::TBitmap *bmp = new Graphics::TBitmap();
Graphics::TBitmap *bmp565 = new Graphics::TBitmap();
Byte *ptr;
int x,y;

bmp->LoadFromFile(OpenDialog1->FileName);//24位元圖片
int w=bmp->Width;
int h=bmp->Height;
bmp->PixelFormat=pf24bit;

bmp565->PixelFormat=pf16bit;
bmp565->Height=h;
bmp565->Width=w;

TRGBTriple *RGB_565Ary;
for (y=0;y {
ptr =(Byte*)bmp->ScanLine[y];
RGB_565Ary = (TRGBTriple *)bmp565->ScanLine[y];
for (x=0;x {
RGB_565Ary[x].rgbtRed = (Byte)ptr[3*x 2]>> 3; // 5-bit red
RGB_565Ary[x].rgbtGreen = (Byte)ptr[3*x 1]>> 2; // 6-bit green
RGB_565Ary[x].rgbtBlue = (Byte)ptr[3*x]>> 3; // 5-bit blue
}
}
Image1->Picture->Bitmap->Assign(bmp565);
[/code]


senso
高階會員


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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2011-09-06 14:16:39 IP:61.219.xxx.xxx 訂閱
沒仔細看0rz..
TRGBTriple是3Byte,不能拿來scanline非24bit的檔...
下面我寫24->16和16->24,15的就自己改吧


[code cpp]
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Graphics::TBitmap *bmp = new Graphics::TBitmap();
Graphics::TBitmap *bmp565 = new Graphics::TBitmap();
bmp->LoadFromFile("D:\\senso\\temp\\640x480x24b.bmp"); //24位元圖片
int w=bmp->Width;
int h=bmp->Height;
bmp565->PixelFormat=pf16bit;
bmp565->Height=h;
bmp565->Width=w;
Byte R,G,B;
for (int y=0;y {
Byte *ptr = (Byte*)bmp->ScanLine[y];
Word *ptr565 = (Word*)bmp565->ScanLine[y]; //unsigned short 0..65535
for (int x=0;x {
B = ptr[3*x ]>>3; //5-bit blue
G = ptr[3*x 1]>>2; //6-bit green
R = ptr[3*x 2]>>3; //5-bit red
ptr565[x] = R<<11 | G<<5 | B;
}
}
Image1->Picture->Bitmap->Assign(bmp565);
delete bmp,bmp565;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Graphics::TBitmap *bmp = new Graphics::TBitmap();
Graphics::TBitmap *bmp565 = new Graphics::TBitmap();
bmp565->Assign(Image1->Picture->Bitmap); //16位元圖片
int w=bmp565->Width;
int h=bmp565->Height;
bmp->PixelFormat=pf24bit;
bmp->Height=h;
bmp->Width=w;
Byte R,G,B;
for (int y=0;y {
Byte *ptr = (Byte*)bmp->ScanLine[y];
Word *ptr565 = (Word*)bmp565->ScanLine[y]; //unsigned short 0..65535
for (int x=0;x {
B = ((ptr565[x] & 0x001F) )<<3;
G = ((ptr565[x] & 0x07E0)>>5 )<<2;
R = ((ptr565[x] & 0xF800)>>11)<<3;
ptr[3*x ] = B;
ptr[3*x 1] = G;
ptr[3*x 2] = R;
}
}
Image1->Picture->Bitmap->Assign(bmp);
delete bmp,bmp565;
}

[/code]
encoref70036
一般會員


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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2011-09-06 14:21:09 IP:114.26.xxx.xxx 訂閱
謝謝您 我先看 先不結案 有問題再問您~ 感恩
encoref70036
一般會員


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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2011-09-06 15:00:44 IP:114.26.xxx.xxx 訂閱
請問 24->16 程式碼中
ptr565[x] = R<<11 | G<<5 | B; 這句是做什麼 做邏輯運算嗎?

還有 16->24 這邊是怎麼算的
B = ((ptr565[x] & 0x001F) )<<3;
G = ((ptr565[x] & 0x07E0)>>5 )<<2;
R = ((ptr565[x] & 0xF800)>>11)<<3;

編輯記錄
encoref70036 重新編輯於 2011-09-06 01:05:01, 註解 無‧
senso
高階會員


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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2011-09-06 15:09:18 IP:61.219.xxx.xxx 訂閱
http://en.wikipedia.org/wiki/High_color#16-bit_high_color

嗯..就左移 x 位(2進制)

B = 0000000000011111 = 0x001F
G = 0000011111100000 = 0x07E0
R = 1111100000000000 = 0xF800
16->24 要把壓縮的那幾位要回來才是正確的R<<3, G<<2, B<<3
編輯記錄
senso 重新編輯於 2011-09-06 01:12:58, 註解 無‧
encoref70036
一般會員


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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2011-09-06 15:17:33 IP:114.26.xxx.xxx 訂閱
哦 了解 謝謝您的教導
編輯記錄
encoref70036 重新編輯於 2011-09-06 01:20:27, 註解 無‧
encoref70036 重新編輯於 2011-09-06 01:20:56, 註解 無‧
encoref70036 重新編輯於 2011-09-06 01:23:25, 註解 無‧
系統時間:2017-10-24 13:55:10
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!