从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位图之代码实现的更多相关文章

  1. vc 加载bmp位图并显示的方法

    方法一.显示位图文件 HBITMAP hBitmap=(HBITMAP)LoadImage(NULL,_T(“xxx.bmp”),Image_Bitmap,0,0,Lr_CreateDibSectio ...

  2. 将文件内容隐藏在bmp位图中

    首先要实现这个功能,你必须知道bmp位图文件的格式,这里我就不多说了,请看:http://www.cnblogs.com/xiehy/archive/2011/06/07/2074405.html 接 ...

  3. C语言实现将彩色BMP位图转化为二值图

    CTF做了图片的隐写题,还没有形成系统的认识,先来总结一下BMP图的组成,并通过将彩色图转为二值图的例子加深下理解. 只写了位图二进制文件的格式和代码实现,至于诸如RGB色彩和调色板是什么的一些概念就 ...

  4. 浅析BMP位图文件结构(含Demo)

    浅析BMP位图文件结构(含Demo) 作者:一点一滴的Beer http://beer.cnblogs.com/   关于BMP位图格式在网上可以找到比较详细的相关文档,有兴趣的可以搜索标题为“BMP ...

  5. (学习笔记3)BMP位图的读取与显示

    在(学习笔记2)中.我们已经具体说明怎样去创建MFC.在这节中.主要解决BMP位图照片的读取和显示问题. 我们新建一个projectdemo1.创建步骤请看(学习笔记2)中具体说明. 创建成功后,例如 ...

  6. gnu-ucos 增加 bmp 位图显示

    昨天又下了点功夫弄了个在tft屏幕上显示bmp位图的. 我选择的是24位tft真彩測显示方式所以也要选择真彩色位图.网上给出的16位位图数组无法使用.在csdn上下载了2个制作工具,一个是c代码的,一 ...

  7. 如何将打印内容转换为bmp位图文件

    bmp是一种与硬件设备无关的图像文件格式,使用非常广.它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BblP文件所占用的空间很大.BMP文件的图像深度可选lbit.4bit.8 ...

  8. BMP位图图像格式简介

    1. 文件结构 位图文件可看成由4个部分组成:位图文件头(bitmap-fileheader).位图信息头(bitmap-informationheader).彩色表(colortable)和定义位图 ...

  9. BMP位图调色板说明

    网上一搜,可以看到BMP位图结构的详细说明,这篇文章专门谈一下其中的调色板. 多少位位图并不是指每一个颜色该用多少位表示,对于颜色来说,它始终都是24位(RGB),或者是32位(RGBA),而是指该位 ...

随机推荐

  1. unity---动画基础

    旧动画系统 using System.Collections; using System.Collections.Generic; using UnityEngine; public class Mo ...

  2. C# settings 文件基础用法

    原文 自定义设置项类型 Serializable 修饰的枚举,可作为设置项类型 [Serializable] public enum DeviceBrand { None = 0, [Descript ...

  3. Django-request的常见属性

    瞧一瞧,看一看,Django时,获取Request的各个属性. Request的常见属性 request.META 返回一个python字典.它包含了所有的HTTP请求信息.如下代码: 点击查看代码 ...

  4. Spring IOC源码研究笔记(2)——ApplicationContext系列

    1. Spring IOC源码研究笔记(2)--ApplicationContext系列 1.1. 继承关系 非web环境下,一般来说常用的就两类ApplicationContext: 配置形式为XM ...

  5. re学习笔记

    re学习笔记 学习链接: https://regexlearn.com/zh-cn/learn \w: 数字字母下划线 \W: 非\w \d \D: !\d \s: space cha \S: !\s ...

  6. make 随笔

    # --with--cc-opt flag导致./configure时找不到对应库文件? checking for --with-ld-opt="-Wl,-z,relro -Wl,-z,no ...

  7. SAP FPM 相关包 APB_FPM_CORE

    related interface: APB_FPM_COREAPB_FPM_CORE_4_EXT_SCAPB_FPM_CORE_INTERNALAPB_FPM_CORE_RESTRICTED

  8. UiPath参数介绍和使用

    一.参数介绍 用于将数据从一个项目传递到另一个项目.在全局意义上,它们类似于变量,因为它们动态地存储数据并传递给它.变量在活动之间传递数据,而参数在自动化之间传递数据.因此,它们使你能够一次又一次地重 ...

  9. 正在运行中的docker容器设置自动重启

    # demo : 你的容器名称 docker update –-restart=always demo

  10. Mysql错误:The server time zone value is unrecognized or represents more than one time zone

    方法1.修改Mysql的时区为东8区,执行如下命令即可: PS:这种方式每次开机都要配置的 set global time_zone='+8:00' 方法2.配置改成这样的 spring.dataso ...