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),而是指该位 ...
随机推荐
- 【clickhouse专栏】数据库、数据仓库之间的区别与联系
从本篇文章开始,笔者打算写一个系列的<clickhouse专栏>,其全称是Click Stream,Data WareHouse,简称ClickHouse.从其全称中的"Data ...
- JAVA - ArrayList是否会越界?
JAVA - ArrayList是否会越界? ArrayList并发add()可能出现数组下标越界异常. ArrayList是实现了基于动态数组的数据结构. LinkedList是基于链表的数据结构 ...
- 2021.06.05【NOIP提高B组】模拟 总结
T1 题意:给你一个 \(n\) 个点 \(n\) 条边的有向图, 求每个店经过 \(K\) 条边后的边权和.最小边权 \(K\le 10^{10}\) 考试时:一直想着环,结果一直不知道怎么做 正解 ...
- centos7 离线升级/在线升级操作系统内核
目录 一.前言 二.系统环境 三.系统内核下载网址 四.centos7离线升级系统内核 1.先查看系统环境 2.离线升级系统内核 五.在线升级系统内核 一.前言 CentOS(Community EN ...
- 【机器学习】K-means聚类分析
前言 聚类问题是无监督学习的问题,算法思想就是物以类聚,人以群分,聚类算法感知样本间的相似度,进行类别归纳,对新输入进行输出预测,输出变量取有限个离散值.本次我们使用两种方法对鸢尾花数据进行聚类. 无 ...
- 编译调试Net6源码
前言 编辑调试DotNet源码可按照官网教程操作,但因为网络问题中间会出现各种下载失败的问题,这里出个简单的教程(以6为版本) 下载源码 下载源码 GitHub下载源码速度极慢,可替换为国内仓库htt ...
- 12.1 Android Studio如何手动下载Gradle文件
实际操作过程中,可能由于各方面原因,导致Gradle无法下载,或者下载比较慢,这个时候,其实我们可以手动下载,或者找一个最近的版本,替换他. 确认要下载的版本 不论是用命令编译Android项目,还是 ...
- 基于 Github Actions 自动部署 Hexo 博客
前言 前不久使用了 Hexo 搭建独立博客,我是部署在我的腾讯云轻量应用服务器上的,每次都需要 hexo deploy 然后打包.上传.解压和刷新 CDN,非常麻烦.我的服务器配置也不高 2C2G 无 ...
- IDEA的项目结构和IDEA的HelloWord
IDEA首次驱动 1. 选择不导入任何设置,点击 OK 2. 选择 Create New Project 3. 点击 new 按钮,配置安装的 JDK9 版本 选择 JDK9 目录,点击确定 4. 不 ...
- springboot creating bean with name 'sqlSessionFactory'
pom.xml文件配置 <build> <plugins> <plugin> <groupId>org.springframework.boot< ...