如何得到bitmap某一點畫素的RGB值
對一個BMP圖片進行分析,得到某一點的RGB值,設定某一點的RGB值.
CMyDIB::CMyDIB()
{
memset(&m_bfh, 0, sizeof(m_bfh));
memset(&m_bih, 0, sizeof(m_bih));
memset(&m_BitmapInfo, 0, sizeof(m_BitmapInfo));
m_nPaletteNum = 0;
m_pRGB = NULL;
m_nBytesPerLine = 0;
m_nDataSize = 0;
m_pDataBuf = NULL;
m_bRGB555 = TRUE;
}
CMyDIB::~CMyDIB()
{
if (m_pDataBuf)
{
delete m_pDataBuf;
m_pDataBuf = NULL;
}
if (m_pRGB)
{
delete m_pRGB;
m_pRGB = NULL;
}
}
BOOL CMyDIB::ReadFile(const char* pcszFileName)
{
FILE* pF = fopen(pcszFileName, "r");
if (NULL == pF)
return FALSE;
int nRead = 0;
if (fread(&m_bfh, 1, sizeof(m_bfh), pF) != sizeof(m_bfh))
goto EXIT_FILE;
if (m_bfh.bfType != 0x4d42)
goto EXIT_FILE;
if (fread(&m_bih, 1, sizeof(m_bih), pF) != sizeof(m_bih))
goto EXIT_FILE;
//得到調色盤的大小
switch(m_bih.biBitCount)
{
case 1:
m_nPaletteNum = 2;
break;
case 4:
m_nPaletteNum = 16;
break;
case 8:
m_nPaletteNum = 256;
break;
case 16:
m_nPaletteNum = 0;
if (m_bih.biCompression == BI_BITFIELDS)
{
fseek(pF, m_bfh.bfOffBits -sizeof(DWORD )*3,0);
DWORD rMask = 0;
fread(&rMask,sizeof(DWORD ),1,pF);
if(rMask==0xF800)
m_bRGB555 = FALSE;
}
break;
case 24:
case 32:
m_nPaletteNum = 0;
break;
}
m_BitmapInfo.bmiHeader = m_bih;
if (m_nPaletteNum > 0)
{
if (m_pRGB)
{
delete m_pRGB;
m_pRGB = NULL;
}
m_pRGB = new RGBQUAD[m_nPaletteNum];
nRead = fread((void*)m_pRGB, 1, m_nPaletteNum * sizeof(RGBQUAD), pF);
memcpy(m_BitmapInfo.bmiColors, m_pRGB, sizeof(RGBQUAD));
if (nRead != m_nPaletteNum * sizeof(RGBQUAD))
goto EXIT_FILE;
}
//位元組數 = 8 位數
m_nBytesPerLine = (m_bih.biWidth * m_bih.biBitCount + 31)/32*4;
//下面是資料區
m_nDataSize = m_bih.biHeight * m_nBytesPerLine;
if (m_pDataBuf)
{
delete m_pDataBuf;
m_pDataBuf = NULL;
}
m_pDataBuf = new BYTE[m_nDataSize + 1];
m_pDataBuf[m_nDataSize] = 0;
fseek(pF, m_bfh.bfOffBits, 0);
nRead = fread(m_pDataBuf, 1, m_nDataSize, pF);
if (nRead != m_nDataSize)
goto EXIT_FILE;
fclose(pF);
return TRUE;
EXIT_FILE:
fclose(pF);
pF = NULL;
return FALSE;
}
BOOL CMyDIB::WriteFile(const char* pcszFileName)
{
FILE* pF = fopen(pcszFileName, "w");
if (NULL == pF)
return FALSE;
fwrite(&m_bfh, 1, sizeof(m_bfh), pF);
fwrite(&m_bih, 1, sizeof(m_bih), pF);
if (m_nPaletteNum > 0)
{
fwrite((void*)m_pRGB, 1, m_nPaletteNum * sizeof(RGBQUAD), pF);
}
fwrite(m_pDataBuf, 1, m_nDataSize, pF);
fclose(pF);
return TRUE;
}
//檔案大小
int CMyDIB::GetFileSize()
{
return m_bfh.bfSize;
}
int CMyDIB::GetWidth()
{
return m_bih.biWidth;
}
int CMyDIB::GetHeight()
{
return m_bih.biHeight;
}
//畫素值(1,1)
//方向從左向右,從下向下
int CMyDIB::GetPixel(int x, int y)
{
int r = 0;
int g = 0;
int b = 0;
switch(m_bih.biBitCount)
{
case 1:
{
static BYTE abyBitMask[] = {0x80, 0x40, 0x20, 0x10, 0x80, 0x40, 0x20, 0x10};
if (m_bih.biHeight > 0)
{
//先找到資料區的索引
BYTE nIndex = m_pDataBuf[(m_bih.biHeight - y) * m_nBytesPerLine + (x + 8)/8 - 1];
int n = (x - 1) % 8; //因為是0開始
BYTE byBitSingle = (nIndex & abyBitMask[n]) >> (7 - n);
r = m_pRGB[byBitSingle].rgbRed;
g = m_pRGB[byBitSingle].rgbGreen;
b = m_pRGB[byBitSingle].rgbBlue;
}
else
{
int nIndex = m_pDataBuf[(y - 1) * m_nBytesPerLine + (x + 8)/8 - 1];
int n = (x - 1) % 8; //因為是0開始
BYTE byBitSingle = (nIndex & abyBitMask[n]) >> (7 - n);
r = m_pRGB[byBitSingle].rgbRed;
g = m_pRGB[byBitSingle].rgbGreen;
b = m_pRGB[byBitSingle].rgbBlue;
}
}
break;
case 4:
{
if (m_bih.biHeight > 0)
{
//先找到資料值的座標
BYTE nIndex = m_pDataBuf[(m_bih.biHeight - y) * m_nBytesPerLine + (x + 1)/2 - 1];
BYTE byBitHigh = (nIndex & 0xF0) >> 4;
BYTE byBitLow = (nIndex & 0x0F);
if (x%2) //奇數
{
r = m_pRGB[byBitHigh].rgbRed;
g = m_pRGB[byBitHigh].rgbGreen;
b = m_pRGB[byBitHigh].rgbBlue;
}
else
{
r = m_pRGB[byBitLow].rgbRed;
g = m_pRGB[byBitLow].rgbGreen;
b = m_pRGB[byBitLow].rgbBlue;
}
}
else
{
int nIndex = m_pDataBuf[(y - 1) * m_nBytesPerLine + (x + 1)/2 - 1];
BYTE byBitHigh = (nIndex & 0xF0) >> 4;
BYTE byBitLow = (nIndex & 0x0F);
if (x%2) //奇數
{
r = m_pRGB[byBitHigh].rgbRed;
g = m_pRGB[byBitHigh].rgbGreen;
b = m_pRGB[byBitHigh].rgbBlue;
}
else
{
r = m_pRGB[byBitLow].rgbRed;
g = m_pRGB[byBitLow].rgbGreen;
b = m_pRGB[byBitLow].rgbBlue;
}
}
}
break;
case 8:
{
if (m_bih.biHeight > 0)
{
int nIndex = m_pDataBuf[(m_bih.biHeight - y) * m_nBytesPerLine + x - 1];
r = m_pRGB[nIndex].rgbRed;
g = m_pRGB[nIndex].rgbGreen;
b = m_pRGB[nIndex].rgbBlue;
}
else
{
int nIndex = m_pDataBuf[(y - 1) * m_nBytesPerLine + x - 1];
r = m_pRGB[nIndex].rgbRed;
g = m_pRGB[nIndex].rgbGreen;
b = m_pRGB[nIndex].rgbBlue;
}
}
break;
case 16:
{
if (m_bih.biHeight > 0)
{
//圖片顛倒
if (m_bih.biCompression == BI_RGB)
{
//555模式
int nIndex = (m_bih.biHeight - y) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
b = bLow & 0x1f; //低5位
g = (bLow >> 5) + ((bHigh & 0x03) << 3);
r = (bHigh << 1) >> 3;
r = (r*0xFF)/0x1F;
g = (g*0xff)/0x1f;
b = (b*0xff)/0x1f;
}
else if (m_bih.biCompression == BI_BITFIELDS)
{
if (m_bRGB555)
{
int nIndex = (m_bih.biHeight - y) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
b = bLow & 0x1f; //低5位
g = (bLow >> 5) + ((bHigh & 0x03) << 3);
r = (bHigh << 1) >> 3;
r = (r*0xFF)/0x1F;
g = (g*0xff)/0x1f;
b = (b*0xff)/0x1f;
}
else
{
int nIndex = (m_bih.biHeight - y) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
b = bLow & 0x1f; //低5位
g = (bLow >> 5) + ((bHigh & 0x07) << 3);
r = bHigh >> 3;
r = (r*0xFF)/0x1F;
g = (g*0xff)/0x3f;
b = (b*0xff)/0x1f;
}
}
}
else
{
//正向的圖片
if (m_bih.biCompression == BI_RGB)
{
//555模式
int nIndex = (y - 1) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
b = bLow & 0x1f; //低5位
g = (bLow >> 5) + ((bHigh & 0x03) << 3);
r = (bHigh << 1) >> 3;
r = (r*0xFF)/0x1F;
g = (g*0xff)/0x1f;
b = (b*0xff)/0x1f;
}
else if (m_bih.biCompression == BI_BITFIELDS)
{
if (m_bRGB555)
{
int nIndex = (y - 1) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
b = bLow & 0x1f; //低5位
g = (bLow >> 5) + ((bHigh & 0x03) << 3);
r = (bHigh << 1) >> 3;
r = (r*0xFF)/0x1F;
g = (g*0xff)/0x1f;
b = (b*0xff)/0x1f;
}
else
{
int nIndex = (y - 1) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
b = bLow & 0x1f; //低5位
g = (bLow >> 5) + ((bHigh & 0x07) << 3);
r = bHigh >> 3;
r = (r*0xFF)/0x1F;
g = (g*0xff)/0x3f;
b = (b*0xff)/0x1f;
}
}
}
}
break;
case 24:
{
if (m_bih.biHeight > 0)
{
int nIndex = (m_bih.biHeight - y) * m_nBytesPerLine + (x-1)*3;
b = m_pDataBuf[nIndex];
g = m_pDataBuf[++nIndex];
r = m_pDataBuf[++nIndex];
}
else
{
int nIndex = (y - 1) * m_nBytesPerLine + (x - 1)*3;
b = m_pDataBuf[nIndex];
g = m_pDataBuf[nIndex++];
r = m_pDataBuf[nIndex++];
}
}
break;
case 32:
break;
}
return RGB(r, g, b);
}
int CMyDIB::SetPixel(int x, int y, DWORD dwRGB)
{
BYTE newr = GetRValue(dwRGB);
BYTE newg = GetGValue(dwRGB);
BYTE newb = GetBValue(dwRGB);
BYTE oldr = 0;
BYTE oldg = 0;
BYTE oldb = 0;
switch(m_bih.biBitCount)
{
case 1:
{
static BYTE abyBitMask[] = {0x80, 0x40, 0x20, 0x10, 0x80, 0x40, 0x20, 0x10};
if (m_bih.biHeight > 0)
{
//先找到資料區的索引
BYTE nIndex = m_pDataBuf[(m_bih.biHeight - y) * m_nBytesPerLine + (x + 8)/8 - 1];
int n = (x - 1) % 8; //因為是0開始
BYTE byBitSingle = (nIndex & abyBitMask[n]) >> (7 - n);
oldr = m_pRGB[byBitSingle].rgbRed;
oldg = m_pRGB[byBitSingle].rgbGreen;
oldb = m_pRGB[byBitSingle].rgbBlue;
m_pRGB[byBitSingle].rgbRed = newr;
m_pRGB[byBitSingle].rgbGreen = newg;
m_pRGB[byBitSingle].rgbBlue = newb;
}
else
{
int nIndex = m_pDataBuf[(y - 1) * m_nBytesPerLine + (x + 8)/8 - 1];
int n = (x - 1) % 8; //因為是0開始
BYTE byBitSingle = (nIndex & abyBitMask[n]) >> (7 - n);
oldr = m_pRGB[byBitSingle].rgbRed;
oldg = m_pRGB[byBitSingle].rgbGreen;
oldb = m_pRGB[byBitSingle].rgbBlue;
m_pRGB[byBitSingle].rgbRed = newr;
m_pRGB[byBitSingle].rgbGreen = newg;
m_pRGB[byBitSingle].rgbBlue = newb;
}
}
break;
case 4:
{
if (m_bih.biHeight > 0)
{
//先找到資料值的座標
BYTE nIndex = m_pDataBuf[(m_bih.biHeight - y) * m_nBytesPerLine + (x + 1)/2 - 1];
BYTE byBitHigh = (nIndex & 0xF0) >> 4;
BYTE byBitLow = (nIndex & 0x0F);
if (x%2) //奇數
{
oldr = m_pRGB[byBitHigh].rgbRed;
oldg = m_pRGB[byBitHigh].rgbGreen;
oldb = m_pRGB[byBitHigh].rgbBlue;
m_pRGB[byBitHigh].rgbRed = newr;
m_pRGB[byBitHigh].rgbGreen = newg;
m_pRGB[byBitHigh].rgbBlue = newb;
}
else
{
oldr = m_pRGB[byBitLow].rgbRed;
oldg = m_pRGB[byBitLow].rgbGreen;
oldb = m_pRGB[byBitLow].rgbBlue;
m_pRGB[byBitLow].rgbRed = newr;
m_pRGB[byBitLow].rgbGreen = newg;
m_pRGB[byBitLow].rgbBlue = newb;
}
}
else
{
int nIndex = m_pDataBuf[(y - 1) * m_nBytesPerLine + (x + 1)/2 - 1];
BYTE byBitHigh = (nIndex & 0xF0) >> 4;
BYTE byBitLow = (nIndex & 0x0F);
if (x%2) //奇數
{
oldr = m_pRGB[byBitHigh].rgbRed;
oldg = m_pRGB[byBitHigh].rgbGreen;
oldb = m_pRGB[byBitHigh].rgbBlue;
m_pRGB[byBitHigh].rgbRed = newr;
m_pRGB[byBitHigh].rgbGreen = newg;
m_pRGB[byBitHigh].rgbBlue = newb;
}
else
{
oldr = m_pRGB[byBitLow].rgbRed;
oldg = m_pRGB[byBitLow].rgbGreen;
oldb = m_pRGB[byBitLow].rgbBlue;
m_pRGB[byBitLow].rgbRed = newr;
m_pRGB[byBitLow].rgbGreen = newg;
m_pRGB[byBitLow].rgbBlue = newb;
}
}
}
break;
case 8:
{
if (m_bih.biHeight > 0)
{
int nIndex = m_pDataBuf[(m_bih.biHeight - y) * m_nBytesPerLine + x - 1];
oldr = m_pRGB[nIndex].rgbRed;
oldg = m_pRGB[nIndex].rgbGreen;
oldb = m_pRGB[nIndex].rgbBlue;
m_pRGB[nIndex].rgbRed = newr;
m_pRGB[nIndex].rgbGreen = newg;
m_pRGB[nIndex].rgbBlue = newb;
}
else
{
int nIndex = m_pDataBuf[(y - 1) * m_nBytesPerLine + x - 1];
oldr = m_pRGB[nIndex].rgbRed;
oldg = m_pRGB[nIndex].rgbGreen;
oldb = m_pRGB[nIndex].rgbBlue;
m_pRGB[nIndex].rgbRed = newr;
m_pRGB[nIndex].rgbGreen = newg;
m_pRGB[nIndex].rgbBlue = newb;
}
}
break;
case 16:
{
if (m_bih.biHeight > 0)
{
//圖片顛倒
if (m_bih.biCompression == BI_RGB)
{
//555模式
int nIndex = (m_bih.biHeight - y) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
oldb = bLow & 0x1f; //低5位
oldg = (bLow >> 5) + ((bHigh & 0x03) << 3);
oldr = (bHigh << 1) >> 3;
oldr = (oldb*0xFF)/0x1F;
oldg = (oldb*0xff)/0x1f;
oldb = (oldb*0xff)/0x1f;
newr = (newr * 0x1f)/0xff;
newg = (newg * 0x1f)/0xff;
newb = (newb * 0x1f)/0xff;
m_pDataBuf[nIndex ] = ((newg & 0x07) << 3) + newb;
m_pDataBuf[nIndex + 1] = (newr << 2) + (newg & 0x18);
}
else
{
if (m_bRGB555)
{
//555模式
int nIndex = (m_bih.biHeight - y) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
oldb = bLow & 0x1f; //低5位
oldg = (bLow >> 5) + ((bHigh & 0x03) << 3);
oldr = (bHigh << 1) >> 3;
oldr = (oldb*0xFF)/0x1F;
oldg = (oldb*0xff)/0x1f;
oldb = (oldb*0xff)/0x1f;
newr = (newr * 0x1f)/0xff;
newg = (newg * 0x1f)/0xff;
newb = (newb * 0x1f)/0xff;
m_pDataBuf[nIndex ] = ((newg & 0x07) << 3) + newb;
m_pDataBuf[nIndex + 1] = (newr << 2) + (newg & 0x18);
}
else
{
//565模式
int nIndex = (m_bih.biHeight - y) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
oldb = bLow & 0x1f; //低5位
oldg = (bLow >> 5) + ((bHigh & 0x07) << 3);
oldr = bHigh >> 3;
oldr = (oldb*0xFF)/0x1F;
oldg = (oldb*0xff)/0x3f;
oldb = (oldb*0xff)/0x1f;
newr = (newr * 0x1f)/0xff;
newg = (newg * 0x3f)/0xff;
newb = (newb * 0x1f)/0xff;
m_pDataBuf[nIndex ] = ((newg & 0x07) << 3) + newb;
m_pDataBuf[nIndex + 1] = (newr << 3) + (newg & 0x38);
}
}
}
else
{
//正向圖片
if (m_bih.biCompression == BI_RGB)
{
//555模式
int nIndex = (y- 1) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
oldb = bLow & 0x1f; //低5位
oldg = (bLow >> 5) + ((bHigh & 0x03) << 3);
oldr = (bHigh << 1) >> 3;
oldr = (oldb*0xFF)/0x1F;
oldg = (oldb*0xff)/0x1f;
oldb = (oldb*0xff)/0x1f;
newr = (newr * 0x1f)/0xff;
newg = (newg * 0x1f)/0xff;
newb = (newb * 0x1f)/0xff;
m_pDataBuf[nIndex ] = ((newg & 0x07) << 3) + newb;
m_pDataBuf[nIndex + 1] = (newr << 2) + (newg & 0x18);
}
else
{
if (m_bRGB555)
{
//555模式
int nIndex = (y - 1) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
oldb = bLow & 0x1f; //低5位
oldg = (bLow >> 5) + ((bHigh & 0x03) << 3);
oldr = (bHigh << 1) >> 3;
oldr = (oldb*0xFF)/0x1F;
oldg = (oldb*0xff)/0x1f;
oldb = (oldb*0xff)/0x1f;
newr = (newr * 0x1f)/0xff;
newg = (newg * 0x1f)/0xff;
newb = (newb * 0x1f)/0xff;
m_pDataBuf[nIndex ] = ((newg & 0x07) << 3) + newb;
m_pDataBuf[nIndex + 1] = (newr << 2) + (newg & 0x18);
}
else
{
//565模式
int nIndex = (y - 1) * m_nBytesPerLine + (x-1)*2;
BYTE bLow = m_pDataBuf[nIndex];
BYTE bHigh = m_pDataBuf[nIndex + 1];
oldb = bLow & 0x1f; //低5位
oldg = (bLow >> 5) + ((bHigh & 0x07) << 3);
oldr = bHigh >> 3;
oldr = (oldb*0xFF)/0x1F;
oldg = (oldb*0xff)/0x3f;
oldb = (oldb*0xff)/0x1f;
newr = (newr * 0x1f)/0xff;
newg = (newg * 0x3f)/0xff;
newb = (newb * 0x1f)/0xff;
m_pDataBuf[nIndex ] = ((newg & 0x07) << 3) + newb;
m_pDataBuf[nIndex + 1] = (newr << 3) + (newg & 0x38);
}
}
}
}
break;
case 24:
if (m_bih.biHeight > 0)
{
int nIndex = (m_bih.biHeight - y) * m_nBytesPerLine + (x-1)*3;
oldb = m_pDataBuf[nIndex];
oldg = m_pDataBuf[++nIndex];
oldr = m_pDataBuf[++nIndex];
m_pDataBuf[nIndex] = newb;
m_pDataBuf[++nIndex] = newg;
m_pDataBuf[++nIndex] = newr;
}
else
{
int nIndex = (y - 1) * m_nBytesPerLine + (x - 1)*3;
oldb = m_pDataBuf[nIndex];
oldg = m_pDataBuf[nIndex++];
oldr = m_pDataBuf[nIndex++];
m_pDataBuf[nIndex] = newb;
m_pDataBuf[nIndex++] = newg;
m_pDataBuf[nIndex++] = newr;
}
case 32:
break;
}
return RGB(oldr, oldg, oldb);
}
void CMyDIB::Draw(HDC hdc, int xDest, int yDest, int nDestWidth, int nDestHeight, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT iUsage, DWORD dwRop)
{
if (m_pRGB) //有顏色表
{
HPALETTE hPalette = CreateBitmapPalette();
HPALETTE hOldPalette = ::SelectPalette(hdc, hPalette, FALSE);
::RealizePalette(hdc);
StretchDIBits(hdc,
xDest,
yDest,
nDestWidth,
nDestHeight,
xSrc,
ySrc,
nSrcWidth,
nSrcHeight,
m_pDataBuf,
&m_BitmapInfo,
iUsage,
dwRop);
::SelectPalette(hdc, hOldPalette, FALSE);
::DeleteObject(hPalette);
}
else
{
StretchDIBits(hdc,
xDest,
yDest,
nDestWidth,
nDestHeight,
xSrc,
ySrc,
nSrcWidth,
nSrcHeight,
m_pDataBuf,
&m_BitmapInfo,
iUsage,
dwRop);
}
}
HPALETTE CMyDIB::CreateBitmapPalette()
{
if (m_pRGB == NULL)
return NULL;
struct
{
WORD palVersion;
WORD palNumEntries;
PALETTEENTRY palLPalEntry[256];
}palette = {0x300, 256};
LPRGBQUAD pRGBTable = m_pRGB;
for (UINT i = 0; i< m_nPaletteNum; ++i)
{
palette.palLPalEntry[i].peRed = pRGBTable[i].rgbRed;
palette.palLPalEntry[i].peGreen = pRGBTable[i].rgbGreen;
palette.palLPalEntry[i].peBlue = pRGBTable[i].rgbBlue;
palette.palLPalEntry[i].peFlags = 0;
}
HPALETTE hPalette = ::CreatePalette((LPLOGPALETTE)&palette);
return hPalette;
}