既然是图解,此处省去介绍....直接上图

以下代码中SetPixel()为在屏幕中打点的函数,在单片机中由自己实现,

根据不同的位深来解析,都是根据以上图片方式,推导出来的算法.

并没有实现压缩算法,图像高度为负的情况,并且未优化,图像较大时速度慢

(pmybmp指向bmp文件的数组)

//windows下加入缓冲提高速度

HDC hdc=GetDC(hWnd);//second method
HDC hmdc = CreateCompatibleDC(hdc);
HBITMAP hbmp = CreateCompatibleBitmap(hdc, bminfohdr.biWidth, bminfohdr.biHeight);
SelectObject(hmdc, hbmp);

        char *pmybmp = (char*)BMP_WAVE;BITMAPFILEHEADER bmfilehdr;BITMAPINFOHEADER bminfohdr; memcpy(&bmfilehdr, &pmybmp[0], sizeof(BITMAPFILEHEADER));//14memcpy(&bminfohdr, &pmybmp[14], sizeof(BITMAPINFOHEADER));//40printf("\n..............................\n");printf("\nsizeof(BITMAPFILEHEADER)=%d\n", sizeof(BITMAPFILEHEADER));printf("bmfilehdr.bfType=%#02x\n", bmfilehdr.bfType);printf("bmfilehdr.bfSize=%#04x,bmp文件大小:%d字节\n", bmfilehdr.bfSize, bmfilehdr.bfSize);printf("bmfilehdr.bfOffBits=%#04x (到RGBQUAD偏移字节)\n", bmfilehdr.bfOffBits);printf("sizeof(BITMAPINFOHEADER)=%d\n", sizeof(BITMAPINFOHEADER));printf("bminfohdr.biSize=%#04x  ( 结构体BITMAPINFOHEADER大小,=sizeof(BITMAPINFOHEADER) )\n", bminfohdr.biSize);printf("bminfohdr.biWidth=%#04x  (位图宽:%dpixels)\n", bminfohdr.biWidth, bminfohdr.biWidth);printf("bminfohdr.biHeight=%#04x  (位图高:%dpixels)\n", bminfohdr.biHeight, bminfohdr.biHeight);printf("bminfohdr.biPlanes=%#02x  (平面数)\n", bminfohdr.biPlanes);printf("bminfohdr.biBitCount=%#02x  (%d位深,1:单色,4:16色,8:256色,16:高彩色,24:真彩色,32:增强真彩色)\n", bminfohdr.biBitCount, bminfohdr.biBitCount);printf("bminfohdr.biCompression=%d  (压缩算法:0:BI_RGB,1:BI_RLE8,2:BI_RLE4,3:BI_BITFIELEDS,4:BI_JPEG,5:BI_PNG)\n", bminfohdr.biCompression);printf("bminfohdr.biSizeImage=%d  (位图缓冲,BI_RGB常为0)\n", bminfohdr.biSizeImage);printf("bminfohdr.biXPelsPerMeter=%d  (水平分辨率,pixels/meter)\n", bminfohdr.biXPelsPerMeter);printf("bminfohdr.biYPelsPerMeter=%d  (垂直分辨率,pixels/meter)\n", bminfohdr.biYPelsPerMeter);printf("bminfohdr.biClrUsed=%d  (位深为1~8时,用于指定调用板用到的颜色数,0表示全部都用到)\n", bminfohdr.biClrUsed);printf("bminfohdr.biClrImportant=%d  (0表示所有色彩都重要)\n", bminfohdr.biClrImportant);switch (bminfohdr.biBitCount)//位深,bpp,bit per pixel{//色彩位数case 32://0x20,增强真彩色,RGBA  ///bminfohdr.biCompression == BI_RGB ||bminfohdr.biCompression ==BI_BITFIELDS{for (long h = 0; h < bminfohdr.biHeight; h++){for (long w = 0; w < bminfohdr.biWidth; w++){unsigned long idxRGB = bmfilehdr.bfOffBits + w*bminfohdr.biBitCount / 8 + (bminfohdr.biWidth*bminfohdr.biBitCount / 8)*h;//由索引到调色板,0XBB,0XGG,0XGG  //bmfilehdr.bfOffBits指向 调色板 的开头RGBQUAD *pixelclr = (RGBQUAD*)&pmybmp[idxRGB];SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr->rgbRed, pixelclr->rgbGreen, pixelclr->rgbBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h}}}break;case 24://24bit/pixel,0x18,真彩色,16777216色{long pad0 = (4 - bminfohdr.biBitCount / 8 * bminfohdr.biWidth % 4) % 4;//补0字节数,bitcount 为位数要除以8!!!for (long h = 0; h < bminfohdr.biHeight; h++){for (long w = 0; w < bminfohdr.biWidth; w++){unsigned long idxRGB = bmfilehdr.bfOffBits + w*bminfohdr.biBitCount / 8 + (bminfohdr.biWidth*bminfohdr.biBitCount / 8 + pad0)*h;//由索引到调色板,0XBB,0XGG,0XGG  //bmfilehdr.bfOffBits指向 调色板 的开头RGBTRIPLE *pixelclr = (RGBTRIPLE*)&pmybmp[idxRGB];// printf("index:%d,RGB(%d,%d,%d)\n", idxRGB, pixelclr->rgbtRed, pixelclr->rgbtGreen, pixelclr->rgbtBlue);SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr->rgbtRed, pixelclr->rgbtGreen, pixelclr->rgbtBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h}}}break;case 16://0x10,高彩色,65536色,RGB565,RGB444,RGB555switch (bminfohdr.biSize){case 0x28://X1RGB555,最高位空{int pad0 = 32 - bminfohdr.biBitCount*bminfohdr.biWidth % 32;for (long h = 0; h < bminfohdr.biHeight; h++){for (long w = 0; w < bminfohdr.biWidth; w++){unsigned long idxRGB = bmfilehdr.bfOffBits + w*bminfohdr.biBitCount / 8 + (bminfohdr.biWidth*bminfohdr.biBitCount + pad0)*h / 8;//由索引到调色板,0XBB,0XGG,0XGG  //bmfilehdr.bfOffBits指向 调色板 的开头USHORT color = *(USHORT*)&pmybmp[idxRGB];RGBTRIPLE pixelclr;pixelclr.rgbtRed = ((0x7c00 & color) >> 7);//RED:D6D5D4D3D2,即每个分量只有5位,靠MSB位置处放pixelclr.rgbtGreen = ((0x03e0 & color) >> 2);//GREEN:D6D5D4D3D2pixelclr.rgbtBlue = ((0x001f & color) << 3);//BLUE:D6D5D4D3D2SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr.rgbtRed, pixelclr.rgbtGreen, pixelclr.rgbtBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h}}}break;case 0x38://根据掩膜来取RGB,X4RGB444,RGB565{if (bminfohdr.biCompression == BI_BITFIELDS){struct CLRMASK{DWORD RedMask, GreenMask, BlueMask, AlphaMask;};int rr = 0, rg = 0, rb = 0;CLRMASK *clr = (CLRMASK*)&pmybmp[icolor_table];//printf("icolor_table:%02X,RGBA_MASK:%04x,%04x,%04x,%04x\n", icolor_table, clr->RedMask, clr->GreenMask, clr->BlueMask, clr->AlphaMask);int pad0 = (32 - bminfohdr.biBitCount*bminfohdr.biWidth % 32) % 32;//cmd.puts("...............,.............\n");if (clr->RedMask == 0xf800 && clr->GreenMask == 0x07e0 && clr->BlueMask == 0x001f) { rr = 8; rg = 3; rb = 3; }else if (clr->RedMask == 0x0f00 && clr->GreenMask == 0x00f0 && clr->BlueMask == 0x000f) { rr = 4; rg = 0; rb = 4; }for (long h = 0; h < bminfohdr.biHeight; h++){for (long w = 0; w < bminfohdr.biWidth; w++){unsigned long idxRGB = bmfilehdr.bfOffBits + w*bminfohdr.biBitCount / 8 + (bminfohdr.biWidth*bminfohdr.biBitCount + pad0)*h / 8;//由索引到调色板,0XBB,0XGG,0XGG  //bmfilehdr.bfOffBits指向 调色板 的开头USHORT color = *(USHORT*)&pmybmp[idxRGB];RGBTRIPLE pixelclr;pixelclr.rgbtRed = (BYTE)((clr->RedMask & color) >> rr);//RED:D6D5D4D3D2,即每个分量只有5位,靠MSB位置处放pixelclr.rgbtGreen = (BYTE)((clr->GreenMask & color) >> rg);//GREEN:D6D5D4D3D2pixelclr.rgbtBlue = (BYTE)((clr->BlueMask & color) << rb);//BLUE:D6D5D4D3D2SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr.rgbtRed, pixelclr.rgbtGreen, pixelclr.rgbtBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h}}}}break;}break;case 8://8bit/pixel,256色{long pad0 = (4 - bminfohdr.biBitCount * bminfohdr.biWidth / 8 % 4) % 4;//补0字节数//if (pad0 == 4) pad0 = 0;for (long h = 0; h < bminfohdr.biHeight; h++){for (long w = 0; w < bminfohdr.biWidth + pad0; w++){//位图颜色数据索引unsigned long   ibmoffset = w + (bminfohdr.biWidth + pad0) * h;unsigned char  iclrtbl = pmybmp[bmfilehdr.bfOffBits + ibmoffset];//由索引到调色板,0XBB,0XGG,0XGG,0XAA  //icolor_table指向 调色板 的开头RGBQUAD *pixelclr = (RGBQUAD*)&pmybmp[icolor_table + iclrtbl * 4];SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr->rgbRed, pixelclr->rgbGreen, pixelclr->rgbBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h}}//   printf("FINISHED\n");}break;case 4: //4bit/pixel,16色位图//  bminfohdr.biCompression{int pad0 = (32 - bminfohdr.biBitCount*bminfohdr.biWidth % 32) % 32;for (long h = 0; h < bminfohdr.biHeight; h++){for (long w = 0; w < bminfohdr.biWidth; w++){//索引,4位的索引,即半字节索引unsigned long   ibmoffset = bmfilehdr.bfOffBits + w / 2 + (bminfohdr.biBitCount*bminfohdr.biWidth + pad0) / 8 * h;unsigned char  iclrtbl = (pmybmp[ibmoffset] >> ((1 - (w & 0x1)) * 4)) & 0x0f;//由索引到调色板,0XBB,0XGG,0XGG,0XAA //icolor_table指向 调色板 的开头RGBQUAD *pixelclr = (RGBQUAD*)&pmybmp[icolor_table + iclrtbl * 4];SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, RGB(pixelclr->rgbRed, pixelclr->rgbGreen, pixelclr->rgbBlue)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h}}}break;case 1://单色,一般为黑白,1=白,0=黑,但其实两是两种可定义的颜色,即双色位图 {int pad0 = (32 - bminfohdr.biBitCount*bminfohdr.biWidth % 32) % 32;for (long h = 0; h < bminfohdr.biHeight; h++){for (long w = 0; w < bminfohdr.biWidth; w++){long idx = (w + h*(bminfohdr.biWidth + pad0)) / 8;unsigned char  mask = (1 << (7 - w % 8));unsigned char dat = pmybmp[bmfilehdr.bfOffBits + idx];SetPixel(hmdc, w, bminfohdr.biHeight - h - 1, (dat & mask) ? RGB(255, 255, 255) : RGB(0, 0, 0)); // bminfohdr.biHeight>0,图像上下倒置,所以要bminfohdr.biHeight - h}}}break;}

//windows下加入缓冲提高速度      
BitBlt(hdc,1,1,bminfohdr.biWidth,bminfohdr.biHeight, hmdc, 0, 0, SRCCOPY);
DeleteObject(hbmp);
DeleteDC(hmdc);
ReleaseDC(hWnd,hdc);

补充:在WINDOWS上可以用一条语句代替以上代码,速度非常之快,超乎想象,不知道WINDOWS内部是怎么实现的    
 SetDIBitsToDevice(hdc, 0, 0, bminfohdr.biWidth, bminfohdr.biHeight, 0, 0, 0, bminfohdr.biHeight, (pmybmp+ bmfilehdr.bfOffBits), (BITMAPINFO*)&pmybmp[14], DIB_RGB_COLORS); 
//lpvBits :Pointer to DIB color data stored as an array of bytes.
//BITMAPFILEHEADER.bfOffBits:Specifies the offset, in bytes, from the BITMAPFILEHEADER structure to the bitmap bits

图解 bmp 文件(BITMAP,windows位图文件)格式相关推荐

  1. Python打包工具Pyintealler打包py文件为windows exe文件过程及踩坑记录+实战例子

    Python打包工具Pyintealler打包py文件为windows exe文件过程及踩坑记录+实战例子 目录 Python打包工具Pyintealler打包py文件为windows exe文件过程 ...

  2. linux头文件与windows头文件,socklen_t在windows和linux平台下的头文件定义

    5-udev多路径 udev多路径 查看scsi的唯一标识符 用这个计算机可以识别 重启服务 想要看到下面的,可能重启服务也不行,那就需要重启计算机了 虚拟磁盘 安装这个包multipath 重启服务 ...

  3. 位图文件(BMP)格式分析

    一.文件格式  Bmp文件是非常常用的位图文件,无论是游戏还是其他都被广泛使用.针对bmp文件的处理也有一堆现成的api进行调用,然而文件内部究竟怎样,如何自己来解析这样的文件呢?为了消除无聊,我用了 ...

  4. 位图文件, JPG格式,PNG格式

    位图文件(Bitmap), 扩展名可以是.bmp或者.dib.位图文件是Windows标准格式图形文件,它将图像定义为由点(像素)组成,每个点可以由多种色彩表示,包括2.4.8.16.24和32位色彩 ...

  5. 重温WIN32 API ------ 窗口上绘制位图文件

    1 基本思路 做界面仿真时,经常需要在窗口上贴图,随着图片数量的增多,通过资源文件中添加位图的方式会变得越来越不可控.所以本着"资源与程序分离"的原则,还是使用外部位图文件更加清晰 ...

  6. 使用 Windows 脚本文件 (.wsf)

    使用 Windows 脚本文件 (.wsf) Windows 脚本文件 (*.wsf) 是含有可扩展标记语言 (XML) 代码的文本文档.它综合了几个可增强脚本灵活性的功能.由于 Windows 脚本 ...

  7. [转载]初识Windows 脚本文件(*.wsf)

    初识Windows 脚本文件(*.wsf) Windows 脚本文件(*.wsf) 是含有可扩展标记语言 (XML) 代码的文本文档,它综合了几个可增强脚本灵活性的功能.由于 Windows 脚本文件 ...

  8. widnows命令行常用命令使用 和 windows创建文件,写内容到文件

    widnows命令行常用命令使用 和 windows创建文件,写内容到文件 1 查看windows命令行常用命令的使用文档 1.1 查看windows中命令行命令 1.2 windows查看某个指定命 ...

  9. windows.edb文件过大,导致c盘空间极小问题

    解决方案2:删除并重建Windows.edb文件 解决Windows.edb文件巨大的windows 10问题的另一个快速解决方法是删除Windows.edb文件. 步骤1:在任务管理器中终止Sear ...

最新文章

  1. 逻辑覆盖测试(一)语句覆盖
  2. java类的运行顺序_Java语言类的基本运行顺序
  3. python读取excel画散点图-python学习之matplotlib绘制散点图实例
  4. zabbix server is not running the information displayed may not be current
  5. vue vue实例中的data与vue组件中的data()
  6. 拿来即用的 Python 时间范围判断方法
  7. 【渝粤题库】广东开放大学 建筑工程概预算 形成性考核
  8. atitit.网络文件访问协议.unc smb nfs ftp http的区别
  9. GlobalMapper20提取点位的高程信息
  10. jsp与jspx文件
  11. 武汉大学计算机网络安全学院,消息︱武汉大学计算机学院(新)与国家网络安全学院正式组建...
  12. 如何在 iPhone 和 iPad 上将你的照片转换为 PDF?
  13. 李航统计学习方法笔记——泛化误差上界
  14. 巧解决阿里云虚拟主机免费版被DDOS攻击问题
  15. 网卡VXLAN的offload技术介绍
  16. Xilinx ZynqMP相关
  17. 学习笔记:python爬虫(第一次写笔记,多多包涵)
  18. Matlab之选取特定区域的坐标点
  19. T13735 fateice-string洛谷八连测2
  20. 听君一席话,胜读十年书

热门文章

  1. ubuntu自带的IBUS 不能切换中英文,装一个sunpinyin就好了
  2. 蓝牙HC05常用调试指令
  3. 你距离家只差一个刷票脚本而已——12306刷票脚本升级版
  4. 【源码】便捷飞行器设计软件Aircraft Intuitive Design (AID) version 1.2.0.0
  5. 关于FPGA设计中的参数化设计
  6. 转载--软件架构模式
  7. 《影响力》note,kotlin开发环境搭建
  8. LeetCode简单题之统计数组中峰和谷的数量
  9. 学校人力资源管理系统可行性研究和需求分析
  10. 常使用投射,折射等各类新型光源和灯具