处理不含调色板的BMP格式图片(24位转16位)

一、BMP图片格式头

struct Bmp_Fileheader_ST   //文件头,长度为14Byte
{
  unsigned short bfType;       //'BM'格式  0x4D42
  unsigned long bfSize;        //文件大小
  unsigned short bfReserved1;  //保留位为0
  unsigned short bfReserved2;  //保留位为0
  unsigned long bfOffBits;     //文件头到像素数据的偏移
};
 
struct Bmp_Infoheader_ST  //文件信息头,长度为40Byte
{
  unsigned long biSize;         //此结构大小
  unsigned long biWidth;        //图像宽度
  unsigned long biHeight;       //图像高度
  unsigned short biPlanes;
  unsigned short biBitCount;    //说明比特数/像素数,文章标题中所写的24位
  unsigned long biCompression;
  unsigned long biSizeImage;
  unsigned long biXPelsPerMeter;
  unsigned long biYPelsPerMeter;
  unsigned long biClrUsed;
  unsigned long biClrImportant;
};

二、读取BMP图像信息

1.读取文件头与信息头

int fp = open("图片路径", O_RDONLY); //打开BMP图像

struct Bmp_Fileheader_ST head;	//文件头结构体变量
struct Bmp_Infoheader_ST info;//信息头结构体变量
  
//这里建议先读取2字节文件类型(为了方便接着读取文件头时的字节对齐问题)
unsigned short bfType;        //先读取’BM‘
FS_FRead(&bfType, sizeof(unsigned short), 1,  fp);
  
read(fp, &head, sizeof(head));        //读取文件头
read(fp, &info, sizeof(info));        //读取文件信息

2.读取源RGB数据存入源数据内存

int rgb_size = head.bfSize -sizeof(unsigned short) - sizeof(head) - sizeof(info);     //源rgb数据大小
  
unsigned char *src_buf;
  
//为了方便接来下的24位数据转成16位,申请8位大小的内存来存放一个'r'/'g'/'b'的数据
src_buf = (unsigned char*)malloc(rgb_size * sizeof(char));    //读取rgb原始数据
read(fp, src_buf, rgb_size); 

三、源24位RGB数据转16位

 unsigned short *dst_buf;
 //申请16位大小的内存刚好存放处理后的rgb数据(dst_buf[0]就为转换成功后的第一个rgb数据)
 dst_buf = (unsigned short*)malloc((rgb_size / 3) * sizeof(short));
 
int temp[3];
unsigned long dst_subscript = 0;
for(unsigned long src_subscript = 0; src_subscript < rgb_size; src_subscript += 3)        //24位转16位
{
  temp[0] = src_buf[src_subscript] >> 3;		//'r''b'都保留高5位
  temp[1] = src_buf[src_subscript + 1] >> 2;	//'g'保留高6位
  temp[2] = src_buf[src_subscript + 2] >> 3;
    
//经过验证,下面两种运算都能正确转换为16位rgb数据(有人说不能用加运算,大家可以去测试,我测试是成功的)
//dst_buf[dst_subscript] = (temp[0] << 11) | (temp[1] << 5) | temp[2] ;
  dst_buf[dst_subscript] = (temp[0] << 11) + (temp[1] << 5) + temp[2] ;
  dst_subscript ++;
}

最后别忘记释放资源…close(fp); free(src_buf); free(dst_buf);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值