位图图像文件缩放(c++)

本文围绕C++实现位图图像文件缩放展开。先介绍24位位图图像的定义、组成元素及结构体,指出像素点存储方式和每行元素大小要求。接着阐述主要算法,通过计算缩放后图像的高和宽,用双线性插值获取像素点颜色通道值。最后给出代码运行示例。

位图图像文件缩放(c++)

前言: c语言课程设计需要实现位图图像缩放,但并没有提供很详细的位图图像的理解,所以颇费了一番功夫,这里给大家整理下以供参考,如有不当之处,还希望纠正


理解位图图像(24位)

本篇文章只介绍biBitCount=24的位图图像,且代码也只适用于24位图像,且无压缩

定义

由多个像素点组成的图像

组成元素

共三部分

  • 位图文件头数据结构,包含BMP图像文件的类型、显示内容等信息
  • 位图信息数据结构,包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息
  • 每个像素点信息 (主要部分)

结构体定义

头文件
#include<windows.h>

  • BITMAPFILEHEADER (对应文件头)
  typedef struct tagBITMAPFILEHEADER {
   
   
    WORD bfType;//固定为0x4d42
    DWORD bfSize;//文件大小
    WORD bfReserved1;//保留字
    WORD bfReserved2;//保留字
    DWORD bfOffBits;//实际位图数据的偏移字节数,即前两个部分长度之和
  } BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
  • BITMAPINFOHEADER (对应信息数据)
  typedef struct tagBITMAPINFOHEADER {
   
   
    DWORD biSize;//指定此结构体的长度,为40
    LONG biWidth;//位图宽(单位:像素)
    LONG biHeight;//位图高(单位:像素)
    WORD biPlanes;//平面数,为1
    WORD biBitCount;//采用颜色位数,可以是1 2 4 8 16 24 32
    DWORD biCompression;//压缩方式,可以是0 1 2,其中0表示不压缩
    DWORD biSizeImage;//实际位图数据占用的字节数
    LONG biXPelsPerMeter;//X方向分辨率
    LONG biYPelsPerMeter;//Y方向分辨率
    DWORD biClrUsed;//使用的颜色数	
    DWORD biClrImportant;//重要颜色数
  } BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;

每个属性的具体意义可参考 这里

看起来属性很多,你只需要关注这些:

  • biWidth
  • biHeight
  • biBitCount

下面主要介绍biBitCount和像素点的存储方式

  • biBitCount 可以理解为每个像素点采用多少位二进制数来描述,例如biBitCount=24代表,每个像素点用24位二进制数描述,而每个像素点又由三个颜色通道组成(rgb),所以每个颜色通道由8位二进制数(1个字节)组成
  • 像素点的存储方式 可以先想象成一个矩阵,开始是矩阵的左下角,然后按行存储在这里插入图片描述
    所以你只需要按照顺序依次存储新的像素单位即可,但这里有一个比较坑的地方,位图规定每一行元素的大小必须是4byte的整数倍,意思就是如果每一行有1个像素点,即24bit,需要在每一行结尾填充8bit,这8bit数据没有任何意义,只是为了凑齐4byte的整数倍

主要算法

  • 计算出缩放后图像的height和width(单位:像素点数量)
  • 遍历目标图像的每一个像素点,找到它在源图像的位置,根据双线性插值获得该像素点的三个颜色通道的值
    在这里插入图片描述
    上图为目标图像的一个像素点(E)在源图像的位置,其中x和y均为整数,E点必定落在源图像的一个像素格中,设 F(E) 代表E点一个颜色通道的值,那么根据双线性插值可以求得
    F ( E ) = d x d y F ( B ) + ( 1 − d x ) ( 1 − d y ) F ( D ) + ( 1 − d x ) d y F ( A ) + d x ( 1 − d y ) F ( C ) F(E)=dxdyF(B) +(1-dx)(1-dy)F(D)+(1-dx)dyF(A)+dx(1-dy)F(C) F(E)=dxdyF(B)+(1dx)(1dy)F(D)+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值