当初是自己要装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图像转换为灰度图的更多相关文章

  1. 【Python开发】python PIL读取图像转换为灰度图及另存为其它格式(也可批量改格式)

    例如有一幅图,文件名为"a.jpg'.  读取: from PIL import Image #或直接import Image im = Image.open('a.jpg') 将图片转换成 ...

  2. 从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中

    //从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中 //作者:sandy //时间:2015-10-10 #inclu ...

  3. 机器学习进阶-图像基本处理-视频的读取与处理 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( ...

  4. Android-将RGB彩色图转换为灰度图

    package com.example.yanlei.wifi; import android.graphics.Bitmap; import android.graphics.BitmapFacto ...

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

    近期在做几个图像处理相关的项目.里面有一个操作就是须要先将彩色图像转换为灰度图像. QImage 有一个convertToFormat方法.最開始一直用这个函数来实现. 可是今天细致看了看,发现这个函 ...

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

    首先,介绍第一种方法, 使用  PIL  库,   PIL库是一种python语言常用的一个图形处理库. 关于   PIL  库的安装本文就不介绍了. from PIL import Image I ...

  7. Android 将ARGB图片转换为灰度图

    思路如下: 1.读取or照相,得到一张ARGB图片. 2.转化为bitmap类,并对其数据做如下操作: A通道保持不变,然后逐像素计算:X = 0.3×R+0.59×G+0.11×B,并使这个像素的值 ...

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

    private Bitmap ToG(string file) { using (Bitmap o = new Bitmap(file)) { Bitmap g = new Bitmap(o.Widt ...

  9. [Xcode 实际操作]六、媒体与动画-(2)使用图形上下文转换图片为灰度图

    目录:[Swift]Xcode实际操作 本文将演示如何将图片转换为灰度图. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit class V ...

随机推荐

  1. 两个bootstrap插件bootstrap-select和bootstrap-paginator

    基于bootstrap的选择器 http://silviomoreto.github.io/bootstrap-select/ <label for="androids" c ...

  2. 乱译文档--开始使用Musca

    原文地址:http://aerosuidae.net/musca_start.html aerosuidae.net Musca - Start Using startx Launch it from ...

  3. 尚学堂 JAVA DAY11 概念总结

    1.冒泡排序算法 <升序排列> 思路1: 数组长度为n,那么要对数组进行n-1次遍历; step 1---从数组的第一个数开始,两两比较,如果第一个数 > 第二个数,将二者进行交换: ...

  4. java文件(文件夹)操作

    java中文件操作 判断是否为文件file.isFile()方法 判断是否为目录file.isDirectory()方法 判断是否存在file.exist()方法 创建新文件file.createNe ...

  5. wxPython跨线程调用

    版权所有,转载请注明出处:http://guangboo.org/2013/08/23/wxpython-non-gui-thread-call-gui-method 之前有介绍了<wxPyth ...

  6. Java笔记6之三目运算符

    /*    单目运算符:~3    双目运算符:3 + 4    三目运算符:        格式:比较表达式?表达式1:表达式2;                比较表达式:结果是一个boolean ...

  7. SCGHR 分析思路

    -- 分析某个模块业务 a:添加表,登记表,历史表,信息表 --- (把表名搞清楚,再看具体的字段) 先搞清楚大概的数据流向,在着手具体的数据,大处布局,小处着手 b:表中的字段,以及各表直接传递什么 ...

  8. WIN32读写INI文件方法

      在程序中经常要用到设置或者其他少量数据的存盘,以便程序在下一次执行的时候可以使用,比如说保存本次程序执行时窗口的位置.大小.一些用户设置的 数据等等,在 Dos 下编程的时候,我们一般自己产生一个 ...

  9. Chapter 1. Introduction gradle介绍

      We would like to introduce Gradle to you, a build system that we think is a quantum leap for build ...

  10. UWP APP 开发日记

    最近需要使用C#开发UWP应用,以前学习过C,这回就是快速看了一下C#的一些特别之处,然后就进入到了实战练习当中. 1.按照MSDN的教程自己搭建了一个简单的“Hello, world”应用.是使用C ...