📄 zgraphdib.cpp
字号:
#include "zGraphDib.h"
const RGBQUAD StandardColorTable16[] = {
{ 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x80, 0x00 },
{ 0x00, 0x80, 0x00, 0x00 },
{ 0x00, 0x80, 0x80, 0x00 },
{ 0x80, 0x00, 0x00, 0x00 },
{ 0x80, 0x00, 0x80, 0x00 },
{ 0x80, 0x80, 0x00, 0x00 },
{ 0xC0, 0xC0, 0xC0, 0x00 },
{ 0x80, 0x80, 0x80, 0x00 },
{ 0x00, 0x00, 0xFF, 0x00 },
{ 0x00, 0xFF, 0x00, 0x00 },
{ 0x00, 0xFF, 0xFF, 0x00 },
{ 0xFF, 0x00, 0x00, 0x00 },
{ 0xFF, 0x00, 0xFF, 0x00 },
{ 0xFF, 0xFF, 0x00, 0x00 },
{ 0xFF, 0xFF, 0xFF, 0x00 }
};
// R G B
const DWORD StandardMask555[] = { 0x007C00, 0x0003E0, 0x00001F };
const DWORD StandardMask565[] = { 0x00F800, 0x0007E0, 0x00001F };
const DWORD StandardMask888[] = { 0xFF0000, 0x00FF00, 0x0000FF };
const BYTE Shift1bpp[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
const BYTE Mask1bpp [] = { ~0x80, ~0x40, ~0x20, ~0x10, ~0x08, ~0x04, ~0x02, ~0x01 };
const BYTE Shift2bpp[] = { 6, 4, 2, 0 };
const BYTE Mask2bpp [] = { ~0xC0, ~0x30, ~0x0C, ~0x03 };
const BYTE Shift4bpp[] = { 4, 0 };
const BYTE Mask4bpp [] = { ~0xF0, ~0x0F };
zGraphDib::zGraphDib()
{
b_create = false;
m_pBMI = NULL;
m_pBits = NULL;
m_Flags = 0;
m_nWidth = 0;
m_nHeight = 0;
m_nPlanes = 1;
m_nBitCount = 1;
m_nColorDepth = 1;
m_nImageSize = 0;
m_nImageFormat = DIB_1BPP;
m_pRGBTRIPLE = NULL;
m_pRGBQUAD = NULL;
}
zGraphDib::~zGraphDib()
{
ReleaseDIB();
}
void zGraphDib::zGraphDibInfo::SetFormat(int width, int height, int bitcount, int compression)
{
//设置文件格式信息
memset(&m_dibinfo, 0, sizeof(m_dibinfo));
m_dibinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_dibinfo.bmiHeader.biWidth = width;
m_dibinfo.bmiHeader.biHeight = height;
m_dibinfo.bmiHeader.biPlanes = 1;
m_dibinfo.bmiHeader.biBitCount = bitcount;
m_dibinfo.bmiHeader.biCompression = compression;
//设置标准调色板
switch ( bitcount )
{
case 2: //2色
m_dibinfo.bmiColors[0].rgbRed = 0; // 黑
m_dibinfo.bmiColors[0].rgbGreen = 0;
m_dibinfo.bmiColors[0].rgbBlue = 0;
m_dibinfo.bmiColors[1].rgbRed = 0xFF; // 白
m_dibinfo.bmiColors[1].rgbGreen = 0xFF;
m_dibinfo.bmiColors[1].rgbBlue = 0xFF;
case 4: //设置标准16色调色板
memcpy(m_dibinfo.bmiColors, StandardColorTable16, 16 * sizeof(RGBQUAD));
break;
case 8: //设置标准256色调色板(windows:40 + 216)
{
for (int blue =0; blue <6; blue ++)
{
for (int green=0; green<6; green++)
{
for (int red =0; red <6; red ++)
{
int i = (blue * 6 + green) * 6 + red;
m_dibinfo.bmiColors[i].rgbRed = red * 55;
m_dibinfo.bmiColors[i].rgbGreen = green * 55;
m_dibinfo.bmiColors[i].rgbBlue = blue * 55;
}
}
}
break;
}
case 16: //设置16位色的rgb分量掩码
if ( compression==BI_BITFIELDS )
memcpy(m_dibinfo.bmiColors, StandardMask555, sizeof(StandardMask555));
break;
case 32: //设置32位色的rgb分量掩码
if ( compression==BI_BITFIELDS )
memcpy(m_dibinfo.bmiColors, StandardMask888, sizeof(StandardMask888));
break;
}
}
void zGraphDib::zGraphDibInfo::SetGrayScale(DWORD mask)
{
int nColor = 1 << m_dibinfo.bmiHeader.biBitCount;
for (int i=0; i<nColor; i++)
{
m_dibinfo.bmiColors[i].rgbRed = i & GetRValue(mask);
m_dibinfo.bmiColors[i].rgbGreen = i & GetGValue(mask);
m_dibinfo.bmiColors[i].rgbBlue = i & GetBValue(mask);
m_dibinfo.bmiColors[i].rgbReserved = 0;
}
}
BITMAPINFO *zGraphDib::zGraphDibInfo::GetBMI() const
{
return (BITMAPINFO *) & m_dibinfo;
}
BITMAPINFO *zGraphDib::zGraphDibInfo::CopyBMI() const
{
int nColor;
if ( m_dibinfo.bmiHeader.biCompression==BI_BITFIELDS )
{
nColor = 3;
}else if ( m_dibinfo.bmiHeader.biBitCount <= 8 )
{
nColor = 1 << m_dibinfo.bmiHeader.biBitCount;
}else
{
nColor = 0;
}
int nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColor;
BITMAPINFO * pBMI = (BITMAPINFO *) new BYTE[nSize];
if (pBMI)
{
memcpy(pBMI, & m_dibinfo, nSize);
}
return pBMI;
}
bool zGraphDib::AttachDIB(BITMAPINFO *pDIB, BYTE *pBits, int flags)
{
if ( IsBadReadPtr(pDIB, sizeof(BITMAPCOREHEADER)) )
{
return false;
}
ReleaseDIB();
m_pBMI = pDIB;
m_Flags = flags;
DWORD size = * (DWORD *) pDIB; //获取信息头尺寸
int compression;
//根据信息头大小判断版本
switch ( size )
{
case sizeof(BITMAPCOREHEADER): //OS2信息头
{
BITMAPCOREHEADER * pHeader = (BITMAPCOREHEADER *) pDIB;
m_nWidth = pHeader->bcWidth;
m_nHeight = pHeader->bcHeight;
m_nPlanes = pHeader->bcPlanes;
m_nBitCount = pHeader->bcBitCount;
m_nImageSize= 0;
compression = BI_RGB;
if ( m_nBitCount <= 8 )
{
m_nClrUsed = 1 << m_nBitCount;
m_nClrImpt = m_nClrUsed;
m_pRGBTRIPLE = (RGBTRIPLE *) ((BYTE *) m_pBMI + size);
m_pBits = (BYTE *) & m_pRGBTRIPLE[m_nClrUsed];
}
else
m_pBits = (BYTE *) m_pBMI + size;
break;
}
case sizeof(BITMAPINFOHEADER):
// case sizeof(BITMAPV4HEADER):
// case sizeof(BITMAPV5HEADER): //位图信息头,V4,V5版本统当作一般信息头处理.
{
BITMAPINFOHEADER * pHeader = & m_pBMI->bmiHeader;
m_nWidth = pHeader->biWidth;
m_nHeight = pHeader->biHeight;
m_nPlanes = pHeader->biPlanes;
m_nBitCount = pHeader->biBitCount;
m_nImageSize= pHeader->biSizeImage;
compression = pHeader->biCompression;
m_nClrUsed = pHeader->biClrUsed;
m_nClrImpt = pHeader->biClrImportant;
if ( m_nBitCount<=8 )
{
if ( m_nClrUsed==0 )
{
//全颜色表
m_nClrUsed = 1 << m_nBitCount;
}
}
if ( m_nClrUsed ) // 有一个颜色表
{
if ( m_nClrImpt==0 ) // 全都使用了
{
m_nClrImpt = m_nClrUsed;
}
if ( compression==BI_BITFIELDS )
{
m_pBitFields = (DWORD *) ((BYTE *)pDIB+size);
m_pRGBQUAD = (RGBQUAD *) ((BYTE *)pDIB+size + 3*sizeof(DWORD));
}else
{
m_pRGBQUAD = (RGBQUAD *) ((BYTE *)pDIB+size);
}
m_pBits = (BYTE *) & m_pRGBQUAD[m_nClrUsed];
}else
{
if ( compression==BI_BITFIELDS )
{
m_pBitFields = (DWORD *) ((BYTE *)pDIB+size);
m_pBits = (BYTE *) m_pBMI + size + 3 * sizeof(DWORD);
}else
{
m_pBits = (BYTE *) m_pBMI + size;
}
}
break;
}
default:
return false;
}
//像素指针
if ( pBits )
{
m_pBits = pBits; //如果直接指定了像素位
}
//颜色深度
m_nColorDepth = m_nPlanes * m_nBitCount;
//DWORD对齐后的大小
m_nBPS = (m_nWidth * m_nBitCount + 31) / 32 * 4;
//高度,行差,起始位置
if (m_nHeight < 0 ) //上下形式位图
{
m_nHeight = - m_nHeight; //高度
m_nDelta = m_nBPS; //行差
m_pOrigin = m_pBits; //从前向后 0...n
}else //下上形式位图
{
m_nDelta = - m_nBPS; //设定行差
m_pOrigin = m_pBits + (m_nHeight-1) * m_nBPS * m_nPlanes; //从后向前 n..0
}
//图像大小
if ( m_nImageSize==0 )
{
m_nImageSize = m_nBPS * m_nPlanes * m_nHeight;
}
//图像格式
switch ( m_nBitCount )
{
case 0:
// if ( compression==BI_JPEG )
// {
// m_nImageFormat = DIB_JPEG;
// }else if ( compression==BI_PNG )
// {
// m_nImageFormat = DIB_PNG;
// }else
{
return false;
}
break;
case 1:
m_nImageFormat = DIB_1BPP;
break;
case 2:
m_nImageFormat = DIB_2BPP;
break;
case 4:
// if ( compression==BI_RLE4 )
// {
// m_nImageFormat = DIB_4BPPRLE;
// }else
{
m_nImageFormat = DIB_4BPP;
}
break;
case 8:
// if ( compression==BI_RLE8 )
// {
// m_nImageFormat = DIB_8BPPRLE;
// }else
{
m_nImageFormat = DIB_8BPP;
}
break;
case 16:
if ( compression==BI_BITFIELDS )
{
m_nImageFormat = DIB_16RGBbitfields;
}else
{
m_nImageFormat = DIB_16RGB555;
}
break;
case 24:
m_nImageFormat = DIB_24RGB888;
break;
case 32:
if ( compression == BI_BITFIELDS )
{
m_nImageFormat = DIB_32RGBbitfields;
}else
{
m_nImageFormat = DIB_32RGB888;
}
break;
default:
return false;
}
if ( compression==BI_BITFIELDS )
{
DWORD red = m_pBitFields[0];
DWORD green = m_pBitFields[1];
DWORD blue = m_pBitFields[2];
if ( (blue==0x001F) && (green==0x03E0) && (red==0x7C00) )
{
m_nImageFormat = DIB_16RGB555;
}else if ( (blue==0x001F) && (green==0x07E0) && (red==0xF800) )
{
m_nImageFormat = DIB_16RGB565;
}else if ( (blue==0x00FF) && (green==0xFF00) && (red==0xFF0000) )
{
m_nImageFormat = DIB_32RGB888;
}
}
//建立标记
b_create = true;
return true;
}
bool zGraphDib::LoadBitmap(HMODULE hModule, LPCTSTR pBitmapName)
{
//从资源载入位图
HRSRC hRes = FindResource(hModule, pBitmapName, RT_BITMAP);
if ( hRes==NULL )
return false;
HGLOBAL hGlb = LoadResource(hModule, hRes);
if ( hGlb==NULL )
return false;
BITMAPINFO * pDIB = (BITMAPINFO *) LockResource(hGlb);
if ( pDIB==NULL )
return false;
return AttachDIB(pDIB, NULL, DIB_BMI_READONLY | DIB_BITS_READONLY);
}
bool zGraphDib::Create(int width, int height, int bitcount)
{
//建立指定位图
zGraphDibInfo dibinfo;
dibinfo.SetFormat(width, height, bitcount, BI_RGB);
int nBitsSize = ( width * bitcount + 31 ) /32 * 4 * height;
BYTE * pBits = new BYTE[nBitsSize];
if ( pBits )
{
return AttachDIB(dibinfo.CopyBMI(), pBits, 0);
}else
{
return FALSE;
}
}
void zGraphDib::ReleaseDIB()
{
b_create = false;
if (m_pBMI != NULL)
{
if ( m_Flags & DIB_BMI_NEEDFREE )
{
delete [] (BYTE *) m_pBMI;
m_Flags &= ~ DIB_BMI_NEEDFREE;
m_pBMI = NULL;
}
}
if (m_pBits != NULL)
{
if ( m_Flags & DIB_BITS_NEEDFREE )
{
delete [] m_pBits;
m_Flags &= ~ DIB_BITS_NEEDFREE;
m_pBits = NULL;
}
}
}
bool zGraphDib::IsCompressed() const
{
return (m_nImageFormat == DIB_4BPPRLE) || (m_nImageFormat == DIB_8BPPRLE) ||
(m_nImageFormat == DIB_JPEG) || (m_nImageFormat == DIB_PNG);
}
int zGraphDib::DrawDib(HDC hDC, int dx, int dy, int dw, int dh, int sx, int sy, int sw, int sh, DWORD rop)
{
if ( m_pBMI )
{
return ::StretchDIBits(hDC, dx, dy, dw, dh, sx, sy, sw, sh,m_pBits, m_pBMI, DIB_RGB_COLORS, rop);
}else
{
return GDI_ERROR;
}
}
int zGraphDib::GetDIBColorCount(const BITMAPINFOHEADER &bmih)
{
if ( bmih.biBitCount <= 8 )
{
if ( bmih.biClrUsed )
{
return bmih.biClrUsed;
}else
{
return 1 << bmih.biBitCount;
}
}else if ( bmih.biCompression==BI_BITFIELDS )
{
return 3 + bmih.biClrUsed;
}else
{
return bmih.biClrUsed;
}
}
int zGraphDib::GetDIBPixelSize(const BITMAPINFOHEADER &bmih)
{
if ( bmih.biSizeImage )
{
return bmih.biSizeImage;
}else
{
return ( bmih.biWidth * bmih.biBitCount + 31 ) / 32 * 4 * bmih.biPlanes * abs(bmih.biHeight);
}
}
DWORD zGraphDib::GetPixelIndex(int x, int y) const
{
if ( (x<0) || (x>=m_nWidth) )
return -1;
if ( (y<0) || (y>=m_nHeight) )
return -1;
BYTE * pPixel = m_pOrigin + y * m_nDelta;
switch ( m_nImageFormat )
{
case DIB_1BPP:
return ( pPixel[x/8] >> Shift1bpp[x%8] ) & 0x01;
case DIB_2BPP:
return ( pPixel[x/4] >> Shift2bpp[x%4] ) & 0x03;
case DIB_4BPP:
return ( pPixel[x/2] >> Shift4bpp[x%4] ) & 0x0F;
case DIB_8BPP:
return pPixel[x];
case DIB_16RGB555:
case DIB_16RGB565:
return ((WORD *)pPixel)[x];
case DIB_24RGB888:
pPixel += x * 3;
return (pPixel[0]) | (pPixel[1] << 8) | (pPixel[2] << 16);
case DIB_32RGB888:
case DIB_32RGBA8888:
return ((DWORD *)pPixel)[x];
}
return -1;
}
BOOL zGraphDib::SetPixelIndex(int x, int y, DWORD index)
{
if ( (x<0) || (x>=m_nWidth) )
return FALSE;
if ( (y<0) || (y>=m_nHeight) )
return FALSE;
BYTE * pPixel = m_pOrigin + y * m_nDelta;
switch ( m_nImageFormat )
{
case DIB_1BPP:
pPixel[x/8] = (BYTE) ( ( pPixel[x/8] & Mask1bpp[x%8] ) | ( (index & 1) << Shift1bpp[x%8] ) );
break;
case DIB_2BPP:
pPixel[x/4] = (BYTE) ( ( pPixel[x/4] & Mask2bpp[x%4] ) | ( (index & 3) << Shift2bpp[x%4] ) );
break;
case DIB_4BPP:
pPixel[x/2] = (BYTE) ( ( pPixel[x/2] & Mask4bpp[x%2] ) | ( (index & 15) << Shift4bpp[x%2] ) );
break;
case DIB_8BPP:
pPixel[x] = (BYTE) index;
break;
case DIB_16RGB555:
case DIB_16RGB565:
((WORD *)pPixel)[x] = (WORD) index;
break;
case DIB_24RGB888:
((RGBTRIPLE *)pPixel)[x] = * ((RGBTRIPLE *) & index);
break;
case DIB_32RGB888:
case DIB_32RGBA8888:
((DWORD *)pPixel)[x] = index;
break;
default:
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -