C语言 BMP图片处理

合集下载

C语言实现BMP图片生成

C语言实现BMP图片生成

C语⾔实现BMP图⽚⽣成###include <stdio.h>#include <stdlib.h>#include <string.h>typedef unsigned char byte;typedef unsigned short dbyte;typedef unsigned long int dword;typedef unsigned short word;/********************************************定义bmp⽂件的头部数据结构********************************************/#pragma pack(push,2) //保持2字节对齐struct tagBITMAPFILEHEADER {//bmp file headerdbyte bfType; //⽂件类型dword bfSize; //⽂件⼤⼩,字节为单位word bfReserved1; //保留,必须为0word bfReserved2; //保留,必须为0dword bfOffBits; //从⽂件头开始的偏移量//bmp info headdword biSize; //该结构的⼤⼩dword biWidth; //图像的宽度,以像素为单位dword biHeight; //图像的⾼度,以像素为单位word biPlanes; //为⽬标设备说明位⾯数,其值总是设为1word biBitCount; //说明⽐特数/像素dword biCompression; //图像数据压缩类型dword biSizeImage; //图像⼤⼩,以字节为单位dword biXPelsPerMeter; //⽔平分辨率,像素/⽶dword biYPelsPerMeter; //垂直分辨率,同上dword biClrUsed; //位图实际使⽤的彩⾊表中的颜⾊索引数dword biClrImportant; //对图像显⽰有重要影响的颜⾊索引的数⽬//bmp rgb quad//对于16位,24位,32位的位图不需要⾊彩表//unsigned char rgbBlue; //指定蓝⾊强度//unsigned char rgbGreen; //指定绿⾊强度//unsigned char rgbRed; //指定红⾊强度//unsigned char rgbReserved; //保留,设置为0}BMPFILEHEADER;#pragma (pop)struct tagBITMAPFILEHEADER *bmp_p; //定义bmp⽂件头结构体指针FILE *fd; //定义⼀个⽂件类型的指针/**************************************************************初始化bmp⽂件头部,设置bmp图⽚**************************************************************/void Init_bmp_head(void){bmp_p = &BMPFILEHEADER;bmp_p-> bfType = 0x4D42; //⽂件类型bmp_p-> bfSize = 0x25836; //⽂件⼤⼩,字节为单位bmp_p-> bfReserved1 = 0x0; //保留,必须为0bmp_p-> bfReserved2 = 0x0; //保留,必须为0bmp_p-> bfOffBits = 0x36; //从⽂件头开始的偏移量//bmp info headbmp_p-> biSize = 0x28; //该结构的⼤⼩bmp_p-> biWidth = 320; //图像的宽度,以像素为单位bmp_p-> biHeight = 240; //图像的⾼度,以像素为单位bmp_p-> biPlanes = 0x01; //为⽬标设备说明位⾯数,其值总是设为1bmp_p-> biBitCount = 16; //说明⽐特数/像素bmp_p-> biCompression = 0; //图像数据压缩类型bmp_p-> biSizeImage = 0x25800;//0x09f8; //图像⼤⼩,以字节为单位bmp_p-> biXPelsPerMeter = 0x60;//0x60; //⽔平分辨率,像素/⽶bmp_p-> biYPelsPerMeter = 0x60; //垂直分辨率,同上bmp_p-> biClrUsed = 0; //位图实际使⽤的彩⾊表中的颜⾊索引数bmp_p-> biClrImportant = 0; //对图像显⽰有重要影响的颜⾊索引的数⽬}int main(void){static char *file_name =NULL; //保存⽂件名的指针static long file_length = 0x25836; //⽂件的⼤⼩(整个⽂件)unsigned char *file_p = NULL; //写⼊数据指针unsigned char *file_p_tmp = NULL; //写⼊数据临时指针unsigned char *byte_copy_p = NULL; //⽂件头部传递指针unsigned char byte_copy = 0; //⽂件头部数据拷贝变量int i = 0;file_name = "test1.bmp";Init_bmp_head();file_p = (unsigned char *)malloc(sizeof(char)*153654); //申请⼀段内存 file_p_tmp = file_p;for(i = 0;i < 153654;i++ ){if(i%2 ==0){*file_p_tmp = 0x00; //图像前8位值}else{*file_p_tmp = 0xf0; //图像后8位值}file_p_tmp++;}byte_copy_p = (unsigned char *)bmp_p;file_p_tmp = file_p;for(i = 0;i < 54;i++){*file_p_tmp = *byte_copy_p;file_p_tmp++;byte_copy_p++;}fd = fopen(file_name, "w");fwrite(file_p, file_length, 1,fd);free(file_p); //释放申请的内存(重要)fclose(fd);printf("Done success\n");getchar();return (0);}。

用VC编程实现BMP图像裁切

用VC编程实现BMP图像裁切

5.5 用VC编程实现BMP图像裁切随着计算电子技术和计算机技术的发展,数字图像处理进入高速发展时期,许多成熟的图像处理软件如雨后春笋般层出不穷。

在大多数图像处理软件中都有图像裁切功能,用它能够快速提取感兴趣区域,去掉多余的图像内容。

那么怎样编程实现图像裁切呢,下面以BMP图像为例介绍一下如何用VC实现图像裁切。

先介绍第一种方法,将图像数据全部读入内存,然后将感兴趣区域裁切下来。

在许多数字图像处理的书中都有关于BMP图像存储结构的章节,这里就不再详细介绍了。

BMP文件一般分为四个部分:位图头文件、位图信息头、调色板和图像数据。

图像裁切要用到位图信息头中的几个参数值:biWidth(图像宽度)、biHeight(图像高度)、biBitCount(每个像素的位数)、biSizeImage(图像长度)。

图像裁切首先要确定裁切区域内每个像素在整幅图像中的位置,我们以裁切区域中心点像素位置起算,要注意的是图像数据的存储是从最下面一行的左边开始的。

如下图,Height是图像高,Width是图像宽,ctPoint是裁切区域中心点坐标,dwX和dwY分别是裁切区域的宽和高。

以256色图像为例(每个像素占一个字节),裁切区域左下角像素(也就是裁切后图像的第一个像素)位置为(Height-ctPoint.y-dwY/2-1)×Width+ctPoint.x-dwX/2,左下角像素位置确定了,裁切区域内的其他像素位置就很容易确定。

确定了裁切区域内每个像素的位置后,就可以把这些像素的值赋给裁切后图像的相应像素。

裁切后图像的位图信息头和调色板只要从原图像数据中拷贝就可以了,修改信息头中图像宽、高和长度值为裁切后的值。

按照上面的思路笔者用VC++ 6.0编写了一个图像裁切函数ClipDIB(),该函数首先计算裁切区域图像数据的大小,为裁切后的图像分配内存,然后将原图像的信息头、调色板拷贝给裁切后的图像,最后将原图像中裁切区域内的像素值赋给裁切后影像。

256级灰度BMP文件读写的源代码+c语言图像处理

256级灰度BMP文件读写的源代码+c语言图像处理

本文档最早发布于 /u/14951820541.256级灰度BMP文件读写的源代码!首先要明白256级灰度BMP文件的格式1.首先是一个14个字节的文件头,定义如下typedef struct tagBITMAPFILEHEADER{WORD bfType;DWORD bfSize;WORD bfReserved1;WORD bfReserved2;DWORD bfOffBits;} BITMAPFILEHEADER, *PBITMAPFILEHEADER;bfType是表明BMP文件类型的数据,在这里我们填入的是0x4d42,其实就是BM两个字,bfSize是文件大小,bfOffBits是文件头到数据块的偏移量,对于256级灰度图,就是1078个字节,后面会做描述2.接下来是40个字节的是描述位图属性的40个字节typedef struct tagBITMAPINFOHEADER{DWORD biSize;LONG biWidth;LONG biHeight;WORD biPlanes;WORD biBitCount;DWORD biCompression;DWORD biSizeImage;LONG biXPelsPerMeter;LONG biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant;} BITMAPINFOHEADER, *PBITMAPINFOHEADER;这里面只有biWidth表示宽度,biPlanes表示高度,biBitCount对于256级灰度正好是83.由于是256级灰度图,那么有256个调色板数据,每个调色板是如下定义的typedef struct tagRGBQUAD {BYTE rgbBlue;BYTE rgbGreen;BYTE rgbRed;BYTE rgbReserved;}RGBQUAD, *PRGBQUAD;调色板数据其实告诉了显示器实际显示的时候的具体颜色,所以调色板长度是1024字节4.最后是按行组织的图像数据,但这些数据并不是简单的按照图像的高度宽度w*h的数组数据这些数据最重要的特点是a.按行组织,每行宽度是w,但是要进行4个字节的对齐。

完整程序_C语言对BMP图像的读和写和对像素的操作

完整程序_C语言对BMP图像的读和写和对像素的操作

#include <stdio.h>#include "Windows.h"BOOL readBmp(char *bmpName);BOOL saveBmp(char *bmpName, char *imgBuf, int width, int heigh, int biBitCount, RGBQUAD *pColorTable);char *pBmpBuf; //位图数据int bmpWidth; // 图像宽度int bmpHeight; //图像高度int biBiCount; //图像类型,每像素位数RGBQUAD *pColorTable; //位图颜色表指针int main(){char readName[] = "read.BMP";readBmp(readName);char writeName[] = "write.BMP";saveBmp(writeName, pBmpBuf, bmpWidth, bmpHeight, biBiCount, pColorTable);int lineByte = (bmpWidth*bmpHeight/8+3)/4*4;if (biBiCount == 8){for (int i = 0; i < bmpWidth/2; i++){for (int j = 0; j < bmpHeight/2; j++){*(pBmpBuf+i*lineByte+j) = 0;}}}else if (biBiCount == 24){/////对于24位真彩图,每个像素占三个字节分别存储R、G、B三个颜色分量的颜色值for (int i = 0; i < bmpWidth/2; i++){for (int j = 0; j < bmpHeight/2; j++){for (int k = 0; k < 3; k++)*(pBmpBuf+i*lineByte+j*3+k) = 0; //将rgb三个颜色分量设置成黑色}}}char Name[] = "copy.BMP";saveBmp(Name, pBmpBuf, bmpWidth, bmpHeight, biBiCount, pColorTable);delete []pBmpBuf;if (biBiCount == 8){delete []pColorTable;}return 0;}BOOL readBmp(char *bmpName ){FILE *pf = fopen(bmpName, "rb");if (pf == NULL) return FALSE;printf("read %s succeeded!\n", bmpName);fseek(pf, sizeof(BITMAPFILEHEADER), SEEK_SET);BITMAPINFOHEADER infoHeader;fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pf);bmpWidth = infoHeader.biWidth;bmpHeight = infoHeader.biHeight;biBiCount = infoHeader.biBitCount;//图像每行的字节数,一定要是4的倍数int lineByte = (bmpWidth*bmpHeight/8+3)/4*4;pBmpBuf = new char[lineByte*bmpHeight];//灰度图像有颜色表if (biBiCount == 8){pColorTable = new RGBQUAD[256];fread(pColorTable, sizeof(RGBQUAD), 1, pf);}fread(pBmpBuf, lineByte*bmpHeight, 1, pf);fclose(pf); //关闭文件return TRUE;}BOOL saveBmp(char *bmpName, char *imgBuf, int width, int heigh, int biBitCount, RGBQUAD *pColorTable ){FILE *pf = fopen(bmpName, "wb");if (pf == NULL) return FALSE;printf("write %s succeeded!\n", bmpName);//写头文件int colorTableSize = 0;if (biBitCount == 8){colorTableSize = 1024;}int lineByte = (width*heigh/8+3)/4*4;BITMAPFILEHEADER filehead;filehead.bfOffBits = 54+colorTableSize;filehead.bfType = 0x4D42;filehead.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTableSize+lineByte*heig h;filehead.bfReserved1 = 0;filehead.bfReserved2 = 0;fwrite(&filehead, sizeof(BITMAPFILEHEADER), 1, pf);BITMAPINFOHEADER infoHead;infoHead.biBitCount = biBitCount;infoHead.biWidth = width;infoHead.biHeight = heigh;infoHead.biSize = 40;infoHead.biClrImportant = 0;infoHead.biSizeImage = lineByte*heigh;infoHead.biClrUsed = 0;infoHead.biPlanes = 1;infoHead.biXPelsPerMeter = 0;infoHead.biYPelsPerMeter = 0;fwrite(&infoHead,sizeof(BITMAPINFOHEADER), 1, pf);if (biBitCount == 8){fwrite(pColorTable, sizeof(RGBQUAD), 256, pf);}fwrite(pBmpBuf, lineByte*heigh, 1, pf);fclose(pf);return TRUE;}。

用c语言读取并显示bmp图像1

用c语言读取并显示bmp图像1

如何在WIN-TC中或TC++3.0中把一张BMP格式的图片显示出来?下面的是<<C & C++编程实例>>随书光盘上的代码,我在TC2.0下编译通过.它是利用了抖动技术显示了8bit和24bit的位图(也就是256色和16M色位图),应该能满足你的需要.不过,我想问下,你老师教过抖动显示吗?#include <stdio.h>#include <dos.h>#include <stdio.h>#include <conio.h>#define NoError 0#define ErrorFileOpen 1#define ErrorFileType 2#define ErrorImageColor 3typedef struct tagBITMAPFILEHEADER{unsigned int bfType;unsigned long bfSize;unsigned int bfReserved1;unsigned int bfReserved2;unsigned long bfoffBits;}BITMAPFILEHEADER;typedef struct tagBITMAPINFOHEADER{unsigned long biSize;unsigned long biWidth;unsigned long biHeight;unsigned int biPlanes;unsigned int biBitCount;unsigned long biCompression;unsigned long biSizeImage;unsigned long biXPelsPerMeter;unsigned long biYPelsPerMeter;unsigned long biClrUsed;unsigned long biClrImportant;} BITMAPINFOHEADER;typedef struct tagRGBQUAD{unsigned char rgbBlue;unsigned char rgbGreen;unsigned char rgbRed;unsigned char rgbReserved;} RGBQUAD;unsigned char PalReg[17]= { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0}; unsigned char StandardPal[48]= {0, 0, 0, 32, 0, 0, 0,32, 0, 32,32, 0, 0, 0,32, 32, 0,32, 0,32,32, 32,32, 32, 48, 48,48, 63, 0, 0, 0,63, 0, 63,63, 0, 0, 0,63, 63, 0,63, 0,63,63, 63,63,63, };unsigned char LightnessMatrix [16][16]= {{ 0,235,59,219,15,231,55,215,2,232,56,217,12,229,52,213},{128,64,187,123,143,79,183,119,130,66,184,120,140,76,180,116},{33,192,16,251,47,207,31,247,34,194,18,248,44,204,28,244},{161,97,144,80,175,111,159,95,162,98,146,82,172,108,156,92},{8,225,48,208,5,239,63,223,10,226,50,210,6,236,60,220},{136,72,176,112,133,69,191,127,138,74,178,114,134,70,188,124},{41,200,24,240,36,197,20,255,42,202,26,242,38,198,22,252},{169,105,152,88,164,100,148,84,170,106,154,90,166,102,150,86},{3,233,57,216,13,228,53,212,1,234,58,218,14,230,54,214},{131,67,185,121,141,77,181,117,129,65,186,122,142,78,182,118},{35,195,19,249,45,205,29,245,32,193,17,250,46,206,30,246},{163,99,147,83,173,109,157,93,160,96,145,81,174,110,158,94},{11,227,51,211,7,237,61,221,9,224,49,209,4,238,62,222},{139,75,179,115,135,71,189,125,137,73,177,113,132,68,190,126},{43,203,27,243,39,199,23,253,40,201,25,241,37,196,21,254},{171,107,155,91,167,103,151,87,168,104,153,89,165,101,149,85},};unsigned char ColorTable[2][2][2]= {{{0,12},{10,14}},{{9,13},{11,15}}}; unsigned char ColorMap[256][3];int ShowBmp(char *FileName);int GetColor(unsigned char R,unsigned char G, unsigned char B,int X,int Y); void SetVideoMode(unsigned char Mode);void SetPalReg(unsigned char *palReg);void SetDacReg(unsigned char *DacReg, int Color, int Count);void PutPixel(int X, int Y, unsigned char Color);/* 主函数*/void main (int argc, char *argv[]){if(argc!=2){printf("Usage:\tSHOW Filename.BMP\n");exit(1);}ShowBmp(argv[1]);}/* 根据图像文件名,读取图像内容并利用抖动技术进行显示*/ int ShowBmp(char *FileName){FILE *Fp;BITMAPFILEHEADER FileHead;BITMAPINFOHEADER InfoHead;RGBQUAD RGB;int N, W,Y,X,C,Color;unsigned char Buffer[4096];Fp=fopen(FileName,"rb");if (Fp==NULL)return(ErrorFileOpen);fread(&FileHead,sizeof(BITMAPFILEHEADER),1,Fp);if(FileHead.bfType!='BM'){fclose(Fp);return(ErrorFileType);}fread(&InfoHead,sizeof(BITMAPINFOHEADER),1,Fp);if(InfoHead.biBitCount!=8 && InfoHead.biBitCount!=24){fclose(Fp);return(ErrorImageColor);}/* 设置显示模式和显示区域*/SetVideoMode(0x12);SetPalReg(PalReg);SetDacReg(StandardPal,0,16);/* 对两种不同色彩数的图像分别进行处理*/if(InfoHead.biBitCount==8) /* 256色*/{for (N=0;N<256;N++){fread(&RGB, sizeof(RGBQUAD),1,Fp);ColorMap[N][0]=RGB.rgbRed;ColorMap[N][1]=RGB.rgbGreen;ColorMap[N][2]=RGB.rgbBlue;}W=(InfoHead.biWidth+3)/4*4;for(Y=InfoHead.biHeight-1;Y>=480;Y--)fread(Buffer,sizeof(unsigned char),W,Fp);for(;Y>0;Y--){fread(Buffer,sizeof(unsigned char),W,Fp);for (X=0;X<InfoHead.biWidth && X<640;X++){C=Buffer[X];Color=GetColor(ColorMap[C][0],ColorMap[C][1],ColorMap[C][2],X,Y); PutPixel (X,Y,Color);}}}else /* 24bits真彩色*/{W=(InfoHead.biWidth*3+3)/4*4;for(Y=InfoHead.biHeight-1;Y>639;Y--)fread(Buffer,sizeof(unsigned char),W,Fp);for(;Y>=0;Y--){fread(Buffer,sizeof(unsigned char),W,Fp);for(X=0;X<InfoHead.biWidth && X<640;X++){C=X*3;Color=GetColor(Buffer[C+2],Buffer[C+1],Buffer[C],X,Y);PutPixel(X,Y,Color);}}}getch();fclose(Fp);SetVideoMode(0x03);return(NoError);}int GetColor(unsigned char R, unsigned char G, unsigned char B, int X, int Y) {unsigned int L=LightnessMatrix[Y & 0x0F][X & 0x0F];return(ColorTable[(unsigned int)R*256/255>L][(unsigned int)G*256/255>L][(unsigned int)B*256/255>L]); }void SetVideoMode(unsigned char Mode){_AH=0x00;_AL=Mode;geninterrupt(0x10);}void SetPalReg(unsigned char *PalReg){_ES=FP_SEG((unsigned char far*)PalReg);_DX=FP_OFF((unsigned char far*)PalReg);_AX=0x1002;geninterrupt(0x10);}void SetDacReg(unsigned char *DacReg,int Color,int Count){_ES=FP_SEG((unsigned char far*)DacReg);_DX=FP_OFF((unsigned char far*)DacReg);_AX=0x1012;_BX=Color;_CX=Count;geninterrupt(0x10);}/* 在对应位置显示像素色彩*/void PutPixel(int X, int Y, unsigned char Color){_AH=0x0C;_AL=Color;_CX=X;_DX=Y;geninterrupt(0x10);}16色位图的显示文:吴进/Luckylai对于象大家常用TC的16色图形模式编程的初学者,如果能在程序里使用图片那就会方便很多了,以前在TC256上看见吴进写的《TC的16色BMP闪电显示(66k) 》的代码,发现写的的确不错,而且绝对能在TC的initgraph()初始化的BGI模式下使用。

c语言image用法

c语言image用法

C语言image用法C语言是一种被广泛应用于系统编程和开发嵌入式软件的高级编程语言。

它提供了强大的图像处理功能,可以通过使用Image库来实现图像的加载、处理和保存。

本文将详细介绍C语言中Image库的用法。

一、Image库概述Image库是C语言中的一个常用工具库,它提供了一组函数和数据结构,用于处理图像数据。

使用Image库可以方便地读取、修改和保存图像,以实现各种图像处理操作。

常见的操作包括图像的缩放、旋转、灰度处理等。

二、图像的加载与保存在使用Image库进行图像处理之前,我们首先需要了解如何加载和保存图像。

Image库支持多种图像格式,包括常见的BMP、PNG、JPEG等。

1. 图像加载Image库提供了一个函数来加载图像数据,该函数的原型如下:IMAGE *imgLoad(const char *filename);该函数接收一个存储图像文件名的字符串作为参数,并返回一个指向图像结构体IMAGE的指针。

通过该指针,我们可以访问图像的宽度、高度和像素数据等信息。

2. 图像保存Image库同样提供了一个函数用于保存图像,函数原型如下:int imgSave(IMAGE *img, const char *filename);该函数接收一个指向IMAGE结构体的指针和一个存储图像文件名的字符串作为参数。

函数会将图像数据保存到指定的文件中,并返回保存是否成功的标志。

三、图像处理操作示例下面我们将通过几个示例演示Image库的图像处理操作。

假设我们有一张名为"image.bmp"的BMP格式图像,我们将使用Image库对该图像进行操作。

1. 图像缩放图像缩放是一种常见的图像处理操作,我们可以使用Image库的函数来实现图像的缩放。

以下是一个图像缩放的示例:#include <stdio.h>#include <image.h>int main() {IMAGE *img = imgLoad("image.bmp"); // 加载图像IMAGE *newImg = imgScale(img, 0.5, 0.5); // 缩小图像imgSave(newImg, "scaled_image.bmp"); // 保存缩放后的图像imgFree(img); // 释放内存imgFree(newImg);return 0;}在上述示例中,我们使用了imgScale函数实现了图像的缩放,该函数接收一个指向原始图像的指针和缩放比例作为参数。

BMP图像分割C语言程序

BMP图像分割C语言程序

} fseek(fp1,sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),S EEK_SET); fseek(fp2,sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),S EEK_SET); for(i=0;i<255;i++) { fread(&pal[i].rgbBlue,1,1,fp1); fread(&pal[i].rgbGreen,1,1,fp1); fread(&pal[i].rgbRed,1,1,fp1); pal[i].rgbReserved=0; } line_bytes1=(biWidth1*biBitCount1+31)/32*4; line_bytes2=(biWidth2*biBitCount2+31)/32*4; pixel1=(BYTE*)malloc(biHeight1*line_bytes1*sizeof(BYTE)); memset(pixel1,0,biHeight1*line_bytes1*sizeof(BYTE)); if(pixel1==0) { printf("Fail to allocate memory to File one.\n"); fclose(fp1); fclose(fp2); return 1; } pixel2=(BYTE*)malloc(biHeight2*line_bytes2*sizeof(BYTE)); memset(pixel2,0,biHeight2*line_bytes2*sizeof(BYTE)); if(pixel2==0) { printf("Fail to allocate memory to File two.\n"); fclose(fp1); fclose(fp2); return 1; }

详解用VC实现bmp位图的打开-fengqing888的日志-网易博客

详解用VC实现bmp位图的打开-fengqing888的日志-网易博客

详解用VC实现bmp位图的打开-fengqing888的日志-网易博客详解用VC实现bmp位图的打开技术_图片编程 2009-12-18 13:59:17 阅读262 评论0 字号:大中小我最近在学VC++数字图像处理,作为一个初学者,万里长征的第一步当然是打开一幅图像,这几天一直在看怎么实现这一功能,虽说简单,但是如果这一步不能做到,那么下面也就无法进行了,所以我总结了一下这个过程,写出来供大家参考。

也希望大家多多批评啊。

这里我就不想介绍关于位图的理论内容了,只是写一下实现的部分。

0.准备工作创建一个SDI,工程名Test,“隐藏工具栏”和“打印和打印预览”取消了,不用那么复杂,简单点就行1.创建菜单创建两个菜单:Caption: 打开 ID: ID_FILE_OPENCaption: 显示原图 ID: IDM_YUANTU2.对打开菜单进行响应右键打开菜单,建立类向导,在CTestDoc类中,进行COMMAND响应,生成OnFileOpen函数,代码如下:void CTestDoc::OnFileOpen(){// TODO: Add your command handler code hereCFileDialog fileDlg(TRUE);//创建一个CfileDialog类对象fileDlg,第一个参数TRUE为打开对话框,若为FALSE,则为另存为fileDlg.m_ofn.lpstrTitle="图片打开对话框";//设置打开对话框的标题fileDlg.m_ofn.lpstrFilter="BMP Files(*.bmp)\0*.bmp\0\0";//设置打开的文件类型if(IDOK==fileDlg.DoModal ())//这个语句有两层意义,第一是dlg.DoModal()作用是弹出CPortDlg对话框,第二层是dlg.DoModal()==IDOK是你点击了对话框上的OK按钮就是说你同时做了上述两件事时就执行if语句后面的程序。

C语言图像处理函数大全

C语言图像处理函数大全

C语言图像处理函数大全,完整版∙∙1.图像平移图像平移只是改变图像在屏幕上的位置,图像本身并不发生变化。

假设原图像区域左上角坐标为(x0, y0),右下角坐标为(x1, y1),将图像分别沿x和y轴平移dx和dy,则新图像的左上角坐标为(x0 +dx, y0+dy),右下角坐标为(x1+dx, y1+dy)。

坐标平移变换公式为:x′ = x +dxy′ = y +dy在屏幕上实现图像的移动分为四个步骤:⑴保存原图像到缓冲区。

⑵擦除原图像。

⑶计算平移后的新坐标。

⑷在新的坐标位置重新显示原图像。

其中,擦除原图像的方法与图形变换中擦除原图形的方法一致,在实现中仍采用XOR异或方式画图擦除原图像。

对于新坐标值的计算还需要考虑边界情况,不要在图像平移后超出允许的屏幕范围。

此外,如果采用C函数getimage()和putimage()来保存和恢复图像,则图像的大小不能超过64K。

2.图像颠倒图像颠倒是指把定义好的图像区域上下翻转地显示在屏幕上。

分析图像颠倒的过程,可发现每行的图像信息都保持不变,而只是改变了行的顺序,将第一行与最后的第n行相互交换,第二行与第n-1行交换……,依此类推,从而实现了图像的颠倒。

只需采用按行交换的方式,即可方便地修改缓冲区内容,实现图像的颠倒。

基本步骤如下:(1) 用getimage()保存原图像,并擦除原图像。

(2) 计算图像的高度,即行数height;计算图像宽度width;计算保存一行图像信息height = bottom -top +1;width = right -left +1;linebytes = (width +7) /8 *4;(3)利用行交换缓冲区linebuf在图像内存缓冲区中进行信息交换,即把第一行与最末行交换,第2行与第n-1行交换……,依此类推,直至全部交换完毕。

(4)把交换后的图像缓冲区内容重新显示在屏幕上。

3.图像镜像变换镜像变换是指将指定区域的图像左右翻转地显示在屏幕。

将JPEG文件转换为BMP文件(C语言实现)

将JPEG文件转换为BMP文件(C语言实现)
unsigned int codevalue[4][256],hufmax[4][16],hufmin[4][16];
int bitpos=0,curbyte=0,run=0,value=0,MCUbuffer[10*64],blockbuffer[64];
int ycoef=0,ucoef=0,vcoef=0,intervalflag=0,interval=0,restart=0;
fread(&flag,sizeof(unsigned int),1,fp);
if(flag!=0xd8ff)
error("Error Jpg File format!");
while(!finish) {
qtindex=*(q++)&0x0f;
for(i=0;i<64;i++)
Qt[qtindex][i]=(int)*(q++);
}
free(p);break;
case 0xc0ff:
sampleYH=(*(p+7))>>4;
sampleYV=(*(p+7))&0x0f;
YQt=(int *)Qt[*(p+8)];
compressindex[1]=*(p+9);
sampleUH=(*(p+10))>>4;
head.size=imagebytes+0x36;
head.reserved=0;
head.offset=0x36;
fwrite(&head,sizeof(head),1,fp);

C语言读取BMP格式图片

C语言读取BMP格式图片

另外需要注意的是这是一个近似值,对于 n 位的位图图像来说,尽管可能有最多 种颜色,一个特定的图像可能并不会使用这些所有的颜色。由于彩色调色板 仅仅定义了图像所用的颜色,所以实际的彩色调色板将小于 如果想知道这些值是如何得到的,请参考下面文件格式的部分。 由于存储算法本身决定的因素, 根据几个图像参数的不同计算出的大小与实际的 文件大小将会有一些细小的差别。 典型的文件格式 。
存储算法
BMP 文件通常是不压缩的,所以它们通常比同一幅图像的压缩图像文件格式要大 很多。例如,一个 800×600 的 24 位几乎占据 1.4MB 空间。因此它们通常不适合 在因特网或者其他低速或者有容量限制的媒介上进行传输。 根据颜色深度的不同,图像上的一个像素可以用一个或者多个字节表示,它由 n/8 所确定(n 是位深度,1 字节包含 8 个数据位)。图片浏览器等基于字节的 ASCII 值计算像素的颜色,然后从调色板中读出相应的值。更为详细的信息请参 阅下面关于位图文件的部分。 n 位 2n 种颜色的包含调色板的位图近似字节数可以用下面的公式计算:
unsigned char r[2000][2000],output_r[2000][2000]; unsigned char g[2000][2000],output_g[2000][2000]; unsigned char b[2000][2000],output_b[2000][2000];
int main(int argc, char* argv[]) { /* Open bmp file */ unsigned char *fp_temp;
bmpFileTest(fpbmp); bmp file or not bmpHeaderPartLength(fpbmp); Header Part BmpWidthHeight(fpbmp); width of the Data Part

在vc下用c语言读bmp文件信息并且改写bmp颜色

在vc下用c语言读bmp文件信息并且改写bmp颜色
在 vc 下用 c 语言读写 bmp 图像信息并且写 bmp 图像的颜色
读者需要的基础: 1.c 语言基础 。 2.会用 vc++ 。 3.了解改 jpg 图像的后缀名来得到 bmp 图像,并不是真正意义的 bmp 图像,这样的图像是不能被 本程序读写的。 5.本程序用的是 24 位的 bmp 图像。
uchar rgbblue; //该颜色的蓝色分量 uchar rgbgreen; //该颜色的绿色分量 uchar rgbred; ////该颜色的红色分量 //uchar rgbReversed; //保留值,这里好像没有。 };
int main() {
struct bmp_header fileheader;//定义一个文件头信息块对象存放读取数据。 struct bmp_information fileinformation;//定义一个图像描述信息块对象存放读取数据。 struct bmp_rgb filergb; //定义一个颜色表(调色板)对象存放读取数据 uchar blue=0;//自定义蓝色分量,用于写进蓝色分量的值,在这里你可以修改三个颜色的分量,改变 bmp 图像的颜色。 uchar green=0;//自定义绿分量,用于写进蓝绿色分量的值 uchar red=255;//自定义红色分量,用于写进红色分量的值 FILE *fp; if((fp=fopen("1.bmp","rb+"))==NULL)//,一定要 rb+,读取并且可写二进制文件。在这里我把我的“1.bmp” 图像放在当前程序下,大家可以自行改变图片的名称和位置,然后在这里自行配置即可。 {
printf("bmp 格式标志:0x%x\n",fileheader.btyde); printf("文件大小: %u\n",fileheader.bsize); printf("保留字 1:%d\n",fileheader.breserved1); printf("保留字 2:%d\n",fileheader.breserved2); printf("位图数据偏移字节数:%u\n",fileheader.bfoffbits); printf("结构体长度: %u\n",fileinformation.bisize); printf("位图宽度: %d\n",fileinformation.bwidth); printf("位图高度: %d\n",fileinformation.bheight); printf("位图平面数: %u\n",fileinformation.bplanes); printf("颜色位数: %u\n",fileinformation.bbitcount); printf("压缩方式:%u\n",fileinformation.bcompression); printf("实际位图数据占用的字节数: %u\n",fileinformation.bmpimagesize); printf("X 方向分辨率:%d\n",fileinformation.bx); printf("Y 方向分辨率: %d\n",fileinformation.by); printf("使用的颜色数:%u\n",fileinformation.bcirused); printf("重要颜色数:%u\n",fileinformation.bcirimportant); printf("红色分量:%u\n",filergb.rgbred); printf("绿色分量:%u\n",filergb.rgbgreen); printf("蓝色分量:%u\n",filergb.rgbblue); fseek(fp,54L,0);//将文件类型指针定位在颜色表(调色板)的开头,便于下面开始写 i=ftell(fp); printf("%d\n",i); for(int j=0;j<fileinformation.bheight;j++)//这里两个循环的意思是保证整个图像的所有像素都被重写 rgb for(int k=0;k<fileinformation.bwidth;k++)

24位BMP图像

24位BMP图像

#include<stdio.h>#include<malloc.h>void main(){FILE *fpIn,*fpOut;///////////////////////////struct RGBQUAD{unsigned char rgbBlue;unsigned char rgbGreen;unsigned char rgbRed;unsigned char rgbReserved;} bicolor;char bfty[2];short bfreserved1,biplanes,bibitcount;long bfsize,bfoffbit,bisize,biwidth,biheight;long bicompression,bisizeimage,bix,biy,biclrused,biclrimportant;char *cR;int iCol,iRow;int i,j;int iWidth;char *lpsData;int iL;short sTemp;////////////////////////////////////fpIn=fopen("F:/课堂学习/遥感数字图像处理/data/AA","rb");fpOut=fopen("F:/课堂学习/遥感数字图像处理/data/Tm23.bmp","wb");//D:\??\??????????\Data\dataiCol=600;iRow=600;bfty[0]='B';bfty[1]='M';bfsize=54+iCol*iRow*3;bfreserved1=0;bfoffbit=54;/////////////////bisize=40;biwidth=iCol;biheight=iRow;biplanes=1;bibitcount=24;bicompression=0;bisizeimage=iRow*iCol*3;bix=0;biy=0;biclrused=0;biclrimportant=0;/////////////////////////fwrite(&bfty[0],1,1,fpOut);//fprintffwrite(&bfty[1],1,1,fpOut);fwrite(&bfsize,4,1,fpOut);fwrite(&bfreserved1,2,1,fpOut);fwrite(&bfreserved1,2,1,fpOut);fwrite(&bfoffbit,4,1,fpOut);///////////////////////////////////fwrite(&bisize,4,1,fpOut);fwrite(&biwidth,4,1,fpOut);fwrite(&biheight,4,1,fpOut);fwrite(&biplanes,2,1,fpOut);fwrite(&bibitcount,2,1,fpOut);fwrite(&bicompression,4,1,fpOut);fwrite(&bisizeimage,4,1,fpOut);fwrite(&bix,4,1,fpOut);fwrite(&biy,4,1,fpOut);fwrite(&biclrused,4,1,fpOut);fwrite(&biclrimportant,4,1,fpOut);////////////////////////////////////////////// ///////////////////////////////iWidth=(iCol*3+3)/4*4;//为什么?cR=(char *)malloc(iWidth*sizeof(char)*iRow); lpsData=(char *)malloc(600*sizeof(char));////////////////////////////fseek(fpIn,600*600*1,0);for(i=0;i<iRow;i++){fread(lpsData,1,600,fpIn);for(j=0;j<iCol;j++)//600{iL=(iRow-1-i)*iWidth+j*3;sTemp=lpsData[j];//[750+j*5+0];cR[iL]=sTemp*2;}}fseek(fpIn,600*600*2,0);for(i=0;i<iRow;i++){fread(lpsData,1,600,fpIn);for(j=0;j<iCol;j++)//600{iL=(iRow-1-i)*iWidth+j*3+1;sTemp=lpsData[j];//[750+j*5+0];cR[iL]=sTemp*2;}}fseek(fpIn,600*600*3,0);for(i=0;i<iRow;i++){fread(lpsData,1,600,fpIn);for(j=0;j<iCol;j++)//600{iL=(iRow-1-i)*iWidth+j*3+2;sTemp=lpsData[j];//[750+j*5+0];cR[iL]=sTemp*2;}}fwrite(cR,sizeof(char),iWidth*iRow,fpOut); free(cR);free(lpsData);fclose(fpOut);fclose(fpIn);}。

C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)

C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)

C#图像处理(各种旋转、改变⼤⼩、柔化、锐化、雾化、底⽚、浮雕、⿊⽩、滤镜效果)⼀、各种旋转、改变⼤⼩注意:先要添加画图相关的using引⽤。

//向右旋转图像90°代码如下:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");//加载图像g.FillRectangle(Brushes.White, this.ClientRectangle);//填充窗体背景为⽩⾊Point[] destinationPoints = {new Point(100, 0), // destination for upper-left point of originalnew Point(100, 100),// destination for upper-right point of originalnew Point(0, 0)}; // destination for lower-left point of originalg.DrawImage(bmp, destinationPoints);}//旋转图像180°代码如下:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");g.FillRectangle(Brushes.White, this.ClientRectangle);Point[] destinationPoints = {new Point(0, 100), // destination for upper-left point of originalnew Point(100, 100),// destination for upper-right point of originalnew Point(0, 0)}; // destination for lower-left point of originalg.DrawImage(bmp, destinationPoints);}//图像切变代码:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");g.FillRectangle(Brushes.White, this.ClientRectangle);Point[] destinationPoints = {new Point(0, 0), // destination for upper-left point of originalnew Point(100, 0), // destination for upper-right point of originalnew Point(50, 100)};// destination for lower-left point of originalg.DrawImage(bmp, destinationPoints);}//图像截取:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");g.FillRectangle(Brushes.White, this.ClientRectangle);Rectangle sr = new Rectangle(80, 60, 400, 400);//要截取的矩形区域Rectangle dr = new Rectangle(0, 0, 200, 200);//要显⽰到Form的矩形区域g.DrawImage(bmp, dr, sr, GraphicsUnit.Pixel);}//改变图像⼤⼩:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");g.FillRectangle(Brushes.White, this.ClientRectangle);int width = bmp.Width;int height = bmp.Height;// 改变图像⼤⼩使⽤低质量的模式g.InterpolationMode = InterpolationMode.NearestNeighbor;g.DrawImage(bmp, new Rectangle(10, 10, 120, 120), // source rectanglenew Rectangle(0, 0, width, height), // destination rectangleGraphicsUnit.Pixel);// 使⽤⾼质量模式//positingQuality = CompositingQuality.HighSpeed;g.InterpolationMode = InterpolationMode.HighQualityBicubic;g.DrawImage(bmp,new Rectangle(130, 10, 120, 120),new Rectangle(0, 0, width, height),GraphicsUnit.Pixel);}//设置图像的分辩率:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Bitmap bmp = new Bitmap("rama.jpg");g.FillRectangle(Brushes.White, this.ClientRectangle);bmp.SetResolution(300f, 300f);g.DrawImage(bmp, 0, 0);bmp.SetResolution(1200f, 1200f);g.DrawImage(bmp, 180, 0);}//⽤GDI+画图private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics gForm = e.Graphics;gForm.FillRectangle(Brushes.White, this.ClientRectangle);for (int i = 1; i <= 7; ++i){//在窗体上⾯画出橙⾊的矩形Rectangle r = new Rectangle(i*40-15, 0, 15,this.ClientRectangle.Height);gForm.FillRectangle(Brushes.Orange, r);}//在内存中创建⼀个Bitmap并设置CompositingModeBitmap bmp = new Bitmap(260, 260,System.Drawing.Imaging.PixelFormat.Format32bppArgb);Graphics gBmp = Graphics.FromImage(bmp);positingMode = positingMode.SourceCopy; // 创建⼀个带有Alpha的红⾊区域// 并将其画在内存的位图⾥⾯Color red = Color.FromArgb(0x60, 0xff, 0, 0);Brush redBrush = new SolidBrush(red);gBmp.FillEllipse(redBrush, 70, 70, 160, 160);// 创建⼀个带有Alpha的绿⾊区域Color green = Color.FromArgb(0x40, 0, 0xff, 0);Brush greenBrush = new SolidBrush(green);gBmp.FillRectangle(greenBrush, 10, 10, 140, 140);//在窗体上⾯画出位图 now draw the bitmap on our windowgForm.DrawImage(bmp, 20, 20, bmp.Width, bmp.Height);// 清理资源bmp.Dispose();gBmp.Dispose();redBrush.Dispose();greenBrush.Dispose();}//在窗体上⾯绘图并显⽰图像private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;Pen blackPen = new Pen(Color.Black, 1);if (ClientRectangle.Height / 10 > 0){for (int y = 0; y < ClientRectangle.Height; y += ClientRectangle.Height / 10){g.DrawLine(blackPen, new Point(0, 0), new Point(ClientRectangle.Width, y));}}blackPen.Dispose();}C# 使⽤Bitmap类进⾏图⽚裁剪在Mapwin(⼿机游戏地图编辑器)⽣成的地图txt⽂件中添加⾃⼰需要处理的数据后转换成可在⼿机(Ophone)开发环境中使⽤的字节流地图⽂件的⼩⼯具,其中就涉及到图⽚的裁剪和⽣成了。

C语言实现BMP转换JPG

C语言实现BMP转换JPG

101 lineData[j*3+1] = data[rgb_index];
102 rgb_index ++;
103 lineData[j*3+0] = data[rgb_index];
104 rgb_index ++;
jpeg.c
view sourceprint?001 /****************************************************************************
002 名称: jpeg.c
003 功能: linux下bmp转化为jpeg程序源代码
114 }
115 free(row_pointer);
116 free(data);
117 fclose(fd);
118 fclose(outfile);
119
120 return 0;
074
075 cinfo.image_width = width; //* image width and height, in pixels
076 cinfo.image_height = height;
077 cinfo.input_components = depth; //* # of color components per pixel
105 }
106 row_pointer[height-i-1] = lineData;
107 }
108 jpeg_write_scanlines(&cinfo, row_pointer, height);
026 {

C语言读取BMP格式图片

C语言读取BMP格式图片

典型的位图文件格式通常包含下面几个数据块:

位图头:保存位图文件的总体信息。 位图信息:保存位图图像的详细信息。 调色板:保存所用颜色的定义。 位图数据:保存一个又一个像素的实际图像。
下面的部分将会详细地描述位图文件中保存的数据。 需要注意的是这是标准位图 的文件格式, 其他一些位图图像可能根据生成文件的应用程序不同所使用格式可 能会有细微的区别。 位图头 这部分是识别信息, 典型的应用程序会首先普通读取这部分数据以确保的确是位 图文件并且没有损坏。
BMP 文件大小 度(width)都以像素为单位。 需要注意的是上面公式中的 54 是位图文件的文件头,
, 其中高度(height)和宽
是彩色调色板的大
小。 如果位图文件不包含调色板,如 24 位,32 位位图,则位图的近似字节数 可以用下面的公式计算:
BMP 文件大小 都以像素为单位。
,其中高度(height)和宽度(wimp 文件格式的描述,就不难发现,读取 bmp 大致只需要用到 fseek,fopen,fread 等函数即可以完成,下面我给出相应的 C 代码,读取的图像头文件信息主要是 offset,width,height,数据信息主要是 r[][],g[][],b[][],同时把数据输出到相应的 txt 文件中。
FILE *fpbmp; FILE *fpout;
fpbmp= fopen("1.bmp", "rb"); if (fpbmp == NULL) { printf("Open bmp failed!!!\n"); return 1; }
fpout= fopen("out.bmp", "wb+"); if (fpout == NULL) { printf("Open out.bmp failed!!!\n"); return 1; }

软件课程设计-C语言实现BMP图像显示

软件课程设计-C语言实现BMP图像显示
b)拓展任务:实现图像的特效显示(淡入淡出,百页窗等等)。
1.2进度情况:
A、我对BMP图像的了解
BMP文件是标准的Windows位图文件,有16色、256色、16位真彩色及24位真彩色等格式。客观存在按文件头、图像控制信息、彩色表和位图点阵数据的格式来存储。文件头是定义图像文件的类型、长度等的数据结构:图像控制信息是定义图像颜色格式、图像大小、颜色数等的数据结构:彩色表是定义图像颜色的调色板的数组位图点阵,是定义图像数据的数组。
Ⅱ定义函数,读取文件头和信息头
Ⅲ定义各个像素BMP图像的显示函数
ⅰ32bit BMP图像的显示函数
⑴定义文件指针
⑵用fopen打开图像文件
⑶利用fseek函数将文件内部指针移到位图数据区,跳过信息头部分
⑷用fread函数将颜色信息读取出来,存放在INT32U型的变量color中
⑸调用画点函数GFMSetPixels,把color中的颜色信息显示在画布上
但是它位图数据的1bit对应了调色板中的一个颜色数据,不正好是1个字节,故也应当对取出的位图数据做一些处理。
⑴定义文件指针
⑵定义存放调色板颜色数据的数组colorboard[2],定义循环变量i,j和颜色变量color等
⑶用fopen打开图像文件
⑷利用fseek函数将文件内部指针移到调色板数据区,跳过信息头部分
for(k=0;k<8;k++)
{
pcolor1=pcolor>>(7-k)&0x01;//取读出的数据的一位
color=colorboard[pcolor1];//对应到调色板的一个颜色
if(j<point->bmpwidth)
GFMSetPixels(color,8*j+k,point->bmpheight-i,1);

C语言BMP图片处理

C语言BMP图片处理

C语言 BMP图片处理BMP是bitmap的缩写形式,bitmap顾名思义,就是位图也即Windows位图。

它一般由4部分组成:文件头信息块、图像描述信息块、颜色表(在真彩色模式无颜色表)和图像数据区组成。

在系统中以BMP为扩展名保存。

打开Windows的画图程序,在保存图像时,可以看到三个选项:2色位图(黑白)、16色位图、256色位图和24位位图。

这是最普通的生成位图的工具,在这里讲解的BMP位图形式,主要就是指用画图生成的位图(当然,也可以用其它工具软件生成)。

现在讲解BMP的4个组成部分:1.文件头信息块0000-0001:文件标识,为字母ASCII码“BM”。

0002-0005:文件大小。

填写。

0006-0009:保留,每字节以“00”000A-000D:记录图像数据区的起始位置。

各字节的信息依次含义为:文件头信息块大小,图像描述信息块的大小,图像颜色表的大小,保留(为01)。

2.图像描述信息块000E-0011:图像描述信息块的大小,常为28H。

0012-0015:图像宽度。

0016-0019:图像高度。

001A-001B:图像的plane(平面?)总数(恒为1)。

001C-001D:记录像素的位数,很重要的数值,图像的颜色数由该值决定。

001E-0021:数据压缩方式(数值位0:不压缩;1:8位压缩;2:4位压缩)。

0022-0025:图像区数据的大小。

0026-0029:水平每米有多少像素,在设备无关位图(.DIB)中,每字节以00H 填写。

002A-002D:垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以00H 填写。

002E-0031:此图像所用的颜色数,如值为0,表示所有颜色一样重要。

3.颜色表颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。

其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(像素的透明度值,一般不需要)。

C#图片处理之:旋转图片任意角度.

C#图片处理之:旋转图片任意角度.

C#图⽚处理之:旋转图⽚任意⾓度.拍摄的数码相⽚偶尔也有拍歪的时候。

没关系,我们还是可以⽤C#来处理图⽚。

/// <summary>/// 任意⾓度旋转/// </summary>/// <param name="bmp">原始图Bitmap</param>/// <param name="angle">旋转⾓度</param>/// <param name="bkColor">背景⾊</param>/// <returns>输出Bitmap</returns>public static Bitmap KiRotate(Bitmap bmp, float angle, Color bkColor)...{int w = bmp.Width + 2;int h = bmp.Height + 2;PixelFormat pf;if (bkColor == Color.Transparent)...{pf = PixelFormat.Format32bppArgb;}else...{pf = bmp.PixelFormat;}Bitmap tmp = new Bitmap(w, h, pf);Graphics g = Graphics.FromImage(tmp);g.Clear(bkColor);g.DrawImageUnscaled(bmp, 1, 1);g.Dispose();GraphicsPath path = new GraphicsPath();path.AddRectangle(new RectangleF(0f, 0f, w, h));Matrix mtrx = new Matrix();mtrx.Rotate(angle);RectangleF rct = path.GetBounds(mtrx);Bitmap dst = new Bitmap((int)rct.Width, (int)rct.Height, pf);g = Graphics.FromImage(dst);g.Clear(bkColor);g.TranslateTransform(-rct.X, -rct.Y);g.RotateTransform(angle);g.InterpolationMode = InterpolationMode.HighQualityBilinear;g.DrawImageUnscaled(tmp, 0, 0);g.Dispose();tmp.Dispose();return dst;}最近论坛⾥好像有观点认为C#不适合做图⽚处理。

BMP图片转JPEG图片C程序源代码

BMP图片转JPEG图片C程序源代码

// A BMP truecolor to JPEG encoder// Copyright 1999 Cristian Cuturicu #include <stdio.h>#include <stdlib.h>#include <string.h>#include "jtypes.h"#include "jglobals.h"#include "jtables.h"void write_APP0info()//Nothing to overwrite for APP0info{writeword(APP0info.marker);writeword(APP0info.length);writebyte('J');writebyte('F');writebyte('I');writebyte('F');writebyte(0);writebyte(APP0info.versionhi);writebyte(APP0info.versionlo);writebyte(APP0info.xyunits);writeword(APP0info.xdensity);writeword(APP0info.ydensity);writebyte(APP0info.thumbnwidth);writebyte(APP0info.thumbnheight);}void write_SOF0info()// We should overwrite width and height{writeword(SOF0info.marker);writeword(SOF0info.length);writebyte(SOF0info.precision);writeword(SOF0info.height);writeword(SOF0info.width);writebyte(SOF0info.nrofcomponents);writebyte(SOF0info.IdY);writebyte(SOF0info.HVY);writebyte(SOF0info.QTY);writebyte(SOF0info.IdCb);writebyte(SOF0info.HVCb);writebyte(SOF0info.QTCb);writebyte(SOF0info.IdCr);writebyte(SOF0info.HVCr);writebyte(SOF0info.QTCr);}void write_DQTinfo(){BYTE i;writeword(DQTinfo.marker);writeword(DQTinfo.length);writebyte(DQTinfo.QTYinfo);for (i=0; i<64; i++)writebyte(DQTinfo.Ytable[i]);writebyte(DQTinfo.QTCbinfo);for (i=0; i<64; i++)writebyte(DQTinfo.Cbtable[i]);}void set_quant_table(BYTE *basic_table, BYTE scale_factor, BYTE *newtable)// Set quantization table and zigzag reorder it{BYTE i;long temp;for (i=0; i<64; i++){temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;// limit the values to the valid rangeif (temp <= 0L)temp = 1L;if (temp > 255L)temp = 255L;newtable[zigzag[i]] = (BYTE) temp;}}void set_DQTinfo(){BYTE scalefactor = 50;// scalefactor controls the visual quality of the image// the smaller is the better image we'll get, and the smaller// compression we'll achieveDQTinfo.marker = 0xFFDB;DQTinfo.length = 132;DQTinfo.QTYinfo = 0;DQTinfo.QTCbinfo = 1;set_quant_table(std_luminance_qt, scalefactor, DQTinfo.Ytable);set_quant_table(std_chrominance_qt, scalefactor, DQTinfo.Cbtable);}void write_DHTinfo(){BYTE i;writeword(DHTinfo.marker);writeword(DHTinfo.length);writebyte(DHTinfo.HTYDCinfo);for (i=0; i<16; i++)writebyte(DHTinfo.YDC_nrcodes[i]);for (i=0; i<12; i++)writebyte(DHTinfo.YDC_values[i]);writebyte(DHTinfo.HTYACinfo);for (i=0; i<16; i++)writebyte(DHTinfo.YAC_nrcodes[i]);for (i=0; i<162; i++)writebyte(DHTinfo.YAC_values[i]);writebyte(DHTinfo.HTCbDCinfo);for (i=0; i<16; i++)writebyte(DHTinfo.CbDC_nrcodes[i]);for (i=0; i<12; i++)writebyte(DHTinfo.CbDC_values[i]);writebyte(DHTinfo.HTCbACinfo);for (i=0; i<16; i++)writebyte(DHTinfo.CbAC_nrcodes[i]);for (i=0; i<162; i++)writebyte(DHTinfo.CbAC_values[i]);}void set_DHTinfo(){BYTE i;// fill the DHTinfo structure [get the values from the standard Huffman tables]DHTinfo.marker = 0xFFC4;DHTinfo.length = 0x01A2;DHTinfo.HTYDCinfo = 0;for (i=0; i<16; i++)DHTinfo.YDC_nrcodes[i] = std_dc_luminance_nrcodes[i+1];for (i=0; i<12; i++)DHTinfo.YDC_values[i] = std_dc_luminance_values[i];DHTinfo.HTYACinfo = 0x10;for (i=0; i<16; i++)DHTinfo.YAC_nrcodes[i] = std_ac_luminance_nrcodes[i+1];for (i=0; i<162; i++)DHTinfo.YAC_values[i] = std_ac_luminance_values[i];DHTinfo.HTCbDCinfo = 1;for (i=0; i<16; i++)DHTinfo.CbDC_nrcodes[i] = std_dc_chrominance_nrcodes[i+1];for (i=0; i<12; i++)DHTinfo.CbDC_values[i] = std_dc_chrominance_values[i];DHTinfo.HTCbACinfo = 0x11;for (i=0; i<16; i++)DHTinfo.CbAC_nrcodes[i] = std_ac_chrominance_nrcodes[i+1];for (i=0; i<162; i++)DHTinfo.CbAC_values[i] = std_ac_chrominance_values[i];}void write_SOSinfo()//Nothing to overwrite for SOSinfo{writeword(SOSinfo.marker);writeword(SOSinfo.length);writebyte(SOSinfo.nrofcomponents);writebyte(SOSinfo.IdY);writebyte(SOSinfo.HTY);writebyte(SOSinfo.IdCb);writebyte(SOSinfo.HTCb);writebyte(SOSinfo.IdCr);writebyte(SOSinfo.HTCr);writebyte(SOSinfo.Ss);writebyte(SOSinfo.Se);writebyte(SOSinfo.Bf);}void write_comment(BYTE *comment){WORD i, length;writeword(0xFFFE); // The COM markerlength = strlen((const char *)comment);writeword(length + 2);for (i=0; i<length; i++)writebyte(comment[i]);}void writebits(bitstring bs)// A portable version; it should be done in assembler{WORD value;SBYTE posval;// bit position in the bitstring we read, should be <=15 and >=0value = bs.value;posval = bs.length - 1;while (posval >= 0){if (value & mask[posval])bytenew |= mask[bytepos];posval--;bytepos--;if (bytepos < 0){// write itif (bytenew == 0xFF){// special casewritebyte(0xFF);writebyte(0);}elsewritebyte(bytenew);// reinitbytepos = 7;bytenew = 0;}}}void compute_Huffman_table(BYTE *nrcodes, BYTE *std_table, bitstring *HT){BYTE k,j;BYTE pos_in_table;WORD codevalue;codevalue = 0;pos_in_table = 0;for (k=1; k<=16; k++){for (j=1; j<=nrcodes[k]; j++){HT[std_table[pos_in_table]].value = codevalue;HT[std_table[pos_in_table]].length = k;pos_in_table++;codevalue++;}codevalue <<= 1;}}void init_Huffman_tables(){// Compute the Huffman tables used for encodingcompute_Huffman_table(std_dc_luminance_nrcodes, std_dc_luminance_values, YDC_HT);compute_Huffman_table(std_ac_luminance_nrcodes, std_ac_luminance_values, YAC_HT);compute_Huffman_table(std_dc_chrominance_nrcodes, std_dc_chrominance_values, CbDC_HT);compute_Huffman_table(std_ac_chrominance_nrcodes, std_ac_chrominance_values, CbAC_HT); }void exitmessage(char *error_message){printf("%s\n",error_message);exit(EXIT_FAILURE);}void set_numbers_category_and_bitcode(){SDWORD nr;SDWORD nrlower, nrupper;BYTE cat;category_alloc = (BYTE *)malloc(65535*sizeof(BYTE));if (category_alloc == NULL)exitmessage("Not enough memory.");//allow negative subscriptscategory = category_alloc + 32767;bitcode_alloc=(bitstring *)malloc(65535*sizeof(bitstring));if (bitcode_alloc==NULL)exitmessage("Not enough memory.");bitcode = bitcode_alloc + 32767;nrlower = 1;nrupper = 2;for (cat=1; cat<=15; cat++){//Positive numbersfor (nr=nrlower; nr<nrupper; nr++){category[nr] = cat;bitcode[nr].length = cat;bitcode[nr].value = (WORD)nr;}//Negative numbersfor (nr=-(nrupper-1); nr<=-nrlower; nr++){category[nr] = cat;bitcode[nr].length = cat;bitcode[nr].value = (WORD)(nrupper-1+nr);}nrlower <<= 1;nrupper <<= 1;}}void precalculate_YCbCr_tables(){WORD R,G,B;for (R=0; R<256; R++){YRtab[R] = (SDWORD)(65536*0.299+0.5)*R;CbRtab[R] = (SDWORD)(65536*-0.16874+0.5)*R;CrRtab[R] = (SDWORD)(32768)*R;}for (G=0; G<256; G++){YGtab[G] = (SDWORD)(65536*0.587+0.5)*G;CbGtab[G] = (SDWORD)(65536*-0.33126+0.5)*G;CrGtab[G] = (SDWORD)(65536*-0.41869+0.5)*G;}for (B=0; B<256; B++){YBtab[B] = (SDWORD)(65536*0.114+0.5)*B;CbBtab[B] = (SDWORD)(32768)*B;CrBtab[B] = (SDWORD)(65536*-0.08131+0.5)*B;}}// Using a bit modified form of the FDCT routine from IJG's C source:// Forward DCT routine idea taken from Independent JPEG Group's C source for// JPEG encoders/decoders/* For float AA&N IDCT method, divisors are equal to quantization coefficients scaled by scalefactor[row]*scalefactor[col], wherescalefactor[0] = 1scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7We apply a further scale factor of 8.What's actually stored is 1/divisor so that the inner loop canuse a multiplication rather than a division. */void prepare_quant_tables(){double aanscalefactor[8] = {1.0, 1.387039845, 1.306562965, 1.175875602,1.0, 0.785694958, 0.541196100, 0.275899379};BYTE row, col;BYTE i = 0;for (row = 0; row < 8; row++){for (col = 0; col < 8; col++){fdtbl_Y[i] = (float) (1.0 / ((double) DQTinfo.Ytable[zigzag[i]] *aanscalefactor[row] * aanscalefactor[col] * 8.0));fdtbl_Cb[i] = (float) (1.0 / ((double) DQTinfo.Cbtable[zigzag[i]] *aanscalefactor[row] * aanscalefactor[col] * 8.0));i++;}}}void fdct_and_quantization(SBYTE *data, float *fdtbl, SWORD *outdata){float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;float tmp10, tmp11, tmp12, tmp13;float z1, z2, z3, z4, z5, z11, z13;float *dataptr;float datafloat[64];float temp;SBYTE ctr;BYTE i;for (i=0; i<64; i++)datafloat[i] = data[i];/* Pass 1: process rows. */dataptr = datafloat;for (ctr = 7; ctr >= 0; ctr--){tmp0 = dataptr[0] + dataptr[7];tmp7 = dataptr[0] - dataptr[7];tmp1 = dataptr[1] + dataptr[6];tmp6 = dataptr[1] - dataptr[6];tmp2 = dataptr[2] + dataptr[5];tmp5 = dataptr[2] - dataptr[5];tmp3 = dataptr[3] + dataptr[4];tmp4 = dataptr[3] - dataptr[4];/* Even part */tmp10 = tmp0 + tmp3; /* phase 2 */tmp13 = tmp0 - tmp3;tmp11 = tmp1 + tmp2;tmp12 = tmp1 - tmp2;dataptr[0] = tmp10 + tmp11; /* phase 3 */dataptr[4] = tmp10 - tmp11;z1 = (tmp12 + tmp13) * ((float) 0.707106781); /* c4 */dataptr[2] = tmp13 + z1; /* phase 5 */dataptr[6] = tmp13 - z1;/* Odd part */tmp10 = tmp4 + tmp5; /* phase 2 */tmp11 = tmp5 + tmp6;tmp12 = tmp6 + tmp7;/* The rotator is modified from fig 4-8 to avoid extra negations. */z5 = (tmp10 - tmp12) * ((float) 0.382683433); /* c6 */z2 = ((float) 0.541196100) * tmp10 + z5; /* c2-c6 */z4 = ((float) 1.306562965) * tmp12 + z5; /* c2+c6 */z3 = tmp11 * ((float) 0.707106781); /* c4 */z11 = tmp7 + z3; /* phase 5 */z13 = tmp7 - z3;dataptr[5] = z13 + z2; /* phase 6 */dataptr[3] = z13 - z2;dataptr[1] = z11 + z4;dataptr[7] = z11 - z4;dataptr += 8; /* advance pointer to next row */ }/* Pass 2: process columns. */dataptr = datafloat;for (ctr = 7; ctr >= 0; ctr--){tmp0 = dataptr[0] + dataptr[56];tmp7 = dataptr[0] - dataptr[56];tmp1 = dataptr[8] + dataptr[48];tmp6 = dataptr[8] - dataptr[48];tmp2 = dataptr[16] + dataptr[40];tmp5 = dataptr[16] - dataptr[40];tmp3 = dataptr[24] + dataptr[32];tmp4 = dataptr[24] - dataptr[32];/* Even part */tmp10 = tmp0 + tmp3; /* phase 2 */tmp13 = tmp0 - tmp3;tmp11 = tmp1 + tmp2;tmp12 = tmp1 - tmp2;dataptr[0] = tmp10 + tmp11; /* phase 3 */dataptr[32] = tmp10 - tmp11;z1 = (tmp12 + tmp13) * ((float) 0.707106781); /* c4 */dataptr[16] = tmp13 + z1; /* phase 5 */dataptr[48] = tmp13 - z1;/* Odd part */tmp10 = tmp4 + tmp5; /* phase 2 */tmp11 = tmp5 + tmp6;tmp12 = tmp6 + tmp7;/* The rotator is modified from fig 4-8 to avoid extra negations. */z5 = (tmp10 - tmp12) * ((float) 0.382683433); /* c6 */z2 = ((float) 0.541196100) * tmp10 + z5; /* c2-c6 */z4 = ((float) 1.306562965) * tmp12 + z5; /* c2+c6 */z3 = tmp11 * ((float) 0.707106781); /* c4 */z11 = tmp7 + z3; /* phase 5 */z13 = tmp7 - z3;dataptr[40] = z13 + z2; /* phase 6 */dataptr[24] = z13 - z2;dataptr[8] = z11 + z4;dataptr[56] = z11 - z4;dataptr++; /* advance pointer to next column */ }/* Quantize/descale the coefficients, and store into output array */for (i = 0; i < 64; i++){/* Apply the quantization and scaling factor */temp = datafloat[i] * fdtbl[i];/* Round to nearest integer.Since C does not specify the direction of rounding for negativequotients, we have to force the dividend positive for portability.The maximum coefficient size is +-16K (for 12-bit data), so thiscode should work for either 16-bit or 32-bit ints.*/outdata[i] = (SWORD) ((SWORD)(temp + 16384.5) - 16384);}}void process_DU(SBYTE *ComponentDU,float *fdtbl,SWORD *DC,bitstring *HTDC,bitstring *HTAC){bitstring EOB = HTAC[0x00];bitstring M16zeroes = HTAC[0xF0];BYTE i;BYTE startpos;BYTE end0pos;BYTE nrzeroes;BYTE nrmarker;SWORD Diff;fdct_and_quantization(ComponentDU, fdtbl, DU_DCT);// zigzag reorderfor (i=0; i<64; i++)DU[zigzag[i]]=DU_DCT[i];// Encode DCDiff = DU[0] - *DC;*DC = DU[0];if (Diff == 0)writebits(HTDC[0]); //Diff might be 0else{writebits(HTDC[category[Diff]]);writebits(bitcode[Diff]);}// Encode ACsfor (end0pos=63; (end0pos>0)&&(DU[end0pos]==0); end0pos--) ;//end0pos = first element in reverse order != 0i = 1;while (i <= end0pos){startpos = i;for (; (DU[i]==0) && (i<=end0pos); i++) ;nrzeroes = i - startpos;if (nrzeroes >= 16){for (nrmarker=1; nrmarker<=nrzeroes/16; nrmarker++)writebits(M16zeroes);nrzeroes = nrzeroes%16;}writebits(HTAC[nrzeroes*16+category[DU[i]]]);writebits(bitcode[DU[i]]);i++;}if (end0pos != 63)writebits(EOB);}void load_data_units_from_RGB_buffer(WORD xpos, WORD ypos){BYTE x, y;BYTE pos = 0;DWORD location;BYTE R, G, B;location = ypos * width + xpos;for (y=0; y<8; y++){for (x=0; x<8; x++){R = RGB_buffer[location].R;G = RGB_buffer[location].G;B = RGB_buffer[location].B;// convert to YCbCrYDU[pos] = Y(R,G,B);CbDU[pos] = Cb(R,G,B);CrDU[pos] = Cr(R,G,B);location++;pos++;}location += width - 8;}}void main_encoder(){SWORD DCY = 0, DCCb = 0, DCCr = 0; //DC coefficients used for differential encoding WORD xpos, ypos;for (ypos=0; ypos<height; ypos+=8){for (xpos=0; xpos<width; xpos+=8){load_data_units_from_RGB_buffer(xpos, ypos);process_DU(YDU, fdtbl_Y, &DCY, YDC_HT, YAC_HT);process_DU(CbDU, fdtbl_Cb, &DCCb, CbDC_HT, CbAC_HT);process_DU(CrDU, fdtbl_Cb, &DCCr, CbDC_HT, CbAC_HT);}}}void load_bitmap(char *bitmap_name, WORD *width_original, WORD *height_original){WORD widthDiv8, heightDiv8; // closest multiple of 8 [ceil]BYTE nr_fillingbytes;//The number of the filling bytes in the BMP file// (the dimension in bytes of a BMP line on the disk is divisible by 4)colorRGB lastcolor;WORD column;BYTE TMPBUF[256];WORD nrline_up, nrline_dn, nrline;WORD dimline;colorRGB *tmpline;FILE *fp_bitmap = fopen(bitmap_name,"rb");if (fp_bitmap==NULL)exitmessage("Cannot open bitmap file.File not found ?");if (fread(TMPBUF, 1, 54, fp_bitmap) != 54)exitmessage("Need a truecolor BMP to encode.");if ((TMPBUF[0]!='B')||(TMPBUF[1]!='M')||(TMPBUF[28]!=24))exitmessage("Need a truecolor BMP to encode.");width = (WORD)TMPBUF[19]*256+TMPBUF[18];height = (WORD)TMPBUF[23]*256+TMPBUF[22];// Keep the old dimensions of the image*width_original = width;*height_original = height;if (width%8 != 0)widthDiv8 = (width/8)*8+8;elsewidthDiv8 = width;if (height%8 != 0)heightDiv8 = (height/8)*8+8;elseheightDiv8 = height;// The image we encode shall be filled with the last line and the last column// from the original bitmap, until width and height are divisible by 8// Load BMP image from disk and complete XRGB_buffer = (colorRGB *)(malloc(3*widthDiv8*heightDiv8));if (RGB_buffer == NULL)exitmessage("Not enough memory for the bitmap image.");if ( (width*3)%4 != 0)nr_fillingbytes = 4 - ( (width*3)%4);elsenr_fillingbytes = 0;for (nrline=0; nrline<height; nrline++){fread(RGB_buffer + nrline*widthDiv8, 1, width*3, fp_bitmap);fread(TMPBUF, 1, nr_fillingbytes, fp_bitmap);// complete Xmemcpy(&lastcolor, RGB_buffer + nrline*widthDiv8 + width-1, 3);for (column=width; column<widthDiv8; column++)memcpy(RGB_buffer+nrline*widthDiv8+column, &lastcolor, 3);}width = widthDiv8;dimline = width*3;tmpline = (colorRGB *)malloc(dimline);if (tmpline == NULL)exitmessage("Not enough memory.");// Reorder in memory the inversed bitmapfor (nrline_up=height-1,nrline_dn=0; nrline_up>nrline_dn; nrline_up--,nrline_dn++){memcpy(tmpline, RGB_buffer+nrline_up*width, dimline);memcpy(RGB_buffer+nrline_up*width, RGB_buffer+nrline_dn*width, dimline);memcpy(RGB_buffer+nrline_dn*width, tmpline, dimline);}// Y completion:memcpy(tmpline, RGB_buffer+(height-1)*width, dimline);for (nrline=height; nrline<heightDiv8; nrline++)memcpy(RGB_buffer+nrline*width, tmpline, dimline);height = heightDiv8;free(tmpline);fclose(fp_bitmap);}void init_all(){set_DQTinfo();set_DHTinfo();init_Huffman_tables();set_numbers_category_and_bitcode();precalculate_YCbCr_tables();prepare_quant_tables();}void main(int argc, char *argv[]){char BMP_filename[64];char JPG_filename[64];WORD width_original,height_original; //the original image dimensions, // before we made them divisible by 8BYTE len_filename;bitstring fillbits; //filling bitstring for the bit alignment of the EOI markerif (argc>1){strcpy(BMP_filename,argv[1]);if (argc>2)strcpy(JPG_filename,argv[2]);else{// replace ".bmp" with ".jpg"strcpy(JPG_filename, BMP_filename);len_filename=strlen(BMP_filename);strcpy(JPG_filename+(len_filename-3),"jpg");}}elseexitmessage("Syntax: enc fis.bmp [fis.jpg]");load_bitmap(BMP_filename, &width_original, &height_original);fp_jpeg_stream = fopen(JPG_filename,"wb");init_all();SOF0info.width = width_original;SOF0info.height = height_original;writeword(0xFFD8); // SOIwrite_APP0info();// write_comment("Cris made this JPEG with his own encoder");write_DQTinfo();write_SOF0info();write_DHTinfo();write_SOSinfo();// init global variablesbytenew = 0; // current bytebytepos = 7; // bit position in this bytemain_encoder();// Do the bit alignment of the EOI markerif (bytepos >= 0){fillbits.length = bytepos + 1;fillbits.value = (1<<(bytepos+1)) - 1;writebits(fillbits);}writeword(0xFFD9); // EOIfree(RGB_buffer);free(category_alloc);free(bitcode_alloc);fclose(fp_jpeg_stream);}//JGLOBALS.Hstatic BYTE bytenew=0; // The byte that will be written in the JPG filestatic SBYTE bytepos=7; // bit position in the byte we write (bytenew)//should be<=7 and >=0static WORD mask[16]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768}; // The Huffman tables we'll use:static bitstring YDC_HT[12];static bitstring CbDC_HT[12];static bitstring YAC_HT[256];static bitstring CbAC_HT[256];static BYTE *category_alloc;static BYTE *category; //Here we'll keep the category of the numbers in range: -32767..32767 static bitstring *bitcode_alloc;static bitstring *bitcode; // their bitcoded representation//Precalculated tables for a faster YCbCr->RGB transformation// We use a SDWORD table because we'll scale values by 2^16 and work with integersstatic SDWORD YRtab[256],YGtab[256],YBtab[256];static SDWORD CbRtab[256],CbGtab[256],CbBtab[256];static SDWORD CrRtab[256],CrGtab[256],CrBtab[256];static float fdtbl_Y[64];static float fdtbl_Cb[64]; //the same with the fdtbl_Cr[64]colorRGB *RGB_buffer; //image to be encodedWORD width, height;// image dimensions divisible by 8static SBYTE YDU[64]; // This is the Data Unit of Y after YCbCr->RGB transformation static SBYTE CbDU[64];static SBYTE CrDU[64];static SWORD DU_DCT[64]; // Current DU (after DCT and quantization) which we'll zigzag static SWORD DU[64]; //zigzag reordered DU which will be Huffman codedFILE *fp_jpeg_stream;//JTABLES.Hstatic BYTE zigzag[64]={ 0, 1, 5, 6,14,15,27,28,2, 4, 7,13,16,26,29,42,3, 8,12,17,25,30,41,43,9,11,18,24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 };/* These are the sample quantization tables given in JPEG spec section K.1.The spec says that the values given produce "good" quality, andwhen divided by 2, "very good" quality.*/static BYTE std_luminance_qt[64] = {16, 11, 10, 16, 24, 40, 51, 61,12, 12, 14, 19, 26, 58, 60, 55,14, 13, 16, 24, 40, 57, 69, 56,14, 17, 22, 29, 51, 87, 80, 62,18, 22, 37, 56, 68, 109, 103, 77,24, 35, 55, 64, 81, 104, 113, 92,49, 64, 78, 87, 103, 121, 120, 101,72, 92, 95, 98, 112, 100, 103, 99};static BYTE std_chrominance_qt[64] = {17, 18, 24, 47, 99, 99, 99, 99,18, 21, 26, 66, 99, 99, 99, 99,24, 26, 56, 99, 99, 99, 99, 99,47, 66, 99, 99, 99, 99, 99, 99,99, 99, 99, 99, 99, 99, 99, 99,99, 99, 99, 99, 99, 99, 99, 99,99, 99, 99, 99, 99, 99, 99, 99,99, 99, 99, 99, 99, 99, 99, 99};// Standard Huffman tables (cf. JPEG standard section K.3) */static BYTE std_dc_luminance_nrcodes[17]={0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0}; static BYTE std_dc_luminance_values[12]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};static BYTE std_dc_chrominance_nrcodes[17]={0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; static BYTE std_dc_chrominance_values[12]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};static BYTE std_ac_luminance_nrcodes[17]={0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d }; static BYTE std_ac_luminance_values[162]= {0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,0xf9, 0xfa };static BYTE std_ac_chrominance_nrcodes[17]={0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77}; static BYTE std_ac_chrominance_values[162]={0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,0xf9, 0xfa };//JTYPES.H#define BYTE unsigned char#define SBYTE signed char#define SWORD signed short int#define WORD unsigned short int#define DWORD unsigned long int#define SDWORD signed long intstatic struct APP0infotype {WORD marker;// = 0xFFE0WORD length; // = 16 for usual JPEG, no thumbnailBYTE JFIFsignature[5]; // = "JFIF",'\0'BYTE versionhi; // 1BYTE versionlo; // 1BYTE xyunits; // 0 = no units, normal densityWORD xdensity; // 1WORD ydensity; // 1BYTE thumbnwidth; // 0BYTE thumbnheight; // 0} APP0info={0xFFE0,16,'J','F','I','F',0,1,1,0,1,1,0,0};static struct SOF0infotype {WORD marker; // = 0xFFC0WORD length; // = 17 for a truecolor YCbCr JPGBYTE precision ;// Should be 8: 8 bits/sampleWORD height ;WORD width;BYTE nrofcomponents;//Should be 3: We encode a truecolor JPGBYTE IdY; // = 1BYTE HVY; // sampling factors for Y (bit 0-3 vert., 4-7 hor.)BYTE QTY; // Quantization Table number for Y = 0BYTE IdCb; // = 2BYTE HVCb;BYTE QTCb; // 1BYTE IdCr; // = 3BYTE HVCr;BYTE QTCr; // Normally equal to QTCb = 1} SOF0info = { 0xFFC0,17,8,0,0,3,1,0x11,0,2,0x11,1,3,0x11,1};// Default sampling factors are 1,1 for every image component: No downsampling static struct DQTinfotype {WORD marker; // = 0xFFDBWORD length; // = 132BYTE QTYinfo;// = 0: bit 0..3: number of QT = 0 (table for Y)// bit 4..7: precision of QT, 0 = 8 bit BYTE Ytable[64];BYTE QTCbinfo; // = 1 (quantization table for Cb,Cr}BYTE Cbtable[64];} DQTinfo;// Ytable from DQTinfo should be equal to a scaled and zizag reordered version// of the table which can be found in "tables.h": std_luminance_qt// Cbtable , similar = std_chrominance_qt// We'll init them in the program using set_DQTinfo functionstatic struct DHTinfotype {WORD marker; // = 0xFFC4WORD length; //0x01A2BYTE HTYDCinfo; // bit 0..3: number of HT (0..3), for Y =0//bit 4 :type of HT, 0 = DC table,1 = AC table//bit 5..7: not used, must be 0BYTE YDC_nrcodes[16]; //at index i = nr of codes with length iBYTE YDC_values[12];BYTE HTYACinfo; // = 0x10BYTE YAC_nrcodes[16];BYTE YAC_values[162];//we'll use the standard Huffman tablesBYTE HTCbDCinfo; // = 1BYTE CbDC_nrcodes[16];BYTE CbDC_values[12];BYTE HTCbACinfo; // = 0x11BYTE CbAC_nrcodes[16];BYTE CbAC_values[162];} DHTinfo;static struct SOSinfotype {WORD marker; // = 0xFFDAWORD length; // = 12BYTE nrofcomponents; // Should be 3: truecolor JPGBYTE IdY; //1BYTE HTY; //0 // bits 0..3: AC table (0..3)// bits 4..7: DC table (0..3)BYTE IdCb; //2BYTE HTCb; //0x11BYTE IdCr; //3BYTE HTCr; //0x11BYTE Ss,Se,Bf; // not interesting, they should be 0,63,0} SOSinfo={0xFFDA,12,3,1,0,2,0x11,3,0x11,0,0x3F,0};typedef struct { BYTE B,G,R; } colorRGB;typedef struct { BYTE length;WORD value;} bitstring;#define Y(R,G,B) ((BYTE)( (YRtab[(R)]+YGtab[(G)]+YBtab[(B)])>>16 ) - 128) #define Cb(R,G,B) ((BYTE)( (CbRtab[(R)]+CbGtab[(G)]+CbBtab[(B)])>>16 ) ) #define Cr(R,G,B) ((BYTE)( (CrRtab[(R)]+CrGtab[(G)]+CrBtab[(B)])>>16 ) )#define writebyte(b) fputc((b),fp_jpeg_stream)#define writeword(w) writebyte((w)/256);writebyte((w)%256);。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C语言BMP图片处理BMP是bitmap的缩写形式,bitmap顾名思义,就是位图也即Windows位图。

它一般由4部分组成:文件头信息块、图像描述信息块、颜色表(在真彩色模式无颜色表)和图像数据区组成。

在系统中以BMP为扩展名保存。

打开Windows的画图程序,在保存图像时,可以看到三个选项:2色位图(黑白)、16色位图、256色位图和24位位图。

这是最普通的生成位图的工具,在这里讲解的BMP位图形式,主要就是指用画图生成的位图(当然,也可以用其它工具软件生成)。

现在讲解BMP的4个组成部分:1.文件头信息块0000-0001:文件标识,为字母ASCII码“BM”。

0002-0005:文件大小。

0006-0009:保留,每字节以“00”填写。

000A-000D:记录图像数据区的起始位置。

各字节的信息依次含义为:文件头信息块大小,图像描述信息块的大小,图像颜色表的大小,保留(为01)。

2.图像描述信息块000E-0011:图像描述信息块的大小,常为28H。

0012-0015:图像宽度。

0016-0019:图像高度。

001A-001B:图像的plane(平面?)总数(恒为1)。

001C-001D:记录像素的位数,很重要的数值,图像的颜色数由该值决定。

001E-0021:数据压缩方式(数值位0:不压缩;1:8位压缩;2:4位压缩)。

0022-0025:图像区数据的大小。

0026-0029:水平每米有多少像素,在设备无关位图(.DIB)中,每字节以00H 填写。

002A-002D:垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以00H 填写。

002E-0031:此图像所用的颜色数,如值为0,表示所有颜色一样重要。

3.颜色表颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。

其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(像素的透明度值,一般不需要)。

即首先4字节表示颜色号0的颜色,接下来表示颜色号1的颜色,依此类推。

4.图像数据区颜色表接下来位为位图文件的图像数据区,在此部分记录着每点像素对应的颜色号,其记录方式也随颜色模式而定,既2色图像每点占1位(8位为1字节);16色图像每点占4位(半字节);256色图像每点占8位(1字节);真彩色图像每点占24位(3字节)。

所以,整个数据区的大小也会随之变化。

究其规律而言,可的出如下计算公式:图像数据信息大小=(图像宽度*图像高度*记录像素的位数)/8。

然而,未压缩的图像信息区的大小。

除了真彩色模式外,其余的均大于或等于数据信息的大小。

这是为什么呢?原因有两个:1.BMP文件记录一行图像是以字节为单位的。

因此,就不存在一个字节中的数据位信息表示的点在不同的两行中。

也就是说,设显示模式位16色,在每个字节分配两个点信息时,如果图像的宽度位奇数,那么最后一个像素点的信息将独占一个字节,这个字节的后4位将没有意义。

接下来的一个字节将开始记录下一行的信息。

2.为了显示的方便,除了真彩色外,其他的每中颜色模式的行字节数要用数据“00”补齐为4的整数倍。

如果显示模式为16色,当图像宽为19时,存储时每行则要补充4-(19/2+1)%4=2个字节(加1是因为里面有一个像素点要独占了一字节)。

如果显示模式为256色,当图像宽为19时,每行也要补充4-19%4=1个字节。

还有一点我要申明,当屏幕初始化为16或256色模式时,一定要设置调色板或修正颜色值,否则无法得到正确的图像颜色。

C代码//ReadBitMap//#include <string.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define WIDTHBYTES(bits) (((bits)+31)/32*4)typedef unsigned char BYTE;typedef unsigned short WORD;typedef unsigned long DWORD;typedef long LONG;//位图文件头信息结构定义//其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息)typedef struct tagBITMAPFILEHEADER {DWORD bfSize; //文件大小WORD bfReserved1; //保留字,不考虑WORD bfReserved2; //保留字,同上DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和} BITMAPFILEHEADER;//信息头BITMAPINFOHEADER,也是一个结构,其定义如下:typedef struct tagBITMAPINFOHEADER{//public:DWORD biSize; //指定此结构体的长度,为40LONG biWidth; //位图宽LONG biHeight; //位图高WORD biPlanes; //平面数,为1WORD biBitCount; //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32DWORD biCompression; //压缩方式,可以是0,1,2,其中0表示不压缩DWORD biSizeImage; //实际位图数据占用的字节数LONG biXPelsPerMeter; //X方向分辨率LONG biYPelsPerMeter; //Y方向分辨率DWORD biClrUsed; //使用的颜色数,如果为0,则表示默认值(2^颜色位数) DWORD biClrImportant; //重要颜色数,如果为0,则表示所有颜色都是重要的} BITMAPINFOHEADER;//调色板Palette,当然,这里是对那些需要调色板的位图文件而言的。

24位和32位是不需要调色板的。

//(似乎是调色板结构体个数等于使用的颜色数。

)typedef struct tagRGBQUAD {//public:BYTE rgbBlue; //该颜色的蓝色分量BYTE rgbGreen; //该颜色的绿色分量BYTE rgbRed; //该颜色的红色分量BYTE rgbReserved; //保留值} RGBQUAD;void showBmpHead(BITMAPFILEHEADER* pBmpHead)printf("位图文件头:\n");printf("文件大小:%d\n",pBmpHead->bfSize);printf("保留字:%d\n",pBmpHead->bfReserved1);printf("保留字:%d\n",pBmpHead->bfReserved2);printf("实际位图数据的偏移字节数:%d\n",pBmpHead->bfOffBits);}void showBmpInforHead(tagBITMAPINFOHEADER* pBmpInforHead){printf("位图信息头:\n");printf("结构体的长度:%d\n",pBmpInforHead->biSize);printf("位图宽:%d\n",pBmpInforHead->biWidth);printf("位图高:%d\n",pBmpInforHead->biHeight);printf("biPlanes平面数:%d\n",pBmpInforHead->biPlanes);printf("biBitCount采用颜色位数:%d\n",pBmpInforHead->biBitCount);printf("压缩方式:%d\n",pBmpInforHead->biCompression);printf("biSizeImage实际位图数据占用的字节数:%d\n",pBmpInforHead->biSizeImage);printf("X方向分辨率:%d\n",pBmpInforHead->biXPelsPerMeter);printf("Y方向分辨率:%d\n",pBmpInforHead->biYPelsPerMeter);printf("使用的颜色数:%d\n",pBmpInforHead->biClrUsed);printf("重要颜色数:%d\n",pBmpInforHead->biClrImportant);}void showRgbQuan(tagRGBQUAD* pRGB){printf("(%-3d,%-3d,%-3d) ",pRGB->rgbRed,pRGB->rgbGreen,pRGB->rgbBlue); }void main(){BITMAPFILEHEADER bitHead;BITMAPINFOHEADER bitInfoHead;FILE* pfile;char strFile[50];printf("please input the .bmp file name:\n");scanf("%s",strFile);pfile = fopen(strFile,"rb");//打开文件if(pfile!=NULL){printf("file bkwood.bmp open success.\n");//读取位图文件头信息WORD fileType;fread(&fileType,1,sizeof(WORD),pfile);if(fileType != 0x4d42){printf("file is not .bmp file!");return;}//fseek(pfile,2,SEEK_CUR); // "BM"fread(&bitHead,1,sizeof(tagBITMAPFILEHEADER),pfile);showBmpHead(&bitHead);printf("\n\n");//读取位图信息头信息fread(&bitInfoHead,1,sizeof(BITMAPINFOHEADER),pfile); showBmpInforHead(&bitInfoHead);printf("\n");}else{printf("file open fail!\n");return;}tagRGBQUAD *pRgb ;if(bitInfoHead.biBitCount < 24)//有调色板{//读取调色盘结信息long nPlantNum = long(pow(2,double(bitInfoHead.biBitCount))); // Mix color Plant Number;pRgb=(tagRGBQUAD *)malloc(nPlantNum*sizeof(tagRGBQUAD));memset(pRgb,0,nPlantNum*sizeof(tagRGBQUAD));int num = fread(pRgb,4,nPlantNum,pfile);printf("Color Plate Number: %d\n",nPlantNum);printf("颜色板信息:\n");for (int i =0; i<nPlantNum;i++){if (i%5==0){printf("\n");}showRgbQuan(&pRgb[i]);}printf("\n");}int width = bitInfoHead.biWidth;int height = bitInfoHead.biHeight;//分配内存空间把源图存入内存int l_width = WIDTHBYTES(width* bitInfoHead.biBitCount);//计算位图的实际宽度并确保它为32的倍数BYTE *pColorData=(BYTE *)malloc(height*l_width);memset(pColorData,0,height*l_width);long nData = height*l_width;//把位图数据信息读到数组里fread(pColorData,1,nData,pfile);//将位图数据转化为RGB数据tagRGBQUAD* dataOfBmp;dataOfBmp = (tagRGBQUAD *)malloc(width*height*sizeof(tagRGBQUAD));//用于保存各像素对应的RGB数据memset(dataOfBmp,0,width*height*sizeof(tagRGBQUAD));if(bitInfoHead.biBitCount<24)//有调色板,即位图为非真彩色{int k;int index = 0;if (bitInfoHead.biBitCount == 1){for(int i=0;i<height;i++)for(int j=0;j<width;j++){BYTE mixIndex= 0;k = i*l_width + j/8;//k:取得该像素颜色数据在实际数据数组中的序号//j:提取当前像素的颜色的具体值mixIndex = pColorData[k];switch(j%8){case 0:mixIndex = mixIndex<<7;mixIndex = mixIndex>>7;break;case 1:mixIndex = mixIndex<<6;mixIndex = mixIndex>>7;break;case 2:mixIndex = mixIndex<<5;mixIndex = mixIndex>>7;break;case 3:mixIndex = mixIndex<<4;mixIndex = mixIndex>>7;break;case 4:mixIndex = mixIndex<<3;mixIndex = mixIndex>>7;break;case 5:mixIndex = mixIndex<<2;mixIndex = mixIndex>>7;break;case 6:mixIndex = mixIndex<<1;mixIndex = mixIndex>>7;break;case 7:mixIndex = mixIndex>>7;break;}//将像素数据保存到数组中对应的位置dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen; dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved; index++;}}if(bitInfoHead.biBitCount==2){for(int i=0;i<height;i++)for(int j=0;j<width;j++){BYTE mixIndex= 0;k = i*l_width + j/4;//k:取得该像素颜色数据在实际数据数组中的序号//j:提取当前像素的颜色的具体值mixIndex = pColorData[k];switch(j%4){case 0:mixIndex = mixIndex<<6;mixIndex = mixIndex>>6;break;case 1:mixIndex = mixIndex<<4;mixIndex = mixIndex>>6;break;case 2:mixIndex = mixIndex<<2;mixIndex = mixIndex>>6;break;case 3:mixIndex = mixIndex>>6;break;}//将像素数据保存到数组中对应的位置dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen; dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;index++;}}if(bitInfoHead.biBitCount == 4){for(int i=0;i<height;i++)for(int j=0;j<width;j++){BYTE mixIndex= 0;k = i*l_width + j/2;mixIndex = pColorData[k];if(j%2==0){//低mixIndex = mixIndex<<4;mixIndex = mixIndex>>4;}else{//高mixIndex = mixIndex>>4;}dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed; dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen; dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue; dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved; index++;}}if(bitInfoHead.biBitCount == 8){for(int i=0;i<height;i++)for(int j=0;j<width;j++){BYTE mixIndex= 0;k = i*l_width + j;mixIndex = pColorData[k];dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen; dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue; dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved; index++;}}if(bitInfoHead.biBitCount == 16){for(int i=0;i<height;i++)for(int j=0;j<width;j++){WORD mixIndex= 0;k = i*l_width + j*2;WORD shortTemp;shortTemp = pColorData[k+1];shortTemp = shortTemp<<8;mixIndex = pColorData[k] + shortTemp;dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed; dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen; dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue; dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved; index++;}}}else//位图为24位真彩色{int k;int index = 0;for(int i=0;i<height;i++)for(int j=0;j<width;j++){k = i*l_width + j*3;dataOfBmp[index].rgbRed = pColorData[k+2];dataOfBmp[index].rgbGreen = pColorData[k+1];dataOfBmp[index].rgbBlue = pColorData[k];index++;}}printf("像素数据信息:\n");for (int i=0; i<width*height; i++) {if (i%5==0){printf("\n");}showRgbQuan(&dataOfBmp[i]); }fclose(pfile);if (bitInfoHead.biBitCount<24) {free(pRgb);}free(dataOfBmp);free(pColorData);printf("\n");}。

相关文档
最新文档