BMP位图之代码实现
从16位开始,不存在调色板,顶多存在一个RGBQUAD的掩码。
16位位图,我没有拿到对应的素材,但是根据官方文档的描述和代码验证后,我总结为下:
当biCompression为BI_RGB时,此时是RGB555格式,不存在调色板。
当biCompression为BI_BITFIELDS时,16位位图时RGB565格式,对应的32位是带掩码的格式,两种都有一个RGBQUAD的数据存在于调色板。
24位位图,只有BI_RGB存储方式。
代码实现如下
enum { bitmap_undefined, bitmap_unknown, bitmap1, bitmap4, bitmap4_RLE4,
bitmap8, bitmap8_RLE8, bitmap16_RGB555, bitmap16_RGB565, bitmap24, bitmap32, bitmap32_mask};//所有bmp类型
class Bitmap {
public:
Bitmap();
virtual ~Bitmap();
HBITMAP BitCreate(HDC hDC, LPTSTR szFilename);//从文件载入
HBITMAP BitCreate(HDC hDC, HINSTANCE hInstance, UINT rscID);//从资源载入
PBITMAPFILEHEADER GetBitFileheader(PBYTE pBitmap = NULL);//位图头
PBITMAPINFOHEADER GetBitInfoheader(PBYTE pBitmap = NULL);//位图INFO结构
LPRGBQUAD GetBitPalette(PBYTE pBitmap = NULL);//位图画板,不存在返回NULL
PVOID GetBitData(PBYTE pBitmap = NULL);//位图数据
void BitDraw(HDC hDC, int x, int y, HBITMAP hBitmap);//将位图画到自己的窗口
protected:
void BitErrorshow(DWORD errorID);//错误提示
void BitTypedefined();//类型定义
void BitFree();//资源释放
HBITMAP BitLoad(HDC hDC, PBYTE pBitmap = NULL);//载入的数据,转换为HBITMAP句柄,方便操作
private:
HGLOBAL m_hGlablebitmap;
HANDLE m_hFilemapping;
PBYTE m_pBitmap;
int m_iWidth, m_iHeight, m_iFilesize;
int m_iType;
};
对应的实现代码
Bitmap::Bitmap() {
m_hFilemapping = m_hGlablebitmap = NULL;
m_pBitmap = NULL;
m_iFilesize = m_iWidth = m_iHeight = 0;
m_iType = bitmap_undefined;
}
Bitmap::~Bitmap() {
BitFree();
}
void Bitmap::BitTypedefined() {
PBITMAPINFOHEADER bInfoheader;
bInfoheader = GetBitInfoheader();
m_iWidth = bInfoheader->biWidth;
m_iHeight = bInfoheader->biHeight;
WORD bitCount = bInfoheader->biBitCount;
DWORD bitCompression = bInfoheader->biCompression;
if (bitCompression == BI_RGB) {
switch (bitCount) {
case 1:
m_iType = bitmap1; break;
case 4:
m_iType = bitmap4; break;
case 8:
m_iType = bitmap8; break;
case 16:
m_iType = bitmap16_RGB555; break;
case 24:
m_iType = bitmap24; break;
case 32:
m_iType = bitmap32; break;
default:
m_iType = bitmap_unknown;
}
}
else if (bitCompression == BI_BITFIELDS) {
switch (bitCount) {
case 16:
m_iType = bitmap16_RGB565; break;
case 32:
m_iType = bitmap32_mask; break;
default:
m_iType = bitmap_unknown;
}
}
else if (bitCompression == BI_RLE4)
m_iType = bitmap4_RLE4;
else if (bitCompression == BI_RLE8)
m_iType = bitmap8_RLE8;
else
m_iType = bitmap_unknown;
}
HBITMAP Bitmap::BitLoad(HDC hDC, PBYTE pBitmap) {
PBITMAPINFOHEADER pBitmapinfo = GetBitInfoheader(pBitmap);
PBYTE pBitmapdata = (PBYTE)GetBitData(pBitmap), pDIBData = NULL;
HBITMAP hBitmap = CreateDIBSection(hDC, (PBITMAPINFO)pBitmapinfo, DIB_RGB_COLORS, (void **)&pDIBData,
NULL, 0);
DWORD sizeImage = m_iFilesize - (DWORD)(pBitmapdata - pBitmap);//永远自己计算数据大小,因为位图INFO头中的biSizeImage字段可能为0.
CopyMemory(pDIBData, pBitmapdata, sizeImage);
return hBitmap;
}
void Bitmap::BitErrorshow(DWORD errorID) {
TCHAR szCaption[64];
LPVOID lpMsgBuf;
wsprintf(szCaption, L"错误代码:0x%08x", errorID);
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errorID,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL);
MessageBox(NULL, (LPTSTR)lpMsgBuf, szCaption, MB_OK | MB_ICONSTOP);
LocalFree(lpMsgBuf);
}
HBITMAP Bitmap::BitCreate(HDC hDC, LPTSTR szFilename) {
HANDLE hFile = NULL;
BitFree();//释放之前数据
__try {
hFile = CreateFile(szFilename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
m_hFilemapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
m_pBitmap = (PBYTE)MapViewOfFile(m_hFilemapping, FILE_MAP_READ, 0, 0, 0);
m_iFilesize = GetFileSize(hFile, 0);
BitTypedefined();
}__except (EXCEPTION_EXECUTE_HANDLER) {
BitErrorshow(GetLastError());
CloseHandle(hFile);
BitFree();
return NULL;
}
CloseHandle(hFile);
return BitLoad(hDC, m_pBitmap);
}
HBITMAP Bitmap::BitCreate(HDC hDC, HINSTANCE hInstance, UINT rscID) {
HRSRC hResInfo = NULL;
BitFree();//释放之前数据
__try {
hResInfo = FindResource(hInstance, MAKEINTRESOURCE(rscID), RT_BITMAP);
m_hGlablebitmap = LoadResource(hInstance, hResInfo);
m_pBitmap = (PBYTE)LockResource(m_hGlablebitmap);
m_iFilesize = SizeofResource(hInstance, hResInfo);
BitTypedefined();
}__except (EXCEPTION_EXECUTE_HANDLER) {
BitErrorshow(GetLastError());
BitFree();
return NULL;
}
return BitLoad(hDC, m_pBitmap);
}
void Bitmap::BitFree() {
if (m_hFilemapping != NULL) {
UnmapViewOfFile(m_pBitmap);
CloseHandle(m_hFilemapping);
m_hFilemapping = NULL;
}
else if (m_hGlablebitmap != NULL) {
UnlockResource(m_hGlablebitmap);
FreeResource(m_hGlablebitmap);
m_hGlablebitmap = NULL;
}
m_pBitmap = NULL;
m_iType = bitmap_undefined;
m_iFilesize = m_iHeight = m_iWidth = 0;
}
PBITMAPFILEHEADER Bitmap::GetBitFileheader(PBYTE pBitmap) {
if (m_hFilemapping != NULL)
return pBitmap ? (PBITMAPFILEHEADER)pBitmap : (PBITMAPFILEHEADER)m_pBitmap;
return NULL;
}
PBITMAPINFOHEADER Bitmap::GetBitInfoheader(PBYTE pBitmap) {
DWORD offset = 0;
if (m_hFilemapping != NULL)
offset = sizeof(BITMAPFILEHEADER);
return pBitmap ? (PBITMAPINFOHEADER)(pBitmap + offset) : (PBITMAPINFOHEADER)(m_pBitmap + offset);
}
LPRGBQUAD Bitmap::GetBitPalette(PBYTE pBitmap) {
PBITMAPINFOHEADER pBitmapinfo = GetBitInfoheader(pBitmap);
PBYTE pPalette = (PBYTE)pBitmapinfo + sizeof(PBITMAPINFOHEADER), pData = (PBYTE)GetBitData(pBitmap);
if (pPalette == pData)//不存在调色板
return NULL;
return (LPRGBQUAD)pPalette;
}
PVOID Bitmap::GetBitData(PBYTE pBitmap) {
DWORD offset = 0, n;
PBITMAPINFOHEADER pBitmapinfo = GetBitInfoheader(pBitmap);
n = pBitmapinfo->biClrUsed ? pBitmapinfo->biClrUsed : pBitmapinfo->biBitCount;
switch (m_iType) {
case bitmap1:
case bitmap4:
case bitmap4_RLE4:
case bitmap8:
case bitmap8_RLE8:
offset = (DWORD)pow(2, n); break;
case bitmap16_RGB565:
case bitmap32_mask:
offset = 1; break;
}
return (PBYTE)pBitmapinfo + offset * sizeof(RGBQUAD)+sizeof (BITMAPINFOHEADER);
}
void Bitmap::BitDraw(HDC hDC, int x, int y, HBITMAP hBitmap){
if (hBitmap != NULL) {
HDC hMemDC = CreateCompatibleDC(hDC);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);//载入位图
BitBlt(hDC, x, y, m_iWidth, m_iHeight, hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBitmap);//还原位图
DeleteDC(hMemDC);
}
}
代码测试图
1位位图:

4位位图

8位位图

24位位图

其他位图可以随意测试,均无问题。图片是我随意弄的,哈哈哈,自己用windows自带的画图工具就可以做出不同类型的位图,这里就不上传位图资源文件了。
BMP位图之代码实现的更多相关文章
- vc 加载bmp位图并显示的方法
方法一.显示位图文件 HBITMAP hBitmap=(HBITMAP)LoadImage(NULL,_T(“xxx.bmp”),Image_Bitmap,0,0,Lr_CreateDibSectio ...
- 将文件内容隐藏在bmp位图中
首先要实现这个功能,你必须知道bmp位图文件的格式,这里我就不多说了,请看:http://www.cnblogs.com/xiehy/archive/2011/06/07/2074405.html 接 ...
- C语言实现将彩色BMP位图转化为二值图
CTF做了图片的隐写题,还没有形成系统的认识,先来总结一下BMP图的组成,并通过将彩色图转为二值图的例子加深下理解. 只写了位图二进制文件的格式和代码实现,至于诸如RGB色彩和调色板是什么的一些概念就 ...
- 浅析BMP位图文件结构(含Demo)
浅析BMP位图文件结构(含Demo) 作者:一点一滴的Beer http://beer.cnblogs.com/ 关于BMP位图格式在网上可以找到比较详细的相关文档,有兴趣的可以搜索标题为“BMP ...
- (学习笔记3)BMP位图的读取与显示
在(学习笔记2)中.我们已经具体说明怎样去创建MFC.在这节中.主要解决BMP位图照片的读取和显示问题. 我们新建一个projectdemo1.创建步骤请看(学习笔记2)中具体说明. 创建成功后,例如 ...
- gnu-ucos 增加 bmp 位图显示
昨天又下了点功夫弄了个在tft屏幕上显示bmp位图的. 我选择的是24位tft真彩測显示方式所以也要选择真彩色位图.网上给出的16位位图数组无法使用.在csdn上下载了2个制作工具,一个是c代码的,一 ...
- 如何将打印内容转换为bmp位图文件
bmp是一种与硬件设备无关的图像文件格式,使用非常广.它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BblP文件所占用的空间很大.BMP文件的图像深度可选lbit.4bit.8 ...
- BMP位图图像格式简介
1. 文件结构 位图文件可看成由4个部分组成:位图文件头(bitmap-fileheader).位图信息头(bitmap-informationheader).彩色表(colortable)和定义位图 ...
- BMP位图调色板说明
网上一搜,可以看到BMP位图结构的详细说明,这篇文章专门谈一下其中的调色板. 多少位位图并不是指每一个颜色该用多少位表示,对于颜色来说,它始终都是24位(RGB),或者是32位(RGBA),而是指该位 ...
随机推荐
- 好客租房16-jsx中的列表渲染
如果要渲染一组数组 应该使用数组的map方法 注意:渲染列表时候添加key属性 key属性的值要保持唯一 原则:map()遍历谁 就给谁添加key属性 尽量避免索引号作为key //导入react i ...
- 关于基础RMQ——ST算法
RMQ,Range Maximum/Minimum Query,顾名思义,就是询问某个区间内的最大值或最小值,今天我主要记录的是其求解方法--ST算法 相对于线段树,它的运行速度会快很多,可以做到O( ...
- OI中组合数学公式和定理90%歼灭
组合数学 基础概念 加法和乘法原理 加法原理 同一步下的不同选择,可以通过累加得到方案数. 乘法原理 整个流程的方案数可以由每一步的方案数相乘得到. 有了加法原理和乘法原理,就可以解决一些没有选择导致 ...
- (干货)基于 veImageX 搭建海报生成平台 -- 附源码
前言 618 年中促销即将来临,很多公司都会通过海报来宣传自己的促销方案,通常情况下海报由设计团队基于 PS.Sketch 等工具创作,后期若想替换海报文案.商品列表等内容则需打开原工程进行二次创作, ...
- 使用nodejs的wxmnode模块,开发一个微信自动监控提醒功能,做个天气预报。
这个模块是一个公众号的模块,名字叫"帮你看着". 原本这个公众号是做股票监控提醒的,我也没炒股.因为接口支持写入任何内容,所以可以有其他的用处.比如做成天气预报定时提醒. 我们去n ...
- BUUCTF-假如给我三天光明
假如给我三天光明 打开压缩包可以看到一个海报,下方有盲文显示,通过对照表得知 盲文翻译为kmdonowg 通过盲文翻译得到的字符串解压压缩包得到一个音频文件 使用Audacity打开,看样子应该是摩斯 ...
- js 循环生成元素,并为元素添加click事件,结果只执行最后一个点击事件
问题描述:有一个参数集合data,for循环为每一个参数生成一个dom元素,并附加onclick事件.生成之后发现点击事件里的参数全是data集合里的最后一个. 代码如下: var dom=$('#d ...
- Maven + SSM环境搭建
Maven + SSM 之前Maven+SSM都是照着搭建的,自己想写点什么的时候发现搭建的过程不清楚. 于是花了时间边整理思路边搭建,并把搭建过程记录下来. 视频看来终觉浅,还是需要自己动手实践,捋 ...
- 利用IDEA搭建SpringBoot项目,整合mybatis
一.配置文件.启动项目 生成之后这几个文件可以删掉的 配置application spring.datasource.url=jdbc:mysql://localhost:3306/test?serv ...
- Linux 目录挂载服务
Linux 服务器挂载文件目录通常有三种形式,手动挂载.自动挂载.Autofs 自动挂载,下面对这三个挂载做一下介绍,接受一下这三个区别以及使用场景: 准备服务器和客户端: server 192.16 ...