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格式图像的显示相关推荐
- RAW图像详解及使用Python读取raw格式图像并显示
一.RAW图像详解 1.1 什么是raw格式图像? RAW在英文中的解释是未处理的.自然状态的,这也就是RAW文件的真谛.RAW图像就是CMOS或者CCD图像感应器将捕捉到 的光源信号转化为数字信号的 ...
- 使用Python读取raw格式图像并显示
整理日期:2020-02-13 整理内容:使用Python读取raw格式图像并显示 代码如下: import cv2 #OpenCV包 import numpy as np# 首先确定原图片的基本信息 ...
- C语言用句柄显示bmp图片,VC编程之VC MFC界面上显示BMP图片
本文主要向大家介绍了VC编程之VC MFC界面上显示BMP图片,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助. 1.通过点击界面浏览按钮选择BMP图像文件. 点击浏览按钮打开文件对话框选择 ...
- BMP格式图像的显示
使用多文档编程 也可以使用单文档编程 建立一个DIB图像的显示类 ImageDib 成员变量: 4个指针: LPBYTE m_lpDib; //指向DIB的指针 LPBITMAPINFOHE ...
- UEFI显示BMP图片
两种方式 :一种为按像素点画图:另一种为将图片转换到GOP blt缓冲区中,允许用户调用blt将其显示出来. 画像素点方式极慢,可以看到一行一行的绘画过程:而使用缓冲区则会立刻显示出一张图片. 先了解 ...
- FFmpeg开发实战(五):bmp转换为jpeg格式图像
文章目录 1. bmp结构 2. bgr24转yuv420p 3. yuv420转jpeg 4. 下载 本文介绍了将bmp格式图像转换为jpeg格式图像的方法,附有详细的代码和图像示例. 1. bmp ...
- Linux应用开发-LCD显示BMP图片
1. 前言 BMP是一种与硬件设备无关的图像文件格式,是Windows环境中交换与图有关的数据的一种标准,在Windows环境中运行的图形图像软件都支持BMP图像格式.BMP格式的图片存放的就是原始的 ...
- 在6818开发板上显示bmp图片的基本步骤
我总结为以下四步: 1)打开液晶屏文件.打开bmp图片文件.完成液晶屏内存映射 2)读取bmp图片文件到临时数组temp,等待处理数组里面的数据. 3)处理数据.映射到液晶屏上,此处是bmp图片算法: ...
- VC MFC界面上显示BMP图片
1.通过点击界面浏览按钮选择BMP图像文件. 点击浏览按钮打开文件对话框选择BMP图像文件,得到文件所在的路径目录.关键代码如下: void ShowBMPDlg::OnButtonSelectiam ...
最新文章
- java8 lambda 表达式详解
- linux进程假死的原因_一次Spring Boot假死诊断
- SpringBoot+Vue+OpenOffice实现文档管理(文档上传、下载、在线预览)
- Linux上更新war包
- (转)详解JS位置、宽高属性之一:offset系列
- 3d激光雷达开发(voxel滤波)
- 20135226黄坤信息安全系统设计基础期末总结
- UR+RealSense手眼标定(eye-to-hand)
- Extjs之EditorGridPanel的beforeedit事件参数
- oracle语句执行过程
- 【通信电子电路】谐振功率放大电路multisim仿真
- html消除自带边距,CSS3中清除外边距、内边距margin,padding使用方法
- IPhone 日历提醒
- 微软系列的PPC开发工具【转贴】
- Python实现电话号码的数字组合
- 第九章 数据库事物管理
- Fluent报错调试系列(一)
- 2019年云计算产业市场前景研究,云计算技术发展趋势
- 南邮电装实习报告(最全)
- Hive报错:stage24 contains a task of very large size;the maximum recommended task size is 100kb
热门文章
- 2019秋季PAT甲级_C++题解
- day13 Java学习(常见对象正则表达式)
- request,logging,ConfigParser——接口框架
- 集体智慧编程学习笔记——第一讲
- [bzoj1614]: [Usaco2007 Jan]Telephone Lines架设电话线
- 对于c语言int类型和float,以及double类型表示范围的计算
- 在windows下使用putty登陆linux
- 【使用 DOM】为DOM元素设置样式
- 重磅!2021年考研国家线正式公布,部分学科分数线比去年更低!
- 域控制器服务器端和客户端设置