2010-05-18 113 views
1

我剛剛開始使用win32 GDI編程,並且很難找到很好的參考。我有一個簡單的應用程序,通過執行以下捕獲屏幕:win32 - 如何將畫面捕捉爲8位或16位位圖?

UINT32 x,y; 
x = GetSystemMetrics(SM_CXSCREEN); 
y = GetSystemMetrics(SM_CYSCREEN); 

HDC hdc = GetDC(NULL); 
HDC hdcScreen = CreateCompatibleDC(hdc); 

HBITMAP hbmp = CreateCompatibleBitmap(hdc, x, y); 

SelectObject(hdcScreen, hbmp); 

BitBlt(hdcScreen, 0, 0, x, y, hdc, 0, 0, SRCCOPY) 

ReleaseDC(NULL, hdc); 

我捕捉兼容的位圖,其中我的機器上是32位的。使用相同/相似的呼叫,我將如何捕捉8位的屏幕?那麼16位呢?

回答

2

使用CreateDIBSection來創建一個8bpp位圖,並BitBlt到那。


填充BITMAPINFO結構將是有趣的。您不能使用普通的BITMAPINFO結構,因爲它只爲單個調色板條目分配空間,而對於8bpp圖像,您將需要全部256個條目。

如果您想作弊一點,可以使用匿名聯合來爲其調色板聲明一個具有足夠空間的BITMAPINFO。

union 
{ 
    BITMAPINFO bmi; 
    struct { 
    BITMAPINFOHEADER bmih; 
    RGBQUAD extra[256]; 
    } dummy; 
}; 

bmi.bmiHeader.biSize = sizeof (bmi.bmiHeader); 
bmi.biBitCount = 8; 
// and so on. 

至於顏色表初始化值...我想不出一個簡單的方法來從GDI獲得一個默認8bpp的調色板時,其不8bpp的模式。我懷疑CreateHalftonePalette不會在非調色板設備上執行任何操作。

+0

那麼轉換爲16位呢?這會改變什麼? – Jon 2010-05-18 19:01:55

+1

使用> 8位,您不需要爲顏色表分配空間。因此,請忽略--- – 2010-05-18 19:08:14

+0

以下的所有內容,謝謝Chris,這非常有幫助! – Jon 2010-05-18 19:10:18

1

我敢肯定,你必須捕捉一個32位的位圖,然後將其自己轉換爲8位。 8位轉換通常會丟失相當數量的數據,並且有多少不同的算法可用於如何執行此操作。除非你真的有沒有的選擇,否則我會重新考慮這樣做。這是一個時間,因爲大多數人有很多理由弄亂8位位圖 - 他們一團糟。

8位位圖(至少是典型的位圖)有一個「調色板」,它指定位圖文件中要使用的每個(最多)256種顏色的24位值。通常情況下,您希望選取與原始位圖中最接近的顏色。發明了算法的批次這樣做。谷歌搜索類似於「減少顏色算法」應該會產生不少的點擊量,關於如何做這些點的變化有很多,從執行速度,內存使用情況等等來衡量。我甚至無法猜測哪種方法最適合爲了您的特定目的。

正如我剛纔所說的,我的第一個想法是花一些時間和精力來簡單地消除這個要求。從32位減少到24位甚至16位是非常容易的,並且保留了原始質量的批次。去8位是相當困難失去了很多的質量。