c语言实现BMP图像转换为灰度图
当初是自己要装X,非要用c来写信息隐藏作业,装了X,就得付出实践。查了好久资料,到期末才把作业交了,这里总结一下。
这道题是将真彩图转换为灰度图。
- 关于BMP文件结构,这是困扰了我好久的问题,上网查了很久图片的知识才弄明白
- BMP文件包括以下几部分(具体结构在程序中说明):
- 位图文件头
- 位图信息头
- 调色板
- 位图数据
- 结构体内存对齐原则对于pragma pack(n)
- 当成员大小小于n时,每个成员存储的起始位置要从该成员大小的整数倍开始,否则从n的整数倍开始
- 成员是结构体时相对于起始偏移是以其内部最大成员为准
- 当n大于内部最大成员时,结构体的总大小是其内部最大成员的整数倍反之为n的整数倍
- 32位默认n为4,64位默认为8
- 因此在定义头结构的时候要加上#pragma pack(1),设置以1字节为对齐方式,不然后面数据会错位
/*
真彩图转换成灰度图的改进版
(不把真彩图的每个像素点放入二维矩阵,而是读一行写一行)
blog:http://www.cnblogs.com/wd1001/
2015年6月2日19:04:09
*/
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
/*
位图头结构
*/
#pragma pack(1)
typedef struct tagBITMAPFILEHEADER
{
unsigned char bfType[];//文件格式
unsigned long bfSize;//文件大小
unsigned short bfReserved1;//保留
unsigned short bfReserved2;
unsigned long bfOffBits; //DIB数据在文件中的偏移量
}fileHeader;
#pragma pack()
/*
位图数据信息结构
*/
#pragma pack(1)
typedef struct tagBITMAPINFOHEADER
{
unsigned long biSize;//该结构的大小
long biWidth;//文件宽度
long biHeight;//文件高度
unsigned short biPlanes;//平面数
unsigned short biBitCount;//颜色位数
unsigned long biCompression;//压缩类型
unsigned long biSizeImage;//DIB数据区大小
long biXPixPerMeter;
long biYPixPerMeter;
unsigned long biClrUsed;//多少颜色索引表
unsigned long biClrImporant;//多少重要颜色
}fileInfo;
#pragma pack()
/*
调色板结构
*/
#pragma pack(1)
typedef struct tagRGBQUAD
{
unsigned char rgbBlue; //蓝色分量亮度
unsigned char rgbGreen;//绿色分量亮度
unsigned char rgbRed;//红色分量亮度
unsigned char rgbReserved;
}rgbq;
#pragma pack() int main()
{
/*存储RGB图像的一行像素点*/
unsigned char ImgData[][];
/*将灰度图的像素存到一个一维数组中*/
unsigned char ImgData2[];
int i,j,k;
FILE * fpBMP,* fpGray;
fileHeader * fh;
fileInfo * fi;
rgbq * fq; if((fpBMP=fopen("G:/vc6.0/work/21.bmp","rb"))==NULL)
{
printf("打开文件失败");
exit();
} if((fpGray=fopen("G:/vc6.0/work/22.bmp","wb"))==NULL)
{
printf("创建文件失败");
exit();
} fh=(fileHeader *)malloc(sizeof(fileHeader));
fi=(fileInfo *)malloc(sizeof(fileInfo));
//读取位图头结构和信息头
fread(fh,sizeof(fileHeader),,fpBMP);
fread(fi,sizeof(fileInfo),,fpBMP);
//修改头信息
fi->biBitCount=;
fi->biSizeImage=( (fi->biWidth*+)/ ) * *fi->biHeight;
//fi->biClrUsed=256; fh->bfOffBits = sizeof(fileHeader)+sizeof(fileInfo)+*sizeof(rgbq);
fh->bfSize = fh->bfOffBits + fi->biSizeImage; //创建调色版
fq=(rgbq *)malloc(*sizeof(rgbq));
for(i=;i<;i++)
{
fq[i].rgbBlue=fq[i].rgbGreen=fq[i].rgbRed=i;
//fq[i].rgbReserved=0;
}
//将头信息写入
fwrite(fh,sizeof(fileHeader),,fpGray);
fwrite(fi,sizeof(fileInfo),,fpGray);
fwrite(fq,sizeof(rgbq),,fpGray);
//读取RGB图像素并转换为灰度值
for ( i=;i<fi->biHeight;i++ )
{
for(j=;j<(fi->biWidth+)/*;j++)
{
for(k=;k<;k++)
fread(&ImgData[j][k],,,fpBMP);
}
for(j=;j<(fi->biWidth+)/*;j++)
{
ImgData2[j]=int( (float)ImgData[j][] * 0.114 +
(float)ImgData[j][] * 0.587 +
(float)ImgData[j][] * 0.299 );
}
//将灰度图信息写入
fwrite(ImgData2,j,,fpGray);
} free(fh);
free(fi);
free(fq);
fclose(fpBMP);
fclose(fpGray);
printf("success\n");
return ;
}
结果:


c语言实现BMP图像转换为灰度图的更多相关文章
- 【Python开发】python PIL读取图像转换为灰度图及另存为其它格式(也可批量改格式)
例如有一幅图,文件名为"a.jpg'. 读取: from PIL import Image #或直接import Image im = Image.open('a.jpg') 将图片转换成 ...
- 从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中
//从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中 //作者:sandy //时间:2015-10-10 #inclu ...
- 机器学习进阶-图像基本处理-视频的读取与处理 1.cv2.VideoCapture(视频的载入) 2.vc.isOpened(载入的视频是否可以打开) 3.vc.read(视频中一张图片的读取) 4.cv2.cvtColor(将图片转换为灰度图)
1.vc = cv2.VideoCapture('test.mp4') #进行视频的载入 2.vc.isOpened() # 判断载入的视频是否可以打开 3.ret, frame = vc.read( ...
- Android-将RGB彩色图转换为灰度图
package com.example.yanlei.wifi; import android.graphics.Bitmap; import android.graphics.BitmapFacto ...
- Qt 中彩色图像转换为灰度图
近期在做几个图像处理相关的项目.里面有一个操作就是须要先将彩色图像转换为灰度图像. QImage 有一个convertToFormat方法.最開始一直用这个函数来实现. 可是今天细致看了看,发现这个函 ...
- 如何使用 python3 将RGB 图片转换为 灰度图
首先,介绍第一种方法, 使用 PIL 库, PIL库是一种python语言常用的一个图形处理库. 关于 PIL 库的安装本文就不介绍了. from PIL import Image I ...
- Android 将ARGB图片转换为灰度图
思路如下: 1.读取or照相,得到一张ARGB图片. 2.转化为bitmap类,并对其数据做如下操作: A通道保持不变,然后逐像素计算:X = 0.3×R+0.59×G+0.11×B,并使这个像素的值 ...
- C# (灰度)加权平均法将图片转换为灰度图
private Bitmap ToG(string file) { using (Bitmap o = new Bitmap(file)) { Bitmap g = new Bitmap(o.Widt ...
- [Xcode 实际操作]六、媒体与动画-(2)使用图形上下文转换图片为灰度图
目录:[Swift]Xcode实际操作 本文将演示如何将图片转换为灰度图. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit class V ...
随机推荐
- BZOJ 1021 [SHOI2008]Debt 循环的债务
1021: [SHOI2008]Debt 循环的债务 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 694 Solved: 356[Submit][S ...
- android sudio 记录
1. KVM is not installed on this machine (/dev/kvm is missing) 原文网址:http://askubuntu.com/questions/56 ...
- word页面不对齐,如何解决?
http://blog.163.com/haibianfeng_yr/blog/static/34572620201157105439516/
- STL_iterator迭代器(2)——几种迭代器对象的用法
要学会使用迭代器和容器以及算法,需要学习下面的新技术. 一.流和迭代器 本书的很多例子程序使用I/O流语句来读写数据.例如: int value; cout << "Enter ...
- Hadoop操作hdfs的命令【转载】
本文系转载,原文地址被黑了,故无法贴出原始链接. Hadoop操作HDFS命令如下所示: hadoop fs 查看Hadoop HDFS支持的所有命令 hadoop fs –ls 列出目录及文件信息 ...
- C++ 通过Thunk在WNDPROC中访问this指针实现细节
本文代码使用了一些C++11特性,需要编译器支持.本文仅讨论x86_64平台的相关实现,x86平台理论上只需修改 thunk 相关机器码即可. THUNK的原理参见之前的一篇博文<C++ 通过T ...
- compile libvirt
POSIX-linux 编译安装libvirt依赖包; 1.yum install device-mapper-devel
- OpenStack入门之初步认识
一.OpenStack 入门 之 基础知识 二.OpenStack 入门 之 基本组件 三.OpenStack 入门 之 各组件解析(基础) 四.OpenStack 入门 之 各组件解析(进阶) 五. ...
- oracle防火墙端口问题
Oracle服务端口方面会有很多的问题,下面就将为您介绍在防火墙上开放Oracle服务端口的方法,希望对您学习Oracle服务端口方面能有所帮助. 要使Oracle客户端能正常连接到设置有防火墙的安装 ...
- QE是什么
量化宽松(Quantitative Easing,简称QE),是一种货币政策,主要指各国央行通过公开市场购买政府债券.银行金融资产等做法.量化宽松直接导致市场的货币供应量增加,可视为变相“印钞”.市场 ...