mysql显示bmp图片_BMP格式图像的显示
使用多文檔編程 也可以使用單文檔編程
建立一個DIB圖像的顯示類 ImageDib
成員變量:
4個指針:
LPBYTE m_lpDib;??????//指向DIB的指針
LPBITMAPINFOHEADER m_lpBmpInfoHead; ?//圖像信息頭指針
LPRGBQUAD m_lpColorTable; ????//圖像顏色表指針
unsigned char * m_pImgData; ????//圖像數據指針
4個普通變量(存放圖像的參數):
int m_imgWidth;???????//圖像的寬,像素為單位
int m_imgHeight; ??????//圖像的高,像素為單位
int m_nBitCount;??????//每像素占的位數
int m_nColorTableLength; ?????//顏色表長度(多少個表項)
1個句柄:
HPALETTE m_hPalette;?????//邏輯調色板句柄
成員函數:
帶參數構造函數 ImageDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable,?unsigned char *pImgData);?????????? //帶參數的構造函數
View Code
ImageDib::ImageDib(CSize size, intnBitCount, LPRGBQUAD lpColorTable,
unsignedchar *pImgData)
{//如果沒有位圖數據傳入,我們認為是空的DIB,此時不分配DIB內存
if(pImgData==NULL){
m_lpDib=NULL;
m_lpColorTable=NULL;
m_pImgData=NULL; //圖像數據
m_lpBmpInfoHead=NULL; //圖像信息頭
m_hPalette =NULL;
}else{//如果有位圖數據傳入//可以通過調用ReplaceDib()來實現 代碼一樣的//ReplaceDib(size,nBitCount,lpColorTable,pImgData);//圖像的寬、高、每像素位數等成員變量賦值
m_imgWidth=size.cx;
m_imgHeight=size.cy;
m_nBitCount=nBitCount;//根據每像素位數,計算顏色表長度
m_nColorTableLength=ComputeColorTabalLength(nBitCount);//每行像素所占字節數,必須擴展成4的倍數
int lineByte=(m_imgWidth*nBitCount/8+3)/4*4;//位圖數據緩沖區的大小(圖像大小)
int imgBufSize=m_imgHeight*lineByte;//為m_lpDib一次性分配內存,生成DIB結構
m_lpDib=new BYTE [sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * m_nColorTableLength+imgBufSize];//填寫BITMAPINFOHEADER結構
m_lpBmpInfoHead =(LPBITMAPINFOHEADER) m_lpDib;
m_lpBmpInfoHead->biSize = sizeof(BITMAPINFOHEADER);
m_lpBmpInfoHead->biWidth =m_imgWidth;
m_lpBmpInfoHead->biHeight =m_imgHeight;
m_lpBmpInfoHead->biPlanes = 1;
m_lpBmpInfoHead->biBitCount =m_nBitCount;
m_lpBmpInfoHead->biCompression =BI_RGB;
m_lpBmpInfoHead->biSizeImage = 0;
m_lpBmpInfoHead->biXPelsPerMeter = 0;
m_lpBmpInfoHead->biYPelsPerMeter = 0;
m_lpBmpInfoHead->biClrUsed =m_nColorTableLength;
m_lpBmpInfoHead->biClrImportant =m_nColorTableLength;//調色板句柄初始化為空,有顏色表時,MakePalette()函數要生成新的調色板
m_hPalette =NULL;//如果有顏色表,則將顏色表拷貝進DIB的顏色表位置
if(m_nColorTableLength!=0){//m_lpColorTable指向DIB顏色表的起始位置
m_lpColorTable=(LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER));//顏色表拷貝
memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD) *m_nColorTableLength);//創建邏輯調色板
MakePalette();
}//m_pImgData指向DIB位圖數據起始位置
m_pImgData = (LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+
sizeof(RGBQUAD) *m_nColorTableLength;//拷貝圖像數據進DIB位圖數據區
memcpy(m_pImgData,pImgData,imgBufSize);
}
}
讀文件: ? BOOL Read(LPCTSTR lpszPathName); ??//DIB讀函數
View Code
BOOL ImageDib::Read(LPCTSTR lpszPathName)
{//讀模式打開圖像文件
CFile file;if (!file.Open(lpszPathName, CFile::modeRead |CFile::shareDenyWrite))returnFALSE;
BITMAPFILEHEADER bmfh;//讀取BITMAPFILEHEADER結構到變量bmfh中
int nCount=file.Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));//為m_lpDib分配空間,讀取DIB進內存
if(m_lpDib!=NULL) delete []m_lpDib;
m_lpDib=new BYTE[file.GetLength() -sizeof(BITMAPFILEHEADER)];
file.Read(m_lpDib, file.GetLength()-sizeof(BITMAPFILEHEADER));//m_lpBmpInfoHead位置為m_lpDib起始位置
m_lpBmpInfoHead =(LPBITMAPINFOHEADER)m_lpDib;//為成員變量賦值
m_imgWidth=m_lpBmpInfoHead->biWidth;
m_imgHeight=m_lpBmpInfoHead->biHeight;
m_nBitCount=m_lpBmpInfoHead->biBitCount;//計算顏色表長度
m_nColorTableLength= ComputeColorTabalLength(m_lpBmpInfoHead->biBitCount);//如果有顏色表,則創建邏輯調色板
m_hPalette =NULL;if(m_nColorTableLength!=0){m_lpColorTable=(LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER));
MakePalette();
}//m_pImgData指向DIB的位圖數據起始位置
m_pImgData = (LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) *m_nColorTableLength;returnTRUE;
}
寫文件: BOOL Write(LPCTSTR lpszPathName);?????? //DIB寫函數
View Code
BOOL ImageDib::Write(LPCTSTR lpszPathName)
{//寫模式打開文件
CFile file;if (!file.Open(lpszPathName, CFile::modeCreate |CFile::modeReadWrite|CFile::shareExclusive))returnFALSE;//填寫文件頭結構
BITMAPFILEHEADER bmfh;
bmfh.bfType= 0x4d42; //'BM'
bmfh.bfSize = 0;
bmfh.bfReserved1= bmfh.bfReserved2 = 0;
bmfh.bfOffBits= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) *m_nColorTableLength;try{//文件頭結構寫進文件
file.Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));//文件信息頭結構寫進文件
file.Write(m_lpBmpInfoHead, sizeof(BITMAPINFOHEADER));//如果有顏色表的話,顏色表寫進文件
if(m_nColorTableLength!=0)
file.Write(m_lpColorTable,sizeof(RGBQUAD) *m_nColorTableLength);//位圖數據寫進文件
int imgBufSize=(m_imgWidth*m_nBitCount/8+3)/4*4*m_imgHeight;
file.Write(m_pImgData, imgBufSize);
}catch(CException*pe) {
pe->Delete();
AfxMessageBox("write error");returnFALSE;
}//函數返回
returnTRUE;
}
計算顏色表長度:? int ComputeColorTabalLength(int nBitCount);?//計算顏色表的長度
View Code
int ImageDib::ComputeColorTabalLength(intnBitCount)
{intcolorTableLength;switch(nBitCount) {case 1:
colorTableLength= 2;break;case 4:
colorTableLength= 16;break;case 8:
colorTableLength= 256;break;case 16:case 24:case 32:
colorTableLength= 0;break;default:
ASSERT(FALSE);
}
ASSERT((colorTableLength>= 0) && (colorTableLength <= 256));returncolorTableLength;
}
創建邏輯調色板:? void MakePalette();??????//創建邏輯調色板
View Code
voidImageDib::MakePalette()
{//如果顏色表長度為0,則不創建邏輯調色板
if(m_nColorTableLength == 0)return;//刪除舊的邏輯調色板句柄
if(m_hPalette !=NULL) ::DeleteObject(m_hPalette);//申請空間,根據顏色表生成LOGPALETTE結構
LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) +m_nColorTableLength* sizeof(PALETTEENTRY)];
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries =m_nColorTableLength;
LPRGBQUAD m_lpDibQuad=(LPRGBQUAD) m_lpColorTable;for(int i = 0; i < m_nColorTableLength; i++) {
pLogPal->palPalEntry[i].peRed = m_lpDibQuad->rgbRed;
pLogPal->palPalEntry[i].peGreen = m_lpDibQuad->rgbGreen;
pLogPal->palPalEntry[i].peBlue = m_lpDibQuad->rgbBlue;
pLogPal->palPalEntry[i].peFlags = 0;
m_lpDibQuad++;
}//創建邏輯調色板
m_hPalette =::CreatePalette(pLogPal);//釋放空間
delete pLogPal;
}
讀取圖像維數: CSize GetDimensions();?????//讀取圖像維數
View Code
CSize ImageDib::GetDimensions()
{if(m_lpDib == NULL) return CSize(0, 0);returnCSize(m_imgWidth, m_imgHeight);
}
圖像繪制: ??? BOOL Draw(CDC* pDC, CPoint origin, CSize size); //圖像繪制
View Code
BOOL ImageDib::Draw(CDC*pDC, CPoint origin, CSize size)
{
HPALETTE hOldPal=NULL; //舊的調色板句柄
if(m_lpDib == NULL) return FALSE; //如果DIB為空,則返回0
if(m_hPalette != NULL) { //如果DIB有調色板//將調色板選進設備環境中
hOldPal=::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);
pDC->RealizePalette();
}
pDC->SetStretchBltMode(COLORONCOLOR); //設置位圖伸縮模式//將DIB在pDC所指向的設備上進行顯示
::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,0, 0, m_lpBmpInfoHead->biWidth, m_lpBmpInfoHead->biHeight,m_pImgData,
(LPBITMAPINFO) m_lpBmpInfoHead, DIB_RGB_COLORS, SRCCOPY);if(hOldPal!=NULL) //恢復舊的調色板
::SelectPalette(pDC->GetSafeHdc(), hOldPal, TRUE);returnTRUE;
}
用新的數據替代DIB:void ReplaceDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable,?unsigned char *pImgData);????????????? ?//用新的數據替換DIB
View Code
void ImageDib::ReplaceDib(CSize size, intnBitCount,
LPRGBQUAD lpColorTable,unsignedchar *pImgData)
{//釋放原DIB所占空間
Empty();//成員變量賦值
m_imgWidth=size.cx;
m_imgHeight=size.cy;
m_nBitCount=nBitCount;//計算顏色表的長度
m_nColorTableLength=ComputeColorTabalLength(nBitCount);//每行像素所占字節數,擴展成4的倍數
int lineByte=(m_imgWidth*nBitCount/8+3)/4*4;//位圖數據的大小
int imgBufSize=m_imgHeight*lineByte;//為m_lpDib重新分配空間,以存放新的DIB
m_lpDib=new BYTE [sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * m_nColorTableLength+imgBufSize];//填寫位圖信息頭BITMAPINFOHEADER結構
m_lpBmpInfoHead =(LPBITMAPINFOHEADER) m_lpDib;
m_lpBmpInfoHead->biSize = sizeof(BITMAPINFOHEADER);
m_lpBmpInfoHead->biWidth =m_imgWidth;
m_lpBmpInfoHead->biHeight =m_imgHeight;
m_lpBmpInfoHead->biPlanes = 1;
m_lpBmpInfoHead->biBitCount =m_nBitCount;
m_lpBmpInfoHead->biCompression =BI_RGB;
m_lpBmpInfoHead->biSizeImage = 0;
m_lpBmpInfoHead->biXPelsPerMeter = 0;
m_lpBmpInfoHead->biYPelsPerMeter = 0;
m_lpBmpInfoHead->biClrUsed =m_nColorTableLength;
m_lpBmpInfoHead->biClrImportant =m_nColorTableLength;//調色板置空
m_hPalette =NULL;//如果有顏色表,則將顏色表拷貝至新生成的DIB,并創建邏輯調色板
if(m_nColorTableLength!=0){
m_lpColorTable=(LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER));
memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD) *m_nColorTableLength);
MakePalette();
}//m_pImgData指向DIB的位圖數據起始位置
m_pImgData = (LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+
sizeof(RGBQUAD) *m_nColorTableLength;//將新位圖數據拷貝至新的DIB中
memcpy(m_pImgData,pImgData,imgBufSize);
}
清理空間函數: void Empty();???????????????????????? ?//清理空間
View Code
voidImageDib::Empty()
{//釋放DIB內存緩沖區
if(m_lpDib !=NULL) {
delete [] m_lpDib;
m_lpDib=NULL;
m_lpColorTable=NULL;
m_pImgData=NULL;
m_lpBmpInfoHead=NULL;
}//釋放邏輯調色板緩沖區
if(m_hPalette !=NULL){
::DeleteObject(m_hPalette);
m_hPalette=NULL;
}
}
默認構造函數:
View Code
ImageDib::ImageDib()
{
m_lpDib=NULL;//初始化m_lpDib為空。
m_lpColorTable=NULL; //顏色表指針為空
m_pImgData=NULL; //圖像數據指針為空
m_lpBmpInfoHead=NULL; //圖像信息頭指針為空
m_hPalette = NULL; //調色板為空
}
默認析構函數:
View Code
ImageDib::~ImageDib()
{//釋放m_lpDib所指向的內存緩沖區
if(m_lpDib !=NULL)
delete [] m_lpDib;//如果有調色板,釋放調色板緩沖區
if(m_hPalette !=NULL)
::DeleteObject(m_hPalette);
}
編寫好ImageDib類后,在doc文件類中添加一個ImageDib類的指針,在構造函數中new出來,在析構函數中delete,然后重寫OnOpenDocument()函數 在其中調用讀函數打開圖像 在View類的OnDraw()中調用ImageDib類的繪制函數 將圖像繪制在打開的新文件中
總結:編程的關鍵在于幾個指針的賦值,指向DIB的指針的分配空間,位圖信息頭等結構的賦值等等。
只要記住:
BMP文件=位圖頭文件+位圖信息頭+顏色表+數據塊 (等號后邊的內容按順序寫的)
DIB=位圖信息頭+顏色表+數據塊
位圖信息=位圖信息頭+顏色表
這些圖像文件的存儲組成及順序,萬事OK!
總結
以上是生活随笔為你收集整理的mysql显示bmp图片_BMP格式图像的显示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 表名不加单引号_当表名“ m
- 下一篇: 二层交换机可以划分vlan吗_二层交换机