(接上文)
接著是把 Image 儲存到陣列的部分
for(i=0;i<BitmapInfoHead.biHeight;++i)
{
ptr=(Byte*)Image1->Picture->Bitmap->ScanLine[i];
for(k=0,j=0;j<BitmapInfoHead.biWidth;++j)
{
Source[i][j][0] = ptr[k+2];
Source[i][j][1] = ptr[k+1];
Source[i][j][2] = ptr[k];
k+=3;
}
}
我在 compile 的時候,錯誤訊息都是在 Source[i][j][0] = ptr[k+2]; 這三行
內容是什麼我忘了
應該是因為型態的不同吧,我猜的
要研究一下 Byte 和 TBitmap 的內容是什麼才能知道
ptr 是 *Byte
Source 是 *Graphics::TBitmap
又或許是要另外宣告一個動態陣列來儲存而不是用 Source !?
我還沒試過
補充:
for loop 前面要先宣告 ptr,然後用動態配置 ptr 的長度
Byte *ptr;
ptr = new Byte [ Image1->Width*3 ];
寬度 x3是因為 Source[ ][ ][ ] 在這裡儲存的應該是 RGB
每次執行 ScanLine 函數都是讀取一整行的 RGB 值
至於 BitmapInfoHead.biHeight 和 BitmapInfoHead.biWidth
是經由宣告 BITMAPINFOHEADER 類別得到的
也就是如這一行程式碼
BITMAPINFOHEADER BitmapInfoHead;
不過這樣還要去指定 BitmapInfoHead 的長寬
有點多此一舉的感覺, 所以在講義裡應該只是示意用
在 for loop 中用 Panel1->Width & Panel1->>Height
或是 Source->Width & Source->>Height 應該也可以
因為都是一樣的數值, 也就是會變成如下
for(i=0;i<Source->>Height;++i)
{
ptr=(Byte*)Image1->Picture->Bitmap->ScanLine[i];
for(k=0,j=0;j<Source->Width;++j)
{
Source[i][j][0] = ptr[k+2];
Source[i][j][1] = ptr[k+1];
Source[i][j][2] = ptr[k];
k+=3;
}
}
不過這個部分我到現在還是沒 compile 過過
然後是第二個方法
先把單張擷取畫面儲存到 buffer 中再複製到剪貼簿裡,
然後再 assign 給 Image
在這裡要先引進剪貼簿的標頭檔
#include <vcl\Clipbrd.hpp>
才能使用 Clipboard( ) 函數
一樣用個 button 然後丟進程式碼, 內容很短, 只有這樣
capGrabFrameNoStop( hwndCapture );
capEditCopy( hwndCapture );
if( Clipboard()->HasFormat(CF_DIB) )
Image1->Picture->Bitmap->Assign( Clipboard() );
就可以在 Image 中顯示擷取的圖片了
有個好玩的地方是,
當這裡的程式結束後,
開個小畫家按 Ctrl+V 也會在小畫家中顯示剛剛擷取到的圖片
沒有留言:
張貼留言