24位bmp彩色图转换为24位灰度图的方法

一、所用到的流处理函数:

fstream:可同时进行读写操作的文件类;或

ofstream:写操作(从内存中读数据到文件)的文件类;

ifstream:读操作(从文件读数据到内存)的文件类。

二、位图文件的格式:

① 位图文件头,所用结构体:BITMAPFILEHEADER,占14个字节

② 位图信息头,所用结构体:BITMAPINFOHEADER,占40个字节

③ 颜色表项,所用结构体:RGBQUAD,由biBitCount值决定

④ 数据区,当结构体BITMAPINFOHEADER中的成员变量

biBitCount = 1时,1个字节代表8个像素;

biBitCount = 2时,1个字节代表2个像素;

biBitCount = 8时,1个字节代表1个像素;

biBitCount = 16时,2个字节代表1个像素;

biBitCount = 24时,3个字节代表1个像素;

RGBQUAD结构体的定义如下:

typedef struct tagRGBQUAD {
  BYTE    rgbBlue;                // 蓝色分量
  BYTE    rgbGreen;               // 绿色分量
  BYTE    rgbRed;                 // 红色分量
  BYTE    rgbReserved;            // 保留值,必须为0.
} RGBQUAD; 

即一个RGBQUAD结构体占4个字节,

当biBitCount = 1,2,4,8时,颜色表项分别占2,4,16,256个RGBQUAD结构体大小的空间;

当biBitCount = 24时,③颜色表项不占空间,即位图文件只有①②④三项,这是因为数据区中3个字节代表一个像素,本身含有三原色分量值。

三、需要注意的问题:

1. bmp数据存储时按行从左到右、按列从下到上扫描,所以对于24位bmp文件,数据区前三个字节代表位图左下角第一个元素;

2. bmp文件存储的图片数据每行所占的字节数都是4的整数倍,不够的用0补充,所以有

biSizeImage = ((((bi.Width*bitBitCount)+31)&~31)/8)*bi.biHeight

3. 对于24位bmp文件,若图片每行像素所占字节数满足是4的整数倍这个条件,由于BITMAPFILEHEADER和BITMAPINFOHEADER所占的总字节数为54,不是4的倍数,所以补0后为56字节。

四、方法一:

BOOL Cprogram2Dlg::RGB2GRAY(CString strPath)

{

fstream Infile;

fstream Outfile;

BITMAPFILEHEADER  bfheader = {0};

BITMAPINFOHEADER  biheader;

unsigned char *src;

unsigned char *dst;

// 打开与创建

Infile.open("In_Picture.bmp",ios::binary|ios::in);

Outfile.open("Out_ Picture.bmp",ios::binary|ios::out);

// 读取文件头与信息头

Infile.read((char*)& bfheader,sizeof(bmp_fileheader));

Infile.read((char*)& biheader,sizeof(bmp_infoheader));

// 开辟空间载入内存

src = new unsigned char[biheader.biHeight* biheader.biWidth*3];

Infile.read((char*)src,sizeof(unsignedchar)* biheader.biHeight* biheader.biWidth*3);

// 彩色转灰度像素处理,可在此加入图像处理算法

dst = new unsigned char[biheader.biHeight* biheader.biWidth*3];

int tmp;

unsigned long j = 0;

for (unsigned long i = 0;i < biheader.biHeight* biheader.biWidth*3;i += 3)

{

tmp = (src[i]+src[i+1]+src[i+2])/3;

dst[j++]=(unsigned char)tmp;

dst[j++]=(unsigned char)tmp;

dst[j++]=(unsigned char)tmp;

}

// 写文件头与信息头

Outfile.write((char*)& bfheader,sizeof(bmp_fileheader));

Outfile.write((char*)& biheader,sizeof(bmp_infoheader));

Outfile.write((char*)dst,sizeof(unsigned char)* biheader.biWidth* biheader.biHeight*3);

delete[] src;

delete[] dst;

return TRUE;

}

五、方法二:

BOOL Cprogram2Dlg::PictureProcessing(CString strPath)

{

//fstream input_file;

//fstream output_file;

bmp_fileheader  bfh = {0};

bmp_infoheader  bih;

unsigned char *src_buff;

unsigned char *dst_buff;

FILE *fpin = fopen("In_Picture.bmp","rb");

FILE *fpout = fopen("Out_Picture.bmp","wb");

if(fpin == NULL || fpout == NULL) return 0;

fread(&bfh,sizeof(bmp_fileheader),1,fpin);

fread(&bih,sizeof(bmp_infoheader),1,fpin);

src_buff = new unsigned char[bih.biHeight*bih.biWidth*3];

fread(src_buff,sizeof(unsigned char),bih.biHeight*bih.biWidth*3,fpin);

dst_buff = new unsigned char[bih.biHeight*bih.biWidth*3];

int tmp;

unsigned long j = 0;

for (unsigned long i = 0;i < bih.biHeight*bih.biWidth*3;i += 3)

{

tmp = (src_buff[i]+src_buff[i+1]+src_buff[i+2])/3;

dst_buff[j++]=(unsigned char)tmp;

dst_buff[j++]=(unsigned char)tmp;

dst_buff[j++]=(unsigned char)tmp;

}

fwrite(&bfh,sizeof(bmp_fileheader),1,fpout);

fwrite(&bih,sizeof(bmp_infoheader),1,fpout);

fwrite(dst_buff,sizeof(unsigned char),bih.biWidth*bih.biHeight*3,fpout);

delete[] src_buff;

delete[] dst_buff;

return TRUE;

}

时间: 2024-10-29 10:46:24

24位bmp彩色图转换为24位灰度图的方法的相关文章

将32位MD5摘要串转换为128位二进制字符串

将32为MD5摘要串转换为128位二进制字符串: 1 /// <summary> 2 /// 将字符串转成二进制 3 /// </summary> 4 /// <param name="s">源字符串</param> 5 /// <returns>二进制串</returns> 6 internal static string ConvertStringToBinary(string s) 7 { 8 if (s.I

八叉树算法将24位bmp图像转变为8位彩色图像

https://blog.csdn.net/r250tgc/article/details/89604254 #define _CRT_SECURE_NO_DEPRECATE #include <windows.h> #include <cstdio> #include <cmath> #include<iostream> #include<string.h> #include<cstring> using namespace std

8位灰度图在LCD上显示

一.概述 1.灰度 灰度使用黑色调表示物体,即用黑色为基准色,不同的饱和度的黑色来显示图像.每个灰度对象都具有从 0%(白色)到灰度条100%(黑色)的亮度值. 使用黑白或灰度扫描仪生成的图像通常以灰度显示. 像素值量化后用一个字节(8 bits)来表示.如把有黑-灰-白连续变化的灰度值量化为256个灰度级,灰度值的范围为0~255,表示亮度从深到浅,对应图像中的颜色为从黑到白.黑白照片包含了黑白之间的所有的灰度色调,每个像素值都是介于黑色和白色之间的256种灰度中的一种. 2.灰度图bmp文件

Unity Shaders and Effects Cookbook (2-4) 压缩和混合纹理贴图:使用灰度图存储插值信息

这一节看了几次才慢慢的读懂. 首先是这个灰度图,为什么叫灰度图,是因为 这个图片中的 R.G.B 存放的都是同一份数据,打开Unity 来调一下颜色看看 更直观. 可以看到,当 R.G.B 三个值相同的时候,图片是只有黑白,而丢失了其它的颜色的,所以我们叫灰度图. 什么时候用到灰度图? 本文转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn 比如说高度图,在这个坐标的点,海拔高,就记作 1,海拔低就记作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 =

opencv将图像转化为灰度图,然后边缘检测

1:代码如下: #include "stdafx.h" #include "highgui.h" #include "cv.h" #include "iostream" using namespace std; IplImage* doCanny(IplImage* in,double lowThresh,double highThresh,double aperture) { if(in->nChannels !=1)

C/C++ BMP(24位真彩色)图像处理(4)------图像の旋转

历经一个多月,CSDN貌似终于好像把文章列表阅读量信息归零BUG给修好了,于是乎放篇做期末大作业时写的文章上来测测效果,可别又像上次一样一发文章就又坑爹了啊! 本篇谈的是图像的旋转,不算是什么新鲜的题目了.但是现在由于很多工具如MATLAB.OPENCV等都把算法写好给用户调用,导致大多用户只知其然不知其所以然,所以回顾一下也是好的. 图像的旋转,说到底就是每个像素点绕着某个圆心旋转一定角度.如果是写代码的话,旋转的角度和圆心应该是已知的条件,我们第一个思路是根据已知条件求取出图像经过旋转后的新

【数字图像】C++8位和24位BMP位图的平滑、锐化、二值化处理,以及24位真彩图的灰度化

头文件: typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned int DWORD; typedef long LONG; //BMP文件头(14字节) typedef struct tagBITMAPFILEHEADER { //WORD bfType;//位图文件的类型,必须为BM(在结构体中读取会发生错误,所以在函数中读取) DWORD bfSize;//位图文件的大小,以字节为单位 WORD b

关于Opengl中将24位BMP图片加入?一个alpha通道并实现透明的问题

#include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h> #pragma comment( lib, "opengl32.lib" )// 链接时使用OpenGL32.lib#pragma comment( lib, "glu32.lib" )// 链接时使用GLu32.lib  #pragma comment( li