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

請教如何產生TBitmap內容及由pixel內容產生bitmap格式檔案

答題得分者是:JerryKuo
danielj
初階會員


發表:65
回覆:135
積分:40
註冊:2003-06-11

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-08-19 09:39:25 IP:61.220.xxx.xxx 未訂閱
小弟想要嘗試將不含BITMAPINFOHEADER等標頭檔的bmp變成TBitmap屬性,但是不知道該如何做?另外,也想請高手們教一下怎麼把純各像素rgb圖檔內容變成標準的bitmap檔案呢? 先謝謝大家!
JerryKuo
版主


發表:42
回覆:571
積分:322
註冊:2003-03-10

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-08-19 15:46:51 IP:210.68.xxx.xxx 未訂閱
引言: 想要嘗試將不含BITMAPINFOHEADER等標頭檔的bmp變成TBitmap屬性,但是不知道該如何做?另外,也想請高手們教一下怎麼把純各像素rgb圖檔內容變成標準的bitmap檔案呢?
如果沒有誤會你的意思話,假設圖檔已被讀出存為二維陣列 接下來請參考這篇文章( 善用搜尋功能 ) href="http://delphi.ktop.com.tw/topic.php?TOPIC_ID=34301">http://delphi.ktop.com.tw/topic.php?TOPIC_ID=34301
danielj
初階會員


發表:65
回覆:135
積分:40
註冊:2003-06-11

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-08-19 16:37:51 IP:203.74.xxx.xxx 未訂閱
謝謝JerryKuo的回答! 您所提到那篇文章的方式的確是可以將rgb陣列存成bmp檔案,不過,小弟可能沒有說清楚我的重點是要快速繪圖。小弟其實是想做到將rgb陣列轉為TBitmap,以便直接在Canvas上畫出來,小弟試過,比用SetPixel快很多很多,如果用這篇文章的方式,還要一個個畫素複製,感覺好像不會太快,不過我會先試試看的… 也希望如果您還有其它的方法,請再提供出來,謝謝! (我在想是否可將陣列加上某些bitmap的header就可以變成TBitmap,小弟試著去看VCL的help,但是看不太懂structure的東西)
JerryKuo
版主


發表:42
回覆:571
積分:322
註冊:2003-03-10

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-08-19 17:09:28 IP:210.68.xxx.xxx 未訂閱
引言: 謝謝JerryKuo的回答! 您所提到那篇文章的方式的確是可以將rgb陣列存成bmp檔案,不過,小弟可能沒有說清楚我的重點是要快速繪圖。小弟其實是想做到將rgb陣列轉為TBitmap,以便直接在Canvas上畫出來,小弟試過,比用SetPixel快很多很多,如果用這篇文章的方式,還要一個個畫素複製,感覺好像不會太快,不過我會先試試看的… 也希望如果您還有其它的方法,請再提供出來,謝謝! (我在想是否可將陣列加上某些bitmap的header就可以變成TBitmap,小弟試著去看VCL的help,但是看不太懂structure的東西)
試試看用scanline,應該快很多
danielj
初階會員


發表:65
回覆:135
積分:40
註冊:2003-06-11

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-08-19 17:13:01 IP:203.74.xxx.xxx 未訂閱
雖然剛才說JerryKuo所引述那篇文章的方法可能會有點慢,但是也因為此篇文章,小弟才有了靈感,將陣列內容經由ScanLine以及CopyMemory的方法複製到動態新增的TBitmap中,如此繪圖還算是蠻快的,小弟的電腦測試結果,VGA顯示(含將陣列內容複製及顯示)約50~80ms間,比起單純用SetPixel的方式(約1秒)快至少百倍! 以下是小弟實驗程式碼,寫得不好,還請大家不吝指正…
 void __fastcall TForm1::Button1Click(TObject *Sender)
{
    OpenDialog1->Filter = ".bmp";
    if (OpenDialog1->Execute())
    {
        Graphics::TBitmap *bmp = new Graphics::TBitmap();
        bmp->LoadFromFile(OpenDialog1->FileName);
        LPBYTE newbmpa = (LPBYTE)GlobalAlloc(GMEM_FIXED,bmp->Width*bmp->Height*3);
        Image1->ClientHeight = bmp->Height ;
        Image1->ClientWidth  = bmp->Width  ;            //模擬出BGR陣列
        LPBYTE p=newbmpa;
        Byte *ptr;
        for (int y=0;yHeight;y  )
        {
            ptr = (Byte *)bmp->ScanLine[y];
            CopyMemory(p,ptr,bmp->Width*3);
            p =bmp->Width*3;
        }            double st,end;
        st =clock();
        Graphics::TBitmap *newbmp = new Graphics::TBitmap();
        newbmp= GetFormImage();
        newbmp->Height = bmp->Height ;
        newbmp->Width  = bmp->Width  ;
        p=newbmpa;
        newbmp->PixelFormat = pf24bit;
        for (int y=0;yHeight;y  )
        {
            ptr = (Byte *)newbmp->ScanLine[y];
            CopyMemory(ptr,p,newbmp->Width*3);
            p =newbmp->Width*3;
        }
        newbmp->SaveToFile("c:\\tmp\\newbmp.bmp");            Image1->Canvas->Draw(0,0,newbmp);
        end = clock();
        AnsiString mes = "Spend "   FloatToStr(end-st)   " ms";
        ShowMessage(mes);
        delete bmp;
        GlobalFree(newbmpa);
        delete newbmp;
    }
}
danielj
初階會員


發表:65
回覆:135
積分:40
註冊:2003-06-11

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-08-19 17:31:59 IP:203.74.xxx.xxx 未訂閱
抱歉!算錯了,應該只有快十多倍…    另外一種繪圖方式(純SetPixel)我的寫法如下:    
        
        ptr=newbmpa;
        for (int y=0;yHeight;y  )
        {
            for (int x=0;xWidth;x  )
            {
                ::SetPixel(Image1->Canvas->Handle,x,y,TColor(RGB(*(ptr 2),*(ptr 1),*(ptr))));
                ptr =3;
            }
        }
發表人 - danielj 於 2003/08/19 17:33:08 發表人 - danielj 於 2003/08/19 17:34:38
系統時間:2024-04-29 16:03:23
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!