bmp文件显示、翻转、灰化等操作 您所在的位置:网站首页 bmp格式文件不可以使用什么 bmp文件显示、翻转、灰化等操作

bmp文件显示、翻转、灰化等操作

2024-04-10 16:03| 来源: 网络整理| 查看: 265

一 BMP文件格式

BMP(Bitmap)是Windows操作系统中的标准图像文件格式。

Windows的发布时机远早于Linux、Android、IOS等操作系统,Windows中相当多的标准数据格式和算法也是当今所有OS绕不开、必须兼容的数据结构和算法。

BMP是当前计算机中图像文件的标准文件格式,它是计算机图像学这门课程的必修课,研究BMP的意义也在于此。

BMP文件类型可以分成两类:设备相关位图(DDB)和设备无关位图(DIB)。

BMP相较于其他图像格式的特点:

BMP文件不采用任何压缩。BMP是原始的像素数据的集合,文件格式简单易懂。图像的扫描方式是按从左到右、从下到上的顺序。兼容1、2、4、8、16、32位颜色模式。

BMP文件从头到尾结构如下:

1. bmp文件头(BITMAPFILEHEADER结构)

typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER, FAR*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;

bfType:’BM’两个可打印字符,用于标识BMP文件。

bfSize:文件大小

bfReserved1:保留,必须设置为0

bfReserved2:保留,必须设置为0

bfOffBits:从文件头到位图数据的偏移。一般来说,24位和32位的值是54(BITMAPINFOHEADER的大小+ BITMAPINFOHEADER的大小),而8位位图的值为1078(BITMAPINFOHEADER的大小+ BITMAPINFOHEADER的大小+颜色表的大小)

2 位图信息头(即BITMAPINFOHEADER结构)

typedef struct tagBITMAPINFOHEADER { DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

biSize:信息头大小,即40字节

biWidth:以像素为单位图像的宽度

biHeight:以像素为单位图像的高度。如果为正,说明位图倒立(即数据表示从图像的左下角到右上角),如果为负说明正向

biPlanes:为目标设备说明颜色平面数,总被设置为1

biBitCount:bit/pixel,1、2、4、8、16、24、32

biCompression:图像的压缩类型,最常用的就是0(BI_RGB),表示不压缩

biSizeImages:4字节,说明位图数据的大小,当用BI_RGB格式时,可以设置为0

biXPelsPerMeter:表示水平分辨率,单位是像素/米,有符号整数

biYPelsPerMeter:表示垂直分辨率,单位是像素/米,有符号整数

biClrUsed:位图使用的调色板中的颜色索引数,为0说明使用所有

biClrImportant:对图像显示有重要影响的颜色索引数,为0说明都重要

另外需要注意的是,位图的每显示一行的扫描线长度总是4字节对齐的,计算方法是: (width* biBitCount&31+ width* biBitCount)/4,不足的要补0,否则会导致文件格式解析错误。

3. 调色板(只存在于8位位图, 即RGBQUAD[256]数组)

typedef struct tagRGBQUAD { BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; } RGBQUAD;

当位图是8bit时,像素值代表调色板的索引值。显示器很早就可以支持24位色,此模式主要用于减小文件大小和历史兼容性。显示8位位图的像素值时,在调色板中按照索引值找到调色板中索引对应的红黄蓝三颜色的值,在显示器上显示对应的该24位颜色值。

4.位图数据

即像素值。24位像素值按照red,green,blue顺序排列。32位色按照ALPHA,red,green,blue顺序排列,alpha值代表透明度。16位比较特殊,一般是按照5:6:5的顺序表示red,green,blue这3种颜色的值。

二 BMP位图像素操作 将24位位图转换为8位

创建并在调色板中构造合适的24位颜色值,然后将24位(或者32位)位图的颜色值修改为调色板中的索引值。为了简单,代码中将颜色值修改为依此递增的白色。因为纯白色的颜色值为0xffffff(红绿蓝三色的值必须相等,否则将会呈现三者之中值较大的那种颜色,而且三者的值越大,越加趋向于纯白色),所以调色板中的24位色是从010101,020202,030303,…,ffffff依次递增的256种、从灰色到纯白色的颜色值。

原始图片如下:

在这里插入图片描述

结果示例:

在这里插入图片描述

涉及到的gamma矫正算法如下:

在这里插入图片描述

反色灰度图片效果:

即将上述灰度颜色值取反后的结果。 在这里插入图片描述

若是颜色表中不是这种排序,将会导致的结果如下(以绿色蓝色分量为0为例子):

在这里插入图片描述

位图像素块移动

使用代码实现区域像素的平移、在bmp图像中画白色矩形的操作。

因为一般的bmp文件是倒序存放的,即显示时的第一行位于位图数据文件的最后一行,最后一行位于位图文件的第一行中。为了操作和计算方便,需要将位图中扫描线翻转,操作之后,再将像素的扫描线翻转回去。具体实现看代码。

区域平移效果示例:

在这里插入图片描述

画矩形的效果示例:

在这里插入图片描述

平移并画矩形的效果示例:

在这里插入图片描述

旋转操作:

在这里插入图片描述

使用的矩阵乘法,旋转15度。仅仅出于图形学演示效果,未做优化,所以效果不佳。

使用了如下矩阵实现像素旋转:

∣ n e w x n e w y ∣ = ∣ cos ⁡ β − sin ⁡ β sin ⁡ β cos ⁡ β ∣ ∣ x y ∣ \begin {vmatrix} new_x \\ new_y \end {vmatrix} = \begin {vmatrix} \cos \beta & -\sin \beta \\ \sin \beta& \cos \beta \end {vmatrix} \begin {vmatrix} x \\ y \end {vmatrix} ​newx​newy​​ ​= ​cosβsinβ​−sinβcosβ​ ​ ​xy​ ​

图片合成:

背景图:

在这里插入图片描述

使用如下算法: c o l o r = c o l o r ∗ a l p h a + c o l o r 2 ∗ ( 1 − a l p h a ) 0 < a l p h a < 1 color = color* alpha + color2*(1-alpha) \quad \quad 0biWidth*( bi->biBitCount/8); for (int j = 0;j biWidth;j++) { if (bi->biBitCount == 8) { } else if (bi->biBitCount == 16) { } else if (bi->biBitCount == 24) { ULONG v = line[j*3] + line[j*3 + 1] + line[j * 3 + 2]; nd[nd_size++] = v/3; } else if (bi->biBitCount == 32) { ULONG v = line[j * 4] + line[j * 4 + 1] + line[j * 4 + 2] + line[j * 4 + 3]; nd[nd_size++] =v/4; } } } nd_bi->biBitCount = 8; nd_bi->biSizeImage = bi->biHeight*bi->biWidth; nd_bf->bfSize = nd_size; nd_bf->bfOffBits += 1024; ret = FileHelper::fileWriter("mandrill_new.bmp", nd, nd_bf->bfSize,TRUE); char* framedata = new char[nd_bf->bfSize + 1024]; memcpy(framedata, nd, nd_bf->bfSize); reverseBmp(nd + nd_bf->bfOffBits, nd_bi->biHeight, nd_bi->biWidth); ret = FileHelper::fileWriter("mandrill_new_2.bmp", nd, nd_bf->bfSize, TRUE); frame(framedata + nd_bf->bfOffBits, nd_bi->biHeight, nd_bi->biWidth,100,50); ret = FileHelper::fileWriter("mandrill_new_3.bmp", framedata, nd_bf->bfSize, TRUE); char* rotatesrc = new char[bf->bfSize + 1024]; char* rotatedata = new char[bf->bfSize + 1024]; memcpy(rotatesrc, file, bf->bfSize); rotate(rotatesrc + bf->bfOffBits, bi->biHeight, bi->biWidth,bi->biBitCount/8, rotatedata); memcpy(rotatesrc + bf->bfOffBits, rotatedata, bi->biSizeImage); ret = FileHelper::fileWriter("mandrill_new_4.bmp", rotatesrc, bf->bfSize, TRUE); } } return 0; } int main() { int ret = 0; ret = mainproc(); return 0; }

工程代码如下:

https://download.csdn.net/download/m0_37567738/88571695

注意:为防止某些版本的VS编译错误,编译时在“设置”->“c++”->“预处理器”->“预处理器定义”中添加” _CRT_SECURE_NO_WARNINGS”

三 参考链接 c++将24位bmp转8位bmp灰度, 8位bmp灰度反色,24位转3张8位bmp灰度图bmp文件结构


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有