c语言实现BMP图像转换为灰度图

当初是自己要装X,非要用c来写信息隐藏作业,装了X,就得付出实践。查了好久资料,到期末才把作业交了,这里总结一下。

这道题是将真彩图转换为灰度图

  • 关于BMP文件结构,这是困扰了我好久的问题,上网查了很久图片的知识才弄明白
  • BMP文件包括以下几部分(具体结构在程序中说明):
    • 位图文件头
    • 位图信息头
    • 调色板
    • 位图数据
  • 结构体内存对齐原则
    • 每个成员存储的起始位置要从该成员大小的整数倍开始
    • 成员是结构体时相对与起始偏移是其内部最大元素大小的整数倍
    • 结构体的总大小是其内部最大成员的整数倍
  • 因此在定义头结构的时候要加上#pragma pack(1),设置以1字节为对齐方式,不然后面数据会错位
  1 /*
  2 真彩图转换成灰度图的改进版
  3 (不把真彩图的每个像素点放入二维矩阵,而是读一行写一行)
  4 blog:http://www.cnblogs.com/wd1001/
  5 2015年6月2日19:04:09
  6 */
  7 #include<stdio.h>
  8 #include<malloc.h>
  9 #include<stdlib.h>
 10 /*
 11 位图头结构
 12 */
 13 #pragma pack(1)
 14 typedef struct tagBITMAPFILEHEADER
 15 {
 16     unsigned char bfType[2];//文件格式
 17     unsigned long bfSize;//文件大小
 18     unsigned short bfReserved1;//保留
 19     unsigned short bfReserved2;
 20     unsigned long bfOffBits; //DIB数据在文件中的偏移量
 21 }fileHeader;
 22 #pragma pack()
 23 /*
 24 位图数据信息结构
 25 */
 26 #pragma pack(1)
 27 typedef struct tagBITMAPINFOHEADER
 28 {
 29     unsigned long biSize;//该结构的大小
 30     long biWidth;//文件宽度
 31     long biHeight;//文件高度
 32     unsigned short biPlanes;//平面数
 33     unsigned short biBitCount;//颜色位数
 34     unsigned long biCompression;//压缩类型
 35     unsigned long biSizeImage;//DIB数据区大小
 36     long biXPixPerMeter;
 37     long biYPixPerMeter;
 38     unsigned long biClrUsed;//多少颜色索引表
 39     unsigned long biClrImporant;//多少重要颜色
 40 }fileInfo;
 41 #pragma pack()
 42 /*
 43 调色板结构
 44 */
 45 #pragma pack(1)
 46 typedef struct tagRGBQUAD
 47 {
 48     unsigned char rgbBlue; //蓝色分量亮度
 49     unsigned char rgbGreen;//绿色分量亮度
 50     unsigned char rgbRed;//红色分量亮度
 51     unsigned char rgbReserved;
 52 }rgbq;
 53 #pragma pack()
 54
 55 int main()
 56 {
 57     /*存储RGB图像的一行像素点*/
 58     unsigned char ImgData[3000][3];
 59     /*将灰度图的像素存到一个一维数组中*/
 60     unsigned char ImgData2[3000];
 61     int i,j,k;
 62     FILE * fpBMP,* fpGray;
 63     fileHeader * fh;
 64     fileInfo * fi;
 65     rgbq * fq;
 66
 67     if((fpBMP=fopen("G:/vc6.0/work/21.bmp","rb"))==NULL)
 68     {
 69         printf("打开文件失败");
 70         exit(0);
 71     }
 72
 73     if((fpGray=fopen("G:/vc6.0/work/22.bmp","wb"))==NULL)
 74     {
 75         printf("创建文件失败");
 76         exit(0);
 77     }
 78
 79     fh=(fileHeader *)malloc(sizeof(fileHeader));
 80     fi=(fileInfo *)malloc(sizeof(fileInfo));
 81     //读取位图头结构和信息头
 82     fread(fh,sizeof(fileHeader),1,fpBMP);
 83     fread(fi,sizeof(fileInfo),1,fpBMP);
 84     //修改头信息
 85     fi->biBitCount=8;
 86     fi->biSizeImage=( (fi->biWidth*3+3)/4 ) * 4*fi->biHeight;
 87     //fi->biClrUsed=256;
 88
 89     fh->bfOffBits = sizeof(fileHeader)+sizeof(fileInfo)+256*sizeof(rgbq);
 90     fh->bfSize = fh->bfOffBits + fi->biSizeImage;
 91
 92     //创建调色版
 93     fq=(rgbq *)malloc(256*sizeof(rgbq));
 94     for(i=0;i<256;i++)
 95     {
 96         fq[i].rgbBlue=fq[i].rgbGreen=fq[i].rgbRed=i;
 97         //fq[i].rgbReserved=0;
 98     }
 99     //将头信息写入
100     fwrite(fh,sizeof(fileHeader),1,fpGray);
101     fwrite(fi,sizeof(fileInfo),1,fpGray);
102     fwrite(fq,sizeof(rgbq),256,fpGray);
103     //读取RGB图像素并转换为灰度值
104     for ( i=0;i<fi->biHeight;i++ )
105     {
106         for(j=0;j<(fi->biWidth+3)/4*4;j++)
107         {
108             for(k=0;k<3;k++)
109                 fread(&ImgData[j][k],1,1,fpBMP);
110         }
111         for(j=0;j<(fi->biWidth+3)/4*4;j++)
112         {
113             ImgData2[j]=int( (float)ImgData[j][0] * 0.114 +
114                         (float)ImgData[j][1] * 0.587 +
115                         (float)ImgData[j][2] * 0.299 );
116         }
117         //将灰度图信息写入
118         fwrite(ImgData2,j,1,fpGray);
119     }
120
121         free(fh);
122         free(fi);
123         free(fq);
124         fclose(fpBMP);
125         fclose(fpGray);
126         printf("success\n");
127         return 0;
128 }

结果:

时间: 2024-12-24 12:02:28

c语言实现BMP图像转换为灰度图的相关文章

从视频文件中读入数据--&gt;将数据转换为灰度图--&gt;对图像做candy边缘检测

//从视频文件中读入数据-->将数据转换为灰度图-->对图像做candy边缘检测 //作者:sandy //时间:2015-10-10 #include <cv.h> #include <highgui.h> int main(int argc, char *argv[]){ //预备工作 CvCapture* capture=cvCreateFileCapture("E:\\Videos\\xx.avi");//让capture变量指向视频文件 i

机器学习进阶-图像基本处理-视频的读取与处理 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()  #进行单张图片的读取,ret的值为True或者Flase, frame表示读入的图片 4.cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  #表示将图片转换为灰度图 代码: import cv2 vc = cv2.VideoCapture('test.mp4')

mupdf实现常用图片转换为灰度图pnm

我要实现的工作是使用mupdf库转换pdf.jpeg.tif等文件为灰度图,转换完成的灰度图存放到内存中,而不是存为文件,在读取到内存中,主要是嵌入式系统中使用.下面是example.c,我加了我理解的注释,以及自己修改的地方.example.c全文 #include <mupdf/fitz.h> void render(char *filename, int pagenumber, int zoom, int rotation) { // Create a context to hold t

Qt 中彩色图像转换为灰度图

最近在做几个图像处理相关的项目.里面有一个操作就是需要先将彩色图像转换为灰度图像.QImage 有一个convertToFormat方法.最开始一直用这个函数来实现.但是今天仔细看了看,发现这个函数转换出的灰度图与原始图像的亮度似乎是有区别的.比如说下面这副图像: 用下面这三行代码转换: QImage image2 = image.convertToFormat(QImage::Format_Indexed8); image2.setColorCount(256); for(int i = 0;

RGB图像转为灰度图

最后结论: Grey = (R*38 + G*75 + B*15)>> 7 代码 #include <cv.h> #include <highgui.h> using namespace cv; int main(){ Mat src= imread("C:\\Users\\Poplar\\Pictures\\ff.jpg"); Matgrey(src.rows, src.cols, CV_8UC1, Scalar(0)); for (inty =

如何使用 python3 将RGB 图片转换为 灰度图

首先,介绍第一种方法, 使用  PIL  库,   PIL库是一种python语言常用的一个图形处理库. 关于   PIL  库的安装本文就不介绍了. from PIL import Image I = Image.open('C:\\Users\\Administrator\\Desktop\\照片\\timg.jpg') I.show() L = I.convert('L') L.show()L.save('C:\\Users\\Administrator\\Desktop\\照片\\tim

C# (灰度)加权平均法将图片转换为灰度图

private Bitmap ToG(string file) { using (Bitmap o = new Bitmap(file)) { Bitmap g = new Bitmap(o.Width, o.Height); for (int i = 0; i < o.Width; i++) { for (int j = 0; j < o.Height; j++) { Color c = o.GetPixel(i, j); //灰度加权平均法公式 int rgb = (int)(c.R *

怎么样用opencv将彩色图片转化成像素值只有0和255的灰度图?

  分类: OpenCV [Q1]怎么样用opencv将彩色图片转化成像素值只有0和255的灰度图? 进行灰度化,IplImage* pImg = cvLoadImage( "C:\\1.bmp", 0 ); 这样图像已经灰度化,然后调用cvThreshold(image, image, 125, 255, CV_THRESH_BINARY); 就可以了,125那里是你所用的阈值,这就是最简单的二值化,你要用ostu,或者别的高级一点的,就要自己写函数了   // Truncate v

彩色图到灰度图究竟是怎么变换的

??之前对彩色图与灰度图仅仅停留在前者是3通道后者是单通道的理解上.我也知道计算机看图片是将它们当成数组,但是一直搞不清楚将一张彩色图转变为灰度图是怎么操作的.当然,很多库函数都提供借口,包括OpenCV.PIL等.这里我参考https://blog.csdn.net/saltriver/article/details/79677116 手动实现将一张彩色图转换为灰色图.当然还是以帅气的哈士奇.jpg作为我的练习对象,看到它敲代码都有动力. from PIL import Image impor