原文链接:
http://hi.baidu.com/mayadong7349/blog/item/1b7e2b445f8e9e1c6a63e53a.html
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
FILE *fpSrcBmpfile;
FILE *fpDestBmpfile;
void GetBmpHeader(PBITMAPFILEHEADER, PBITMAPINFOHEADER);
void ChangeBmpHeader(PBITMAPFILEHEADER, PBITMAPINFOHEADER, WORD);
void SetBmpHeader(const PBITMAPFILEHEADER, const PBITMAPINFOHEADER);
void SetRGBQUAD();
void RgbToGrade(); // 24位真彩色转8位灰度
void GradeToRgb(); // 8位灰度位图转24位真彩色
int main(int argc, char *argv[])
{
BITMAPFILEHEADER bfheader; // bmp文件头
BITMAPINFOHEADER biheader; // 位图信息头
memset(&bfheader, 0, sizeof(BITMAPFILEHEADER));
memset(&biheader, 0, sizeof(BITMAPINFOHEADER));
if(argc != 2)
{
puts("\n\t***Error : I need two parameters.");
puts("\t Example: RgbToQuad.exe D:\\flower.bmp");
system("pause>nul");
exit(EXIT_SUCCESS);
}
if((fpSrcBmpfile = fopen(argv[1], "rb")) == NULL) {
perror("\t***Open file failed:(read)");
system("pause>nul");
exit(EXIT_FAILURE);
}
GetBmpHeader(&bfheader, &biheader);
if(bfheader.bfType != 0x4D42) {
puts("\t *End: This file is not bitmap file.");
system("pause>nul");
exit(EXIT_SUCCESS);
}
if(biheader.biBitCount != 24 && biheader.biBitCount != 8) {
puts("\n *End: This bmp file is neither a 24bit nor a 8bit bitmap.");
system("pause>nul");
exit(EXIT_SUCCESS);
}
// 对于采用了游程长度编码方法进行压缩的8位位图 不能按照本算法转为24位位图
if(biheader.biBitCount == 8 && biheader.biCompression != BI_RGB) {
puts("\n *End: This 8bit bmp file is not BI_RGB type");
system("pause>nul");
exit(EXIT_SUCCESS);
}
if((fpDestBmpfile = fopen("D:\\_Done_.bmp", "wb")) == NULL) {
perror("fopen failed :(write)");
system("pause>nul");
exit(EXIT_FAILURE);
}
switch(biheader.biBitCount) {
case 8 : GradeToRgb(); break;
case 24: RgbToGrade(); break;
default: break;
}
fclose(fpDestBmpfile);
fclose(fpSrcBmpfile);
system("pause>nul");
return 0;
}
void GetBmpHeader(PBITMAPFILEHEADER pbfheader, PBITMAPINFOHEADER pbiheader)
{
fread(pbfheader, sizeof(BITMAPFILEHEADER), 1,fpSrcBmpfile);
fread(pbiheader, sizeof(BITMAPINFOHEADER), 1,fpSrcBmpfile);
}
void ChangeBmpHeader(PBITMAPFILEHEADER pbfheader, PBITMAPINFOHEADER pbiheader, WORD wType)
{
pbiheader->biBitCount = wType; // 24 或者 8
pbiheader->biClrUsed = (wType == 24) ? 0 : 256;
pbfheader->bfOffBits = 54 + pbiheader->biClrUsed * sizeof(RGBQUAD);
pbiheader->biSizeImage = ((((pbiheader->biWidth * pbiheader->biBitCount) + 31) & ~31) / 8) * pbiheader->biHeight;
pbfheader->bfSize = pbfheader->bfOffBits + pbiheader->biSizeImage;
}
void SetBmpHeader(const PBITMAPFILEHEADER pbfheader, const PBITMAPINFOHEADER pbiheader)
{
fwrite(pbfheader, sizeof(BITMAPFILEHEADER), 1, fpDestBmpfile);
fwrite(pbiheader, sizeof(BITMAPINFOHEADER), 1, fpDestBmpfile);
}
void SetRGBQUAD()
{
int i;
RGBQUAD rgbquad[256];
for(i=0;i<256;i++) {
rgbquad[i].rgbBlue = i;
rgbquad[i].rgbGreen = i;
rgbquad[i].rgbRed = i;
rgbquad[i].rgbReserved = 0;
}
fwrite(rgbquad, 256 * sizeof(RGBQUAD), 1, fpDestBmpfile);
}
void RgbToGrade() {
LONG w, h;
COLORREF rgb;
BYTE r, g, b;
BYTE gray;
BYTE count24, count8;
BYTE Bmpnul = 0;
BITMAPFILEHEADER bfheader; // bmp文件头
BITMAPINFOHEADER biheader; // 位图信息头
memset(&bfheader, 0, sizeof(BITMAPFILEHEADER));
memset(&biheader, 0, sizeof(BITMAPINFOHEADER));
rewind(fpSrcBmpfile);
GetBmpHeader(&bfheader, &biheader);
ChangeBmpHeader(&bfheader, &biheader, 8);
SetBmpHeader(&bfheader, &biheader);
SetRGBQUAD();
count24 = ( 4 - ( biheader.biWidth * 3 ) % 4 ) % 4;
count8 = ( 4 - ( biheader.biWidth ) % 4 ) % 4;
for(h=biheader.biHeight-1; h>=0; h--) {
for(w=0; w<biheader.biWidth; w++) {
fread(&rgb, 3, 1, fpSrcBmpfile);
if(feof(fpSrcBmpfile)) {
break;
}
// rgb: 0x00bbggrr
r = GetBValue(rgb);
g = GetGValue(rgb);
b = GetRValue(rgb);
// 参见: http://zhidao.baidu.com/question/152910968.html
gray = (BYTE)( ( 77 * r + 151 * g + 28 * b) >> 8 ); // 24位转8位核心算法
fwrite(&gray, sizeof(gray), 1, fpDestBmpfile);
} // for(w
fseek(fpSrcBmpfile, count24, SEEK_CUR);
fwrite(&Bmpnul, 1, count8, fpDestBmpfile);
} // for(h=...
}
void GradeToRgb()
{
LONG w, h;
COLORREF rgb;
BYTE gray;
BYTE count24, count8; // 24位位图、8位位图每个扫描行需要填充的0的个数
BYTE Bmpnul = 0;
BITMAPFILEHEADER bfheader; // bmp文件头
BITMAPINFOHEADER biheader; // 位图信息头
memset(&bfheader, 0, sizeof(BITMAPFILEHEADER));
memset(&biheader, 0, sizeof(BITMAPINFOHEADER));
rewind(fpSrcBmpfile);
GetBmpHeader(&bfheader, &biheader);
ChangeBmpHeader(&bfheader, &biheader, 24);
SetBmpHeader(&bfheader, &biheader);
fseek(fpSrcBmpfile, 256 * sizeof(RGBQUAD), SEEK_CUR); // 跳过颜色表部分 因为24位位图不需要颜色表
count24 = ( 4 - ( biheader.biWidth * 3 ) % 4 ) % 4;
count8 = ( 4 - ( biheader.biWidth ) % 4 ) % 4;
for(h=biheader.biHeight-1; h>=0; h--) {
for(w=0; w<biheader.biWidth; w++) {
fread(&gray, 1, 1, fpSrcBmpfile);
if(feof(fpSrcBmpfile)) {
break;
}
rgb = RGB(gray,gray,gray);//
8位转24位核心算法
fwrite(&rgb, 3, 1, fpDestBmpfile);
} // for(w
fseek(fpSrcBmpfile, count8, SEEK_CUR);
fwrite(&Bmpnul, 1, count24, fpDestBmpfile);
} // for(h
}
分享到:
相关推荐
QT和Opencv图像格式转换_ qtopencv图片数组相互转化,opencv格式转换mono8 -C 代码类资源 关于QImage和Mat格式的转换
主要讲述了labview图像经过数据解析后转换为halcon的图像数据格式
图像类型的相互转换,图像存储方式 ,图像文件格式的相互转换
对不同类型的图像进行相互转换,如RGB图像和灰度图像之间的转换
VC6实现bmp格式图像和jpg格式图像相互转化,VC6实现bmp格式图像和jpg格式图像相互转化
该文档说明了Halcon/Opencv/VC之间图像相互转换的原理方法和实例。
RGB与YUV图像视频格式的相互转换 本代码演示了RGB与YUV图像视频格
基于C++的编程工程,用于将输入的RGB图片转化成四副灰度图,分别表示CMYK四个色彩在原图中的分量,并可将转化后的四种分量重新合成为RGB形式的新图,是一种图像处理分析的基础算法
图像运算与图像变换是图像最基本的技术。图像运算可以根据多个像素值,通过运算 得到新像素值(例如:图像的减法运算可以检测图像...互相转换)。图像运算与图像变换作为基本的图像处理技术是图像分析和理解的基础。
YUV420与RGB24之间的视频图像格式相互转,pdf格式
图像格式之间进行相互转换,支持jpg,bmp,png,gif,tif等格式之间的相互转换。方便,易用。
PDF和图像相互转换程序,可以实现将PDF文件转换成TIFF或JEPG等格式的图片,也可以将图片文件转换成PDF文件
Windows位图在IHS与RGB色彩空间之间的转换
实现DIB与DDB图像相互转换 读取 显示 储存 简易vc++代码 睡不着 无聊的写的代码 绝对好用
OpenCV实现灰度图像到二维数组,数组到图像的相互转换存取
emgucv是c#版本的opencv,用c#写的halcon与c#emgucv之间的图像转换函数,对采用halcon与emgucv混合编程的比较有用。是txt格式的,直接把函数复制在自己的代码里面就可以用,注意要把emgucv和halcon的环境配置好才...
C++实现图像处理RGB与HSV相互转换代码
C++实现图像处理RGB与YUV相互转换代码
C++实现图像处理RGB与HSI相互转换代码
RGB与YUV图像视频格式的相互转换