讀、寫像素

来源:百度文库 编辑:神马文学网 时间:2024/04/28 20:12:43

讀、寫圖素
 

應用程式維護packed DIB或DIB區塊的一個引人注目的優點是能夠直接操作DIB圖素位元。程式16-20所示的DIBHELP.C第二部分列出了提供此功能的函式。

 程式16-20  DIBHELP.C檔案的第二部分DIBHELP.C (第二部分)/*----------------------------------------------------------------------------DibPixelPtr:  Returns a pointer to the pixel at position (x, y)-----------------------------------------------------------------------------*/BYTE * DibPixelPtr (HDIB hdib, int x, int y){if (!DibIsAddressable (hdib))return NULL ;if (x < 0 || x >= DibWidth (hdib) || y < 0 || y >= DibHeight (hdib))return NULL ;return (((PDIBSTRUCT) hdib)->ppRow)[y] + (x * DibBitCount (hdib) >> 3) ;}/*---------------------------------------------------------------------------DibGetPixel:  Obtains a pixel value at (x, y)-----------------------------------------------------------------------------*/DWORD DibGetPixel (HDIB hdib, int x, int y){PBYTE pPixel ;if (!(pPixel = DibPixelPtr (hdib, x, y)))return 0 ;switch (DibBitCount (hdib)){case 1:  return 0x01 & (* pPixel >> (7 - (x & 7))) ;case4:  return 0x0F & (* pPixel >> (x & 1 ? 0 : 4)) ;case  8:  return * pPixel ;case 16: return * (WORD *) pPixel ;case 24: return 0x00FFFFFF & * (DWORD *) pPixel ;case 32: return * (DWORD *) pPixel ;}return 0 ;}/*-------------------------------------------------------------------------DibSetPixel:  Sets a pixel value at (x, y)---------------------------------------------------------------------------*/BOOL DibSetPixel (HDIB hdib, int x, int y, DWORD dwPixel){PBYTE pPixel ;if (!(pPixel = DibPixelPtr (hdib, x, y)))return FALSE ;switch (DibBitCount (hdib)){case  1:  * pPixel &= ~(1     << (7 - (x & 7))) ;* pPixel |= dwPixel   << (7 - (x & 7)) ;break ;case  4:  * pPixel &= 0x0F    << (x & 1 ? 4 : 0) ;* pPixel |= dwPixel   << (x & 1 ? 0 : 4) ;break ;case 8:  * pPixel = (BYTE) dwPixel ;break ;case 16:  * (WORD *) pPixel = (WORD) dwPixel ;break ;case 24:  * (RGBTRIPLE *) pPixel = * (RGBTRIPLE *) &dwPixel ;break ;case 32:  * (DWORD *) pPixel = dwPixel ;break ;default:return FALSE ;}return TRUE ;}/*---------------------------------------------------------------------------DibGetPixelColor:  Obtains the pixel color at (x, y)----------------------------------------------------------------------------*/BOOL DibGetPixelColor (HDIB hdib, int x, int y, RGBQUAD * prgb){DWORD      dwPixel ;int        iBitCount ;PDIBSTRUCT pdib = hdib ;// Get bit count; also use this as a validity checkif (0 == (iBitCount = DibBitCount (hdib)))return FALSE ;// Get the pixel valuedwPixel = DibGetPixel (hdib, x, y) ;// If the bit-count is 8 or less, index the color tableif (iBitCount <= 8)return DibGetColor (hdib, (int) dwPixel, prgb) ;// If the bit-count is 24, just use the pixelelse if (iBitCount == 24){* (RGBTRIPLE *) prgb = * (RGBTRIPLE *) & dwPixel ;prgb->rgbReserved = 0 ;}// If the bit-count is 32 and the biCompression field is BI_RGB,//   just use the pixelelse if (iBitCount == 32 &&pdib->ds.dsBmih.biCompression == BI_RGB){* prgb = * (RGBQUAD *) & dwPixel ;}// Otherwise, use the mask and shift values//   (for best performance, don't use DibMask and DibShift functions)else{prgb->rgbRed = (BYTE)(((pdib->ds.dsBitfields[0] & dwPixel)>> pdib->iRShift[0]) << pdib->iLShift[0]) ;prgb->rgbGreen=(BYTE((pdib->ds.dsBitfields[1] & dwPixel)>> pdib->iRShift[1]) << pdib->iLShift[1]) ;prgb->rgbBlue=(BYTE)(((pdib->ds.dsBitfields[2] & dwPixel)>> pdib->iRShift[2]) << pdib->iLShift[2]) ;}return TRUE ;}/*-----------------------------------------------------------------------------DibSetPixelColor:  Sets the pixel color at (x, y)-----------------------------------------------------------------------------*/BOOL DibSetPixelColor (HDIB hdib, int x, int y, RGBQUAD * prgb){DWORD      dwPixel ;int        iBitCount ;PDIBSTRUCT pdib = hdib ;// Don't do this function for DIBs with color tablesiBitCount = DibBitCount (hdib) ;if (iBitCount <= 8)return FALSE ;// The rest is just the opposite of DibGetPixelColorelse if (iBitCount == 24){* (RGBTRIPLE *) & dwPixel = * (RGBTRIPLE *) prgb ;dwPixel &= 0x00FFFFFF ;}else if (iBitCount == 32 &&pdib->ds.dsBmih.biCompression == BI_RGB){* (RGBQUAD *) & dwPixel = * prgb ;}else{dwPixel  = (((DWORD)prgb->rgbRed >> pdib->iLShift[0])<< pdib->iRShift[0]) ;dwPixel |= (((DWORD) prgb->rgbGreen >> pdib->iLShift[1])<< pdib->iRShift[1]) ;dwPixel |= (((DWORD) prgb->rgbBlue >> pdib->iLShift[2])<< pdib->iRShift[2]) ;}DibSetPixel (hdib, x, y, dwPixel) ;return TRUE ;}

這部分DIBHELP.C從DibPixelPtr函式開始,該函式獲得指向儲存(或部分儲存)有特殊圖素的位元組的指標。回想一下DIBSTRUCT結構的ppRow欄位,那是個指向DIB中由頂行開始排列的圖素行位址的指標。這樣,

((PDIBSTRUCT) hdib)->pprow)[0]

就是指向DIB頂行最左端圖素的指標,而

(((PDIBSTRUCT) hdib)->ppRow)[y] + (x * DibBitCount (hdib) >> 3)

是指向位於(x,y)的圖素的指標。注意,如果DIB中的圖素不可被定址(即如果已壓縮),或者如果函式的x和y參數是負數或相對位於DIB外面的區域,則函式將傳回NULL。此檢查降低了函式(和所有依賴於DibPixelPtr的函式)的執行速度,下面我將講述一些更快的常式。

檔案後面的DibGetPixel和DibSetPixel函式利用了DibPixelPtr。對於8位元、16位元和32位元DIB,這些函式只記錄指向合適資料尺寸的指標,並存取圖素值。對於1位元和4位元的DIB,則需要遮罩和移位角度。

DibGetColor函式按RGBQUAD結構獲得圖素顏色。對於1位元、4位元和8位元DIB,這包括使用圖素值來從DIB顏色表獲得顏色。對於16位元、24位元和32位元DIB,通常必須將圖素值遮罩和移位以得到RGB顏色。DibSetPixel函式則相反,它允許從RGBQUAD結構設定圖素值。該函式只為16位元、24位元和32位元DIB定義。