C++ bmp位图读取
来源:互联网 发布:知几学生密码是什么 编辑:程序博客网 时间:2024/06/07 16:37
如何用C++读取 bmp图片格式颜色矩阵 以及显示
首先 简单解释一下bmp文件格式 在 http://paulbourke.net/dataformats/bmp/ 有官方详细解释
bmp 格式文件 分为四个部分
header 文件格式,大小
infoheader 图像的高,宽,位数
optional palette 可选调色板:使用索引来表示图像是的 索引与颜色的映射 并非一定包含
image data 图像像素信息的数据
其中24位bmp文件不使用索引 所以不需要optional palette 部分
header C结构体typedef struct { unsigned short int type; /* Magic identifier 文件格式*/ unsigned int size; /* File size in bytes 文件大小*/ unsigned short int reserved1, reserved2; /* 保留区 默认设置为0 */ unsigned int offset; /* Offset to image data, bytes文件头到图像数据信息便宜字节 */} HEADER;infoheader 结构体typedef struct { unsigned int size; /* Header size in bytes infoheader文件部分size大小 */ int width,height; /* Width and height of image 图像宽,高 */ unsigned short int planes; /* Number of colour planes 位面数 总为1 */ unsigned short int bits; /* Bits per pixel 像素位深 */ unsigned int compression; /* Compression type 压缩类型 */ unsigned int imagesize; /* Image size in bytes 图像大小(字节) */ int xresolution,yresolution; /* Pixels per meter 分辨率(水平,垂直) */ unsigned int ncolours; /* Number of colours 实际所用颜色索引数目 */ unsigned int importantcolours; /* Important colours 对图像显示有重要影响的颜色索引数 */} INFOHEADER;
读取方法
windows 默认最小扫描字节为4字节
bmp图像 记录每行像素 单位是字节,bmp图像每行像素最后位要进行补齐 与4字节对齐 根据补齐规则 算出用于补充的字符长度为
int nBytesPerRow = infoHeader.width * 3; //每行的的字节数 int nPaddingByresPerRow = 4 - (nBytesPerRow % 4); //用于补齐的字节数,也就是读取时需要跳过的字节数
#include"bitmap.h"#include<stdio.h>#include<assert.h>void LoadBmp(D3DCOLOR *surface) //d3d9.h头文件支持 surface为像存取像素地址 {FILE *bmpFile = fopen("C://Users//inkycherry//Desktop//C++forbmp//bmpSource//4.bmp", "rb"); //以二进制形式读入char signature[2];fread(&signature, sizeof(char), 2, bmpFile); //读取前两位 表示type字节BitmapFileHeader fileHeader;fread(&fileHeader, sizeof(fileHeader), 1, bmpFile); //读取header部分BitmapInfoHeader infoHeader;fread(&infoHeader, sizeof(infoHeader), 1, bmpFile); //读取infoheader部分fseek(bmpFile, fileHeader.offset, SEEK_SET);int nPixels = infoHeader.width*infoHeader.height; //图像的像素数int nBytesPerRow = infoHeader.width * 3; int nPaddingByresPerRow = 4 - (nBytesPerRow % 4); for (int y = infoHeader.height-1; y >=0; y--) //bmp文件是自底向上存储像素信息{for (int x = 0; x < infoHeader.width; x++){Piexl24 pixel; //Piexl24为 3个unsigned char变量的结构体fread(&pixel, sizeof(pixel), 1, bmpFile);//surface[x+y*infoHeader.width] = D3DCOLOR_XRGB(pixel.red, pixel.green, pixel.blue);surface[x+y*infoHeader.width] = D3DCOLOR_XRGB(pixel.red, pixel.green, pixel.blue);}fseek(bmpFile, nPaddingByresPerRow, SEEK_CUR); }fclose(bmpFile);
然后用directx打印,两个函数如下(因为directx还是菜鸟,现在还是用别人写的框架)
当然也可以存个一般的结构体数组 ,包含三个uint就可以了,通过其他输出像素的方式打印也可
void D3DGraphics::DrawSurface(int xoff, int yoff, int width, int height, const D3DCOLOR *xsurf){for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){PutPixel(x + xoff, y + yoff, xsurf[x + y*width]);}}}void PutPixel(int x, int y, D3DCOLOR c) {IDirect3DSurface9* pBackBuffer = NULL;D3DLOCKED_RECT rect;D3DGraphics::pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);pBackBuffer->LockRect(&rect, NULL, NULL);((D3DCOLOR*)rect.pBits)[x + (rect.Pitch >> 2) * y] = c;pBackBuffer->UnlockRect();pBackBuffer->Release();}DrawSurface(x,y,inforheader.width,infoheader.height,surface);
还有待完善,下次打印一下矩阵然后注释一下
这个效果图,你能看出打印的什么吗:)
————————————————————————————————————
上边的例子是24位的 基本也是用的最多的
struct Piexl24{
unsigned char blue;
unsigned char green;
unsigned char red;
};
读取32位的方法 比24位简单一些 他的结构体多了一个 alpha 的8位变量
struct Piexl32
{
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char alpha;
};
并且 32位的读取 肯定是4的倍数 不需要填充字符 文件读取不需要位移
读取只需要修改 填充部分 和 结构体类型即可
#include"bitmap.h"#include<stdio.h>#include<assert.h>#include<math.h>void LoadBmp(D3DCOLOR *surface) //d3d9.h头文件支持;{FILE *bmpFile = fopen("C://Users//inkycherry//Desktop//directxpratice//C++fortank//bmpSource//4.bmp", "rb");char signature[2];fread(&signature, sizeof(char), 2, bmpFile);BitmapFileHeader fileHeader;fread(&fileHeader, sizeof(fileHeader), 1, bmpFile);BitmapInfoHeader infoHeader;fread(&infoHeader, sizeof(infoHeader), 1, bmpFile);fseek(bmpFile, fileHeader.offset, SEEK_SET);infoHeader.width = abs(infoHeader.width);infoHeader.height = abs(infoHeader.height);int nPixels = infoHeader.width*infoHeader.height; //图像的像素数/*int nBytesPerRow = infoHeader.width * 3; int nPaddingByresPerRow = 4 - (nBytesPerRow % 4);*/for (int y = infoHeader.height-1; y >=0; y--){for (int x = 0; x < infoHeader.width; x++){Piexl32 pixel;fread(&pixel, sizeof(pixel), 1, bmpFile);//surface[x+y*infoHeader.width] = D3DCOLOR_XRGB(pixel.red, pixel.green, pixel.blue);surface[x+y*infoHeader.width] = D3DCOLOR_ARGB(pixel.alpha,pixel.red, pixel.green, pixel.blue);}/*fseek(bmpFile, nPaddingByresPerRow, SEEK_CUR);*/}fclose(bmpFile);}
另外还发现一个问题,刚测试的时候 都不到东西 调试发现height为负值 绝对值正确
查询得到 bmp 图像 width height 值正数为像素数组与图像逆向 负数则为正向
根据需要自己调一下循环就好了
- C++ BMP位图读取
- C++ bmp位图读取
- C++读取bmp位图入门
- C++读取bmp位图入门
- BMP位图读取部分代码
- 位图的读取,PNG转化为BMP
- 图像识别 - C++读取bmp位图入门
- 图像识别 - C++读取bmp位图入门
- 图像识别 - C++读取bmp位图入门
- 一名小白读取BMP位图的一点记录
- 飞鸽传书 CFile 来读取位图 BMP 文件
- 使用C++读取8位BMP位图
- C++读取BMP位图数据的方法
- C语言读取位图
- c语言下读bmp位图
- C语言读写bmp位图文件
- c语言读取bmp文件
- VC++6.0 中BMP位图的读取和显示
- scala 实现简单的RPC通信流程
- oracle 创建用户并授权
- 轨迹球经历 2017-6
- 关于B/S模式的web服务交互过程中的中文乱码问题浅析
- openNLP在eclipse中配置和使用
- C++ bmp位图读取
- 从尾到头打印链表
- UCOSII创建的创建任务
- 常用的工具类及方法:System、Math、Random、Arrays
- 【感想】百度 阿里 今日头条 面试感想
- Spring data jpa所需的全部jar包
- java使用POI实现替换文件中指定关键字
- 递归
- 一年Android工作经验,阿里 百度 网易 美团 小米 快手面经