C++实现彩色bmp图片转灰度图

news2024/11/18 2:35:05

简介

BMP(全称Bitmap)是Windows操作系统中的标准图像文件格式,可以分成两类:设备相关位图(DDB)和设备无关位图(DIB),使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。BMP位图文件默认的文件扩展名是BMP或者bmp。

BMP图片格式

BMP文件总体上由4部分组成,分别是位图文件头、位图信息头、调色板和图像数据

位图文件头(bitmap-file header)

BMP文件头数据结构共14个字节,包含以下信息:

typedef struct{
    unsigned short bfType;                            //文件类型,具体值为0x4D42
    int bfSize;                                        //文件大小,以字节为单位
    unsigned short bfReserved1;                       //保留值,必须为0
    unsigned short bfReserved2;                       //保留值,必须为0
    int bfOffBits;                                     //从文件开头到具体图像数据的字节偏移量(具体文件头(14byte)+位图信息头(40byte)+调色板)
}BITMAPFILEHEADER;

位图信息头(bitmap-information header)

图片信息头(40字节)存储着图像的尺寸,颜色索引,位平面数等信息,其结构体包括:


typedef struct{
   unsigned int biSize;                           //位图信息头的大小,均为40字节
   int biWidth;                                    //位图宽度,单位为像素
   int biHeight;                                   //位图高度,单位为像素
   unsigned short biPlanes;                      //位图的平面数,设置为1
   unsigned short biBitCount;                    //像素位数,有1,4,8,16,24,32等
   unsigned int biCompression;                   //位图压缩类型,0为不压缩、1为BI_RLE8、2为BI_RLE4(30-33)
   unsigned int    biSizeImage;                  //图像数据部分大小,等于bfSize-bfOffBits (34-37)
   int     biXPelsPerMeter;                       // 用像素/米表示的水平分辨率
   int     biYPelsPerMeter;                       // 用像素/米表示的垂直分辨率
   unsigned int    biClrUsed;                    // 调色板中的颜色索引数,0为图片有调色板
   unsigned int    biClrImportant;               // 重要颜色索引的数目,0表示都重要(50-53)
}BITMAPINFOHEADER;

彩色表/调色板(color table)

调色板,由颜色索引数决定【可以没有该项数据结构】

typedef struct
{
    unsigned char rgbBlue;  //蓝色分量亮度
    unsigned char rgbGreen; //绿色分量亮度
    unsigned char rgbRed;   //红色分量亮度
    unsigned char rgbReserved;
}RGBQUAD;

位图数据(bitmap-data)

位图数据记录了位图的每一个像素值。
像素是从下到上、从左到右保存的
每个像素使用一个或者多个字节表示。
如果一个图像水平线的字节数不是4的倍数,这行就使用空字节补齐,通常是ASCII码0。
如果图片是24位的彩色图,则RGB的顺序为B0G0R0B1G1R1…。

代码编写

本代码实现彩色图转灰度图的功能。

#include<stdio.h>
#pragma pack(1)
typedef struct{
    unsigned short bfType;                            //文件类型,具体值为0x4D42
    int bfSize;                                        //文件大小,以字节为单位
    unsigned short bfReserved1;                       //保留值,必须为0
    unsigned short bfReserved2;                       //保留值,必须为0
    int bfOffBits;                                     //从文件开头到具体图像数据的字节偏移量(具体文件头(14byte)+位图信息头(40byte)+调色板)
}BITMAPFILEHEADER;

typedef struct{
   unsigned int biSize;                           //位图信息头的大小,均为40字节
   int biWidth;                                    //位图宽度,单位为像素
   int biHeight;                                   //位图高度,单位为像素
   unsigned short biPlanes;                      //位图的平面数,设置为1
   unsigned short biBitCount;                    //像素位数,有1,4,8,16,24,32等
   unsigned int biCompression;                   //位图压缩类型,0为不压缩、1为BI_RLE8、2为BI_RLE4(30-33)
   unsigned int    biSizeImage;                  //图像数据部分大小,等于bfSize-bfOffBits (34-37)
   int     biXPelsPerMeter;                       // 用像素/米表示的水平分辨率
   int     biYPelsPerMeter;                       // 用像素/米表示的垂直分辨率
   unsigned int    biClrUsed;                    // 调色板中的颜色索引数,0为图片有调色板
   unsigned int    biClrImportant;               // 重要颜色索引的数目,0表示都重要(50-53)
}BITMAPINFOHEADER;

typedef struct
{
    unsigned char rgbBlue;  //蓝色分量亮度
    unsigned char rgbGreen; //绿色分量亮度
    unsigned char rgbRed;   //红色分量亮度
    unsigned char rgbReserved;
}RGBQUAD;

void showbmp(BITMAPFILEHEADER bmp){
   printf("****************************************文件头信息打印*******************************************************\n");
   printf("文件类型:%x\n",bmp.bfType);
   printf("文件大小=%d\n",bmp.bfSize);
   printf("文件保留值1=%d\n",bmp.bfReserved1);
   printf("文件保留值2=%d\n",bmp.bfReserved2);
   printf("文件信息区的大小=%d\n",bmp.bfOffBits);
}

void showbmpinfo(BITMAPINFOHEADER info){
   printf("结构体大小=%d\n",info.biSize);
   printf("图像宽=%d\n",info.biWidth);
   printf("图像高=%d\n",info.biHeight);
   printf("图像位面数=%d\n",info.biPlanes);
   printf("像素位数=%d\n",info.biBitCount);
   printf("位图压缩类型:%d\n",info.biCompression);
   printf("图像数据部分大小:%d\n",info.biSizeImage);
   printf("水平分辨率:%d\n",info.biXPelsPerMeter);
   printf("垂直分辨率:%d\n",info.biYPelsPerMeter);
   printf("位图颜色表中的颜色数:%d\n",info.biClrUsed);
   printf("重要颜色索引的数目:%d\n",info.biClrImportant);
}

int main(){
    BITMAPFILEHEADER bmp;
    BITMAPINFOHEADER bmp_info;
    //
    FILE* fp1;
    FILE* fp2;
    fp1=fopen("C:\\Users\\qjm\\Desktop\\test.bmp","rb");
    fread(&bmp,14,1,fp1);
    fread(&bmp_info,40,1,fp1);
    //show infomation
    showbmp(bmp);
    showbmpinfo(bmp_info);
    //
    int lineByte=(bmp_info.biWidth*3+3)/4*4;                 //4字节对齐后一行的字节数,单位字节
    int lineByte_gray=(bmp_info.biWidth+3)/4*4;
    printf("lineByte=%d\n",lineByte);
    printf("lineByte_gray=%d\n",lineByte_gray);
    //
    unsigned char* src_img=new unsigned char[bmp_info.biSizeImage];
    unsigned char* dest_img=new unsigned char[bmp_info.biSizeImage/3];
    fread(src_img,1,bmp_info.biSizeImage,fp1);
    for(int i=0;i<bmp_info.biHeight;i++)
        for(int j=0;j<bmp_info.biWidth;j++){
            unsigned char b=src_img[i*lineByte+j*3+0];
            unsigned char g=src_img[i*lineByte+j*3+1];
            unsigned char r=src_img[i*lineByte+j*3+2];
            unsigned char gray=((unsigned int)r+(unsigned int)g+(unsigned int)b)/3;
            dest_img[i*lineByte_gray+j]=gray;
    }
    fclose(fp1);
    //
    printf("****************************************************************\n");
    RGBQUAD* pRgbQuards=new RGBQUAD[256];
	for(int i=0;i<256;i++)
	{
		pRgbQuards[i].rgbBlue=i;
		pRgbQuards[i].rgbRed=i;
		pRgbQuards[i].rgbGreen=i;

	}
    fp2=fopen("C:\\Users\\qjm\\Desktop\\test_out.bmp","wb");
    bmp_info.biBitCount=24/3;
    bmp_info.biSizeImage=bmp_info.biSizeImage/3;
    bmp.bfOffBits=14+40+256*sizeof(RGBQUAD);                         //增加了颜色表
    bmp.bfSize=bmp.bfOffBits+bmp_info.biSizeImage;
    //
    showbmp(bmp);
    showbmpinfo(bmp_info);
    //
    fwrite(&bmp,1,14,fp2);
    fwrite(&bmp_info,1,40,fp2);
    fwrite(pRgbQuards,1,256*sizeof(RGBQUAD),fp2);
    fwrite(dest_img,1,bmp_info.biSizeImage,fp2);
    fclose(fp2);
    return 0;
}

待测试图片:
在这里插入图片描述
转灰度图后的效果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/55147.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第05章_存储引擎

第05章_存储引擎1. 查看存储引擎2. 设置系统默认的存储引擎3. 设置表的存储引擎3.1 创建表时指定存储引擎3.2 修改表的存储引擎4. 引擎介绍4.1 InnoDB 引擎:具备外键支持功能的事务存储引擎4.2 MyISAM 引擎:主要的非事务处理存储引擎4.3 Archive 引擎:用于数据存档4.4 Blackhol…

认真过一遍webpack

1. 简介 Webpack 是 前端资源打包工具&#xff0c;它会根据模块之间的依赖关系进行静态分析&#xff0c;将模块按照指定的规则生成对应的静态资源。 webpack会从入口文件开始打包&#xff0c;先形成依赖关系图&#xff0c;根据依赖图把不同的资源引进来形成一个chunk代码块&a…

Flutter 这个评分组件用起来真香

前言 在很多应用中,我们都需要收集用户的评分,比如商品满意度、配送满意度、应用使用体验等等。评分组件通常会是下面这样,一般满分是5分。 不过,有时候评分组件也会有一些特殊性(都怪产品的想法太多)。比如要求支持0.5分的评分,比如对不同的满意度使用不同的图标,再…

vscode - vscode中使用svn插件进行提交代码

本文介绍工作中在vscode上使用svn插件进行提交代码&#xff1b; 前提&#xff1a;自己需要安装svn服务端和客户端&#xff08;小乌龟&#xff09; svn服务端链接&#xff1a;https://www.visualsvn.com/server/download/ svn客户端链接&#xff1a;https://tortoisesvn.net/dow…

守护安全|AIRIOT城市天然气综合管理解决方案

城市使用天然气存在安全风险和隐患&#xff0c;天然气管理的复杂性也比较高&#xff0c;依靠传统人工难以发现安全漏洞&#xff0c;特别是在燃气场站、管网的安全监管等方面&#xff0c;场站面临作业管理、区域管控等问题&#xff0c;管线存在第三方施工发现问题不及时、监管难…

Java实战-用Java mail实现Exchange发邮件给你喜欢的人

目录1. 官方指导文章2. 需要用到com.microsoft.ews-java-api2.1 maven中添加2.2 gradle中添加3. 完整代码&#xff1a;新建一个MailUtil.java类&#xff1a;如何用java mail 实现Exchange发邮件的功能 1. 官方指导文章 官方文章&#xff1a;https://github.com/OfficeDev/ews…

设计模式(下)

四、行为型模式 4.1 模板方法模式 4.1.1 概述 在面向对象程序设计过程中&#xff0c;程序员常常会遇到这种情况&#xff1a;设计一个系统时知道了算法所需的关键步骤&#xff0c;而且确定了这些步骤的执行顺序&#xff0c;但某些步骤的具体实现还未知&#xff0c;或者说某些…

swin Transformer

文章目录swin Transformer创新点&#xff1a;网络架构&#xff1a;Patch Partitionlinear EmbeddingSwin TransformerPatch Merging总结swin Transformer 论文&#xff1a;https://arxiv.org/pdf/2103.14030.pdf 代码&#xff1a;https://github.com/microsoft/Swin-Transfor…

基于FDB方法的供给需求优化算法改进——基于工程设计问题的综合研究

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

校园网页设计成品 学校班级网页制作模板 dreamweaver网页作业 简单网页课程成品 大学生静态HTML网页源码

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

ArangoDB简单入门

一、安装与启动 1、进入到某个目录 cd /home/neunhoef/ 2 获取包 wget https://download.arangodb.com/arangodb34/Community/Linux/arangodb3-linux-3.4.1.tar.gz 3、解压 tar xzvf arangodb3-linux-3.4.1.tar.gz 4、将使用的命令放到path中 export PATH"/home/neunhoef…

Ajax学习:原生jsonp实践

输入内容&#xff1a;丧失焦点 向服务器发送请求 对用户名做是否存在的检测 并且改变框的颜色 服务端&#xff1a; const {json } require(express); const express require(express)const app express(); app.get(/home, function(requset, response) {//设置响应头 名称…

分布式全局唯一ID (学习总结---从入门到深化)

目录 分布式全局唯一ID 何为 ID 为什么需要分布式ID 分布式全局唯一ID解决方案 UUID 依靠数据库自增字段生成 号段模式 Redis自增key方案 雪花算法&#xff08;SnowFlake&#xff09; 分布式全局唯一ID_什么是雪花算法SonwFlake 雪花算法作用 SnowFlake算法优点 SnowFlake…

【flutter-mobx】Flutter 状态管理- 使用 MobX实现计数器

实践flutter mobx&#xff1a; 提示&#xff1a;对下面这篇掘金文章的实践&#xff0c;通过flutter结合 mobx 实现计数器&#xff0c;过程中也添加了一些处理和注释&#xff0c;代码放在feat/mobx下 https://juejin.cn/post/6954523549386162213 https://github.com/ThinkerW…

论算法是如何优化的:四数之和

论算法是如何优化的&#xff1a;四数之和 心路历程 闲来无事&#xff0c;刷刷力扣&#xff0c;突然看到一道题目叫做四数之和&#xff0c;难度中等&#xff0c;心想&#xff0c;这不就是我大显身手的时候了吗&#xff1f;&#xff1f;&#xff1f;我直接就是一个点击进入&…

2022 CMU15-445 Project 1 Buffer Pool

通过截图 Task #1 - Extendible Hash Table 该 task 的知识点名为 可扩展动态散列 https://cloud.tencent.com/developer/article/1020586 这个部分要实现一个 extendible 哈希表&#xff0c;内部不可以用 built-in 的哈希表&#xff0c;比如 unordered_map。这个哈希表在 Buf…

Open-Dis的C++版本编译(CMake-gpu 3.21.4)以及SDL2和SDL_net库的配置使用

目录Open-DisOpen-Dis简介分布式交互仿真更多资料Open-Dis下载CMake编译教程SDL2和SDL_netSDL介绍下载SDL配置SDL2下载SDL_net配置SDL_net工程编译Open-DisOpen-Dis Open-Dis简介 Dis是国防部&#xff0c;北约和联合国实时/虚拟世界建模和仿真中使用最广泛的协议之一。 Open-…

关于二进制

关于二进制 读《程序是怎样跑起来的》 用二进制表示计算机信息的原因 计算机内部是由IC&#xff08;集成电路&#xff09;这种电子部件构成的。CPU和内存也是IC的一种&#xff0c;IC有几种不同的形状&#xff0c;有的像一条黑色的蜈蚣&#xff0c;在其两侧有数个乃至数百个引脚…

智慧水务:数字孪生污水处理厂,3D可视化一键管控

近年来&#xff0c;智慧水务、数字水务成为水务行业的热点领域。对于污水处理领域&#xff0c;如何贯彻落实双碳战略&#xff0c;积极推进智慧水厂建设&#xff0c;显得尤为关键。 可视化技术结合视频融合、BIM、5G、物联网、云计算及大数据等先进技术&#xff0c;围绕水质达标…

用DIV+CSS技术制作个人博客网站(web前端网页制作课期末作业)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…