C++读图片——Mac下对于bmp文件读写读取过大的解决方案

本文介绍了在Mac环境下处理BMP文件时遇到的尺寸过大问题,当读取文件后,由于long类型在64位系统中占8个字节,导致BITMAPINFOHEADER结构体字节数变为80,而非预期的40字节。为解决此问题,只需将结构体中的long类型替换为int类型,以确保结构体大小正确,从而避免读取错误。通过调整数据类型,成功解决了因编译器差异引发的文件处理问题。
摘要由CSDN通过智能技术生成

Mac下对bmp文件处理时size过大的解决方案

当在读写bmp信息头的时候,首先对根据C和C++的对齐预编译指令进行对齐之后,当进行读文件之后会出现biWidth和biHeight过大的情况。本篇文章对这个情况提出解决方案。

 struct BITMAPINFOHEADER
 {
 unsigned long   biSize;            //本结构所占用字节数 40字节
 long            biWidth;           //位图的宽度,以像素为单位
 long            biHeight;          //位图的高度,以像素为单位
 unsigned short  biPlanes;          //目标设备的级别,必须为1
 unsigned short  biBitCount;        //每个像素所需的位数,必须是1(双色)、4(16色)、8(256色)或24(真彩色)之一
 unsigned long   biCompression;     //位图压缩类型,必须是 0(BI_RGB不压缩)、
 unsigned long   biSizeImage;       //位图的大小,以字节为单位
 long            biXPelsPerMeter;   //位图水平分辨率,每米像素数
 long            biYPelsPerMeter;   //位图垂直分辨率,每米像素数
 unsigned long   biClrUsed;         //位图实际使用的颜色表中的颜色数
 unsigned long   biClrImportant;    //位图显示过程中重要的颜色数
 };

问题描述

当读取文件之后进行malloc或者new处理时,会出现malloc分配空间出现错误的情况,此时查看信息头之后发现biWidth和biHeight过大的情况(如下图),此时进行图片写入的时候会出现错误。
在这里插入图片描述
此时用sizeof对信息头进行输出之后发现原本对齐之后应该是40的变成了80。
此时便出现了读文件错误。

解决方法

此时就要考虑到我们在读文件时,运用对齐之后计算机应该读取40个字节,但是此时读取了80个字节,所以出现了读取错误。此时就要考虑到电脑编译器是不是32位的,后面发现Mac下的编译器确实是64位的,而64位下的long是8个字节,所以在对齐之后信息头所占的字节数时80,因此解决方法也很简单,只需要将long改为int即可解决。

struct BITMAPINFOHEADER
{
    unsigned int   biSize;            //本结构所占用字节数 40字节
    int            biWidth;           //位图的宽度,以像素为单位
    int            biHeight;          //位图的高度,以像素为单位
    unsigned short biPlanes;          //目标设备的级别,必须为1
    unsigned short biBitCount;        //每个像素所需的位数,必须是1(双色)、4(16色)、8(256色)或24(真彩色)之一
    unsigned int   biCompression;     //位图压缩类型,必须是 0(BI_RGB不压缩)、
    unsigned int   biSizeImage;       //位图的大小,以字节为单位
    int            biXPelsPerMeter;   //位图水平分辨率,每米像素数
    int            biYPelsPerMeter;   //位图垂直分辨率,每米像素数
    unsigned int   biClrUsed;         //位图实际使用的颜色表中的颜色数
    unsigned int   biClrImportant;    //位图显示过程中重要的颜色数
};

在这里插入图片描述
此时问题就得到解决啦。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是C++语言实现BMP文件的写代码示例: ```c++ #include <iostream> #include <fstream> #include <vector> using namespace std; #pragma pack(push, 1) // BMP文件头 struct BMPHeader { char signature[2]; uint32_t fileSize; uint32_t reserved; uint32_t dataOffset; }; // BMP信息头 struct BMPInfoHeader { uint32_t size; uint32_t width; uint32_t height; uint16_t planes; uint16_t bitCount; uint32_t compression; uint32_t imageSize; uint32_t xPixelsPerMeter; uint32_t yPixelsPerMeter; uint32_t colorsUsed; uint32_t colorsImportant; }; #pragma pack(pop) // 读取BMP文件 vector<uint8_t> readBMP(const char *filename, BMPInfoHeader &infoHeader) { ifstream file(filename, ios::binary); BMPHeader header; file.read(reinterpret_cast<char *>(&header), sizeof(BMPHeader)); if (header.signature[0] != 'B' || header.signature[1] != 'M') { cerr << "Error: Invalid BMP file" << endl; return vector<uint8_t>(); } file.read(reinterpret_cast<char *>(&infoHeader), sizeof(BMPInfoHeader)); if (infoHeader.bitCount != 24) { cerr << "Error: Only support 24-bit BMP file" << endl; return vector<uint8_t>(); } file.seekg(header.dataOffset, ios::beg); vector<uint8_t> imageData(infoHeader.imageSize); file.read(reinterpret_cast<char *>(imageData.data()), infoHeader.imageSize); file.close(); return imageData; } // 写入BMP文件 bool writeBMP(const char *filename, const BMPInfoHeader &infoHeader, const vector<uint8_t> &imageData) { ofstream file(filename, ios::binary); BMPHeader header; header.signature[0] = 'B'; header.signature[1] = 'M'; header.fileSize = sizeof(BMPHeader) + sizeof(BMPInfoHeader) + imageData.size(); header.reserved = 0; header.dataOffset = sizeof(BMPHeader) + sizeof(BMPInfoHeader); file.write(reinterpret_cast<char *>(&header), sizeof(BMPHeader)); file.write(reinterpret_cast<const char *>(&infoHeader), sizeof(BMPInfoHeader)); file.write(reinterpret_cast<const char *>(imageData.data()), imageData.size()); file.close(); return true; } int main() { BMPInfoHeader infoHeader; vector<uint8_t> imageData = readBMP("input.bmp", infoHeader); // 处理BMP图像数据 writeBMP("output.bmp", infoHeader, imageData); return 0; } ``` 该代码实现了BMP文件的读取和写入,使用了C++中的结构体和文件流操作。其中,`readBMP`函数可以读取BMP文件的文件头和图像数据,返回一个字节向量,`writeBMP`函数可以将图像数据写入BMP文件。 为了测试,可以使用24位BMP格式的图像文件作为输入文件,该程序将入这个文件,然后将图像数据处理后写入一个新的文件。 需要注意的是,BMP文件是二进制文件,因此在读取和写入文件需要使用二进制模式打开文件。 另外,由于BMP文件中的元素存储顺序可能与机器的存储顺序不同,因此在读取和写入文件需要使用`pragma pack`指令来确保结构体的对齐方式。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值