C语言进行数字图像处理

「C语言进行数字图像处理」の編集履歴(バックアップ)一覧はこちら

C语言进行数字图像处理」(2011/10/11 (火) 22:32:31) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

用 c 语言进行数字图像处理 作者:彭千贺 邮件:pengqianhe@gmail.com 博客:http://pengqianhe.googlepages.com 声明:本篇文章和程序全部有彭千贺原创,严禁任何形式的修改,如有发现任何形式的修改,将 有权追究其相关责任人的法律责任。但是,你可以自由的传播本文章的副本。如需要修改,请邮 件通知我。 其实,数字图像处理有几步呢?一共三步。第一步,读入图片。第二步,处理图片。第三步,保存图片。 而第二步主要涉及的是处理图像的算法,所以,我在这里就不多说了。而第一步和第三步是为第二步做 铺垫的。 关于位图文件的文件结构,可以参看我的另外一篇文章《详说如何用C语言,C++和JAVA来读入和保 存位图》。此文章可以在我的博客下载到。我在这里,贴出用C语言进行读入位图的文件头,信息头, 像素数据和保存位图等程序,另外还有声明位图文件结构的头文件。 以下程序在VC6.0中,已经无误通过编译。 位图文件结构的声明:BMP.h #ifndef BMP_H_INCLUDED #define BMP_H_INCLUDED # typedef unsigned short WORD; typedef unsigned long DWORD; typedef long LONG; typedef unsigned char BYTE; t typedef struct tagBITMAPFILEHEADER { // bmfh WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; }BITMAPFILEHEADER; } typedef struct tagBITMAPINFOHEADER { // bmih DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; }BITMAPINFOHEADER; } typedef struct tagRGBQUAD { // rgbq BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; }RGBQUAD; } typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; }BITMAPINFO; } #endif // BMP_H_INCLUDED 主程序:main.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h> #include <ctype.h> #include <process.h> # #include "BMP.h" # BITMAPFILEHEADER bmfh; BITMAPINFOHEADER bmih; BYTE *imgData; bool bReadBMFH=false; bool bReadBMIH=false; bool bReadPixel=false; b //检查路径是否合法:文件能打开;以bmp为后缀名 为 int CheckFilePath(char *filepath);//读入位图的文件头 读 int ReadFileHeader(char *filepath,BITMAPFILEHEADER *bmfh); //打印位图的文件头 打 void PrintFileHeader(BITMAPFILEHEADER *bmfh); //读入位图的信息头 读 int ReadInfoHeader(char *filepath,BITMAPINFOHEADER *bmih); //打印位图的信息头 打 void PrintInfoHeader(BITMAPINFOHEADER *bmih); //创建8位位图的调色板 位 int CreatePalette(RGBQUAD pal[]); //读入位图的像素数据 读 int ReadPixelData(char *filepath,BYTE *imgData); //计算每行像素所占的字节数 计 LONG GetLineBytes(int imgWidth,int bitCount); //打印位图的像素数据 打 void PrintPixelData(BYTE *imgData,int width,int height,int bitCount); //打印菜单选项 打 void PrintMenu(); //另存为位图 另 int SaveAsImage(char *filepath); //显示位图 显 void ShowImage(char * filepath); //保存文件头 保 int SaveFileHeader(FILE* fp); //保存信息头 保 int SaveInfoHeader(FILE* fp); //保存调色板 保 int SaveColorPalette(FILE *fp); //保存像素数据 保 int SavePixelData(FILE* fp); i int main() { char filepath[256]; char saveasfilepath[256]; int i; int width; int height; int bitCount; DWORD dwLineBytes; int select; int q=0; isystem("echo off"); system("color 2"); s printf("-----------TIMimage-----------\n"); printf("Input the path of the BMP file:\n"); gets(filepath); g i=CheckFilePath(filepath); if(i==-1) { return -1; } } do { PrintMenu(); scanf("%u",&select); s switch(select) { case 0: { printf("Input the path of the BMP file:\n"); scanf("%s",filepath); CheckFilePath(filepath); break; } case 1: { i=ReadFileHeader(filepath,&bmfh); if(i!=-1) { printf("Read the file header successfully.\n"); bReadBMFH=true; break; } else { printf("Read the file header failed.\n"); bReadBMFH=false; q=1; break; } }case 2: { i=ReadInfoHeader(filepath,&bmih); if(i!=-1) { printf("Read the info header successfully.\n"); bReadBMIH=true; break; } else { printf("Read the info header failed.\n"); bReadBMIH=false; q=1; break; } } case 3: { if(!bReadBMIH) { printf("Please read the info header at first.\n"); break; } height=bmih.biHeight; width=bmih.biWidth; bitCount=bmih.biBitCount; dwLineBytes=GetLineBytes(width,bitCount); imgData=(BYTE*)malloc(dwLineBytes*height*sizeof(BYTE)); if(!imgData) { printf("Can not allocate memory for the image.\n"); q=1; break; } i=ReadPixelData(filepath,imgData); if(i==-1) { printf("Read the pixel data failed.\n"); bReadPixel=false; q=1; break; } else{ printf("Read the pixel data successfully.\n"); bReadPixel=true; break; } } case 4: { if(bReadBMFH) { PrintFileHeader(&bmfh); break; } else { printf("Please read the file header at first.\n"); break; } } case 5: { if(bReadBMIH) { PrintInfoHeader(&bmih); break; } else { printf("Please read the info header at first.\n"); break; } } case 6: { if(bReadPixel) { PrintPixelData(imgData,width,height,bitCount); break; } else { printf("Please read the pixel data at first.\n"); break; }} case 7: { ShowImage(filepath); break; } case 8: { printf("Input the path(ex. d://poon.bmp) you want to save:\n"); scanf("%s",saveasfilepath); s i=SaveAsImage(saveasfilepath); if(i==-1) { printf("Error: failed to save the image.\n"); break; } break; } default: q=1; break; } } select=9527; s } while (q==0); } return 0; } } int ReadFileHeader(char *filepath,BITMAPFILEHEADER *bmfh) { FILE *fp; F fp=fopen(filepath,"rb"); if(!fp) { printf("Can not open the file:%s\n",filepath); return -1; } } if(fread(&bmfh->bfType,sizeof(WORD),1,fp)!=1) {printf("Can not read bfType in the file header.\n"); fclose(fp); return -1; } } if(fread(&bmfh->bfSize,sizeof(DWORD),1,fp)!=1) { printf("Can not read bfSize in the file header.\n"); fclose(fp); return -1; } } if(fread(&bmfh->bfReserved1,sizeof(WORD),1,fp)!=1) { printf("Can not read bfReserved1 in the file header.\n"); fclose(fp); return -1; } } if(fread(&bmfh->bfReserved2,sizeof(WORD),1,fp)!=1) { printf("Can not read bfReserved2 in the file header.\n"); fclose(fp); return -1; } } if(fread(&bmfh->bfOffBits,sizeof(DWORD),1,fp)!=1) { printf("Can not read bfOffBits in the file header.\n"); fclose(fp); return -1; } } fclose(fp); f return 0; } } int ReadInfoHeader(char *filepath,BITMAPINFOHEADER *bmih) { FILE *fp; F fp=fopen(filepath,"rb"); if(!fp){ printf("Can not open the file:%s\n",filepath); return -1; } } fseek(fp,14,SEEK_SET); f if(fread(&bmih->biSize,sizeof(DWORD),1,fp)!=1) { printf("Can not read biSize in the info header.\n"); fclose(fp); return -1; } } if(fread(&bmih->biWidth,sizeof(LONG),1,fp)!=1) { printf("Can not read biWidth in the info header.\n"); fclose(fp); return -1; } } if(fread(&bmih->biHeight,sizeof(LONG),1,fp)!=1) { printf("Can not read biHeight in the info header.\n"); fclose(fp); return -1; } } if(fread(&bmih->biPlanes,sizeof(WORD),1,fp)!=1) { printf("Can not read biPlanes in the info header.\n"); fclose(fp); return -1; } } if(fread(&bmih->biBitCount,sizeof(WORD),1,fp)!=1) { printf("Can not read biBitCount in the info header.\n"); fclose(fp); return -1; } } if(fread(&bmih->biCompression,sizeof(DWORD),1,fp)!=1) {printf("Can not read biCompression in the info header.\n"); fclose(fp); return -1; } } if(fread(&bmih->biSizeImage,sizeof(DWORD),1,fp)!=1) { printf("Can not read biSizeImage in the info header.\n"); fclose(fp); return -1; } } if(fread(&bmih->biXPelsPerMeter,sizeof(LONG),1,fp)!=1) { printf("Can not read biXPelsPerMeter in the info header.\n"); fclose(fp); return -1; } } if(fread(&bmih->biYPelsPerMeter,sizeof(LONG),1,fp)!=1) { printf("Can not read biYPelsPerMeter in the info header.\n"); fclose(fp); return -1; } } if(fread(&bmih->biClrUsed,sizeof(DWORD),1,fp)!=1) { printf("Can not read biClrUsed in the info header.\n"); fclose(fp); return -1; } } if(fread(&bmih->biClrImportant,sizeof(DWORD),1,fp)!=1) { printf("Can not read biClrImportant in the info header.\n"); fclose(fp); return -1; } } fclose(fp); f return 0; }} int CreatePalette(RGBQUAD pal[]) { int i; i if(sizeof(pal)/sizeof(RGBQUAD)!=256) { printf("The size of the palette must be 256.\n"); return -1; } } for(i=0;i<256;i++) { pal[i].rgbBlue=i; pal[i].rgbGreen=i; pal[i].rgbRed=i; pal[i].rgbReserved=0; } } return 0; } } int ReadPixelData(char *filepath,BYTE *imgData) { BITMAPINFOHEADER bmih; BITMAPFILEHEADER bmfh; BYTE *data; FILE *fp; int n; int width; int height; int bitCount; DWORD dwLineBytes; D n=ReadFileHeader(filepath,&bmfh); if(n==-1) { printf("Can not read the file header of the BMP file.\n"); return -1; } } n=ReadInfoHeader(filepath,&bmih); if(n==-1) {printf("Can not read the info header of the BMP file.\n"); return -1; } } width=bmih.biWidth; height=bmih.biHeight; bitCount=bmih.biBitCount; dwLineBytes=GetLineBytes(width,bitCount); d if(_msize(imgData)!=(dwLineBytes*height)) { printf("The size you allocate for the pixel data is not right.\n"); printf("Fittable size: %ld bytes.\n",(dwLineBytes*height)); printf("Your size: %ld bytes.\n",sizeof(imgData)); return -1; } } data=(BYTE*)malloc(dwLineBytes*height*sizeof(BYTE)); if(!data) { printf("Can not allocate memory for the pixel data.\n"); return -1; } } fp=fopen(filepath,"rb"); if(!fp) { printf("Can not open the file: %s\n",filepath); free(data); return -1; } } if(bitCount==8) { fseek(fp,bmfh.bfOffBits,SEEK_SET); } else if(bitCount==24) { fseek(fp,bmfh.bfOffBits,SEEK_SET); } else { printf("Only Support: 8 or 24 bits.\n"); free(data);fclose(fp); return -1; } } n=fread(data,dwLineBytes*height*sizeof(BYTE),1,fp); if(n==0) { if(feof(fp)) { } if(ferror(fp)) { printf("Can not read the pixel data.\n"); free(data); fclose(fp); return -1; } } } memcpy(imgData,data,dwLineBytes*height*sizeof(BYTE)); m free(data); fclose(fp); f return 0; } } void PrintFileHeader(BITMAPFILEHEADER *bmfh) { printf("The contents in the file header of the BMP file:\n"); printf("bfOffBits: %ld\n",bmfh->bfOffBits); printf("bfReserved1: %ld\n",bmfh->bfReserved1); printf("bfReserved2: %ld\n",bmfh->bfReserved2); printf("bfSize: %ld\n",bmfh->bfSize); printf("bfType: %ld\n",bmfh->bfType); } } void PrintInfoHeader(BITMAPINFOHEADER *bmih) { printf("The content in the info header of the BMP file:\n"); printf("biBitCount: %ld\n",bmih->biBitCount); printf("biClrImportant: %ld\n",bmih->biClrImportant); printf("biClrUsed: %ld\n",bmih->biClrUsed); printf("biCompression: %ld\n",bmih->biCompression);printf("biHeight: %ld\n",bmih->biHeight); printf("biPlanes: %ld\n",bmih->biPlanes); printf("biSize: %ld\n",bmih->biSize); printf("biSizeImage: %ld\n",bmih->biSizeImage); printf("biWidth: %ld\n",bmih->biWidth); printf("biXPelsPerMeter: %ld\n",bmih->biXPelsPerMeter); printf("biYPelsPerMeter: %ld\n",bmih->biYPelsPerMeter); } } LONG GetLineBytes(int imgWidth,int bitCount) { return (imgWidth*bitCount+31)/32*4; } } void PrintPixelData(BYTE *imgData,int width,int height,int bitCount) { int i; int j; int p; DWORD dwLineBytes=GetLineBytes(width,bitCount); D if(bitCount==8) { for(i=0;i<height;i++) { for(j=0;j<width;j++) { p=*(imgData+dwLineBytes*(height-1-i)+j); printf("%d,",p); } printf("\n"); } } else if(bitCount==24) { for(i=0;i<height;i++) { for(j=0;j<width*3;j++) { printf("("); p=*(imgData+dwLineBytes*(height-1-i)+j); printf("%d,",p); j++; p=*(imgData+dwLineBytes*(height-1-i)+j);printf("%d,",p); j++; p=*(imgData+dwLineBytes*(height-1-i)+j); printf("%d) ",p); } printf("\n"); } } else { printf("Only supported: 8 or 24 bits.\n"); } } } int CheckFilePath(char *filepath) { FILE *fp; int len=strlen(filepath)/sizeof(char); char ext[3]; c if(filepath[0]!=int('\"')) { strncpy(ext,&filepath[len-3],3); if(!(ext[0]=='b' && ext[1]=='m' && ext[2]=='p')) { printf("Error: The file is not a BMP file.\n"); printf("Error: The extention of the filename must be 'bmp',not 'BMP'\ n"); return -1; } } fp=fopen(filepath,"r"); if(!fp) { printf("Error: The path is not correct.\n"); return -1; } fclose(fp); } else { printf("Error: The path must not include blank space.\n"); return -1; }return 0; } } void PrintMenu() { printf(" -----Choose Your Operation-----\n"); printf("| 0-----Input the image path |\n"); printf("| 1-----Read the file header |\n"); printf("| 2-----Read the info header |\n"); printf("| 3-----Read the pixel data |\n"); printf("| 4-----Print the file header |\n"); printf("| 5-----Print the info header |\n"); printf("| 6-----Print the pixel data |\n"); printf("| 7-----View the original image |\n"); printf("| 8-----Save as the image |\n"); printf("| other-----Exit the program |\n"); printf(" -------------------------------\n"); } } int SaveAsImage(char *filepath) { FILE *fp; F fp=fopen(filepath,"wb"); if(!fp) { printf("Error: can not create the file.\n"); return -1; } } SaveFileHeader(fp); SaveInfoHeader(fp); if(bmih.biBitCount==8) { SaveColorPalette(fp); } SavePixelData(fp); S fclose(fp); f printf("Save As the image successfully.\n"); p return 0;} } void ShowImage(char * filepath) { char cmd[266]; c strcpy(cmd,"start "); strcat(cmd,filepath); printf("%s\n",cmd); system(cmd); } } int SaveFileHeader(FILE *fp) { if(!bReadBMFH) { printf("Please read the file header at first.\n"); return -1; } } if(fwrite(&bmfh.bfType,sizeof(WORD),1,fp)!=1) { printf("Can not write bfType in the file header.\n"); fclose(fp); return -1; } } if(fwrite(&bmfh.bfSize,sizeof(DWORD),1,fp)!=1) { printf("Can not write bfSize in the file header.\n"); fclose(fp); return -1; } } if(fwrite(&bmfh.bfReserved1,sizeof(WORD),1,fp)!=1) { printf("Can not write bfReserved1 in the file header.\n"); fclose(fp); return -1; } } if(fwrite(&bmfh.bfReserved2,sizeof(WORD),1,fp)!=1) { printf("Can not write bfReserved2 in the file header.\n");fclose(fp); return -1; } } if(fwrite(&bmfh.bfOffBits,sizeof(DWORD),1,fp)!=1) { printf("Can not write bfOffBits in the file header.\n"); fclose(fp); return -1; } } return 0; } } int SaveInfoHeader(FILE *fp) { if(!bReadBMIH) { printf("Please read the info header at first.\n"); return -1; } } if(fwrite(&bmih.biSize,sizeof(DWORD),1,fp)!=1) { printf("Can not write biSize in the info header.\n"); fclose(fp); return -1; } } if(fwrite(&bmih.biWidth,sizeof(LONG),1,fp)!=1) { printf("Can not write biWidth in the info header.\n"); fclose(fp); return -1; } } if(fwrite(&bmih.biHeight,sizeof(LONG),1,fp)!=1) { printf("Can not write biHeight in the info header.\n"); fclose(fp); return -1; } } if(fwrite(&bmih.biPlanes,sizeof(WORD),1,fp)!=1){ printf("Can not write biPlanes in the info header.\n"); fclose(fp); return -1; } } if(fwrite(&bmih.biBitCount,sizeof(WORD),1,fp)!=1) { printf("Can not write biBitCount in the info header.\n"); fclose(fp); return -1; } } if(fwrite(&bmih.biCompression,sizeof(DWORD),1,fp)!=1) { printf("Can not write biCompression in the info header.\n"); fclose(fp); return -1; } } if(fwrite(&bmih.biSizeImage,sizeof(DWORD),1,fp)!=1) { printf("Can not write biSizeImage in the info header.\n"); fclose(fp); return -1; } } if(fwrite(&bmih.biXPelsPerMeter,sizeof(LONG),1,fp)!=1) { printf("Can not write biXPelsPerMeter in the info header.\n"); fclose(fp); return -1; } } if(fwrite(&bmih.biYPelsPerMeter,sizeof(LONG),1,fp)!=1) { printf("Can not write biYPelsPerMeter in the info header.\n"); fclose(fp); return -1; } } if(fwrite(&bmih.biClrUsed,sizeof(DWORD),1,fp)!=1) { printf("Can not write biClrUsed in the info header.\n");fclose(fp); return -1; } } if(fwrite(&bmih.biClrImportant,sizeof(DWORD),1,fp)!=1) { printf("Can not write biClrImportant in the info header.\n"); fclose(fp); return -1; } } return 0; } } int SaveColorPalette(FILE *fp) { int i; RGBQUAD pal[256]; R if(!bReadBMIH) { printf("Please read the info header at first.\n"); return -1; } } if(bmih.biBitCount!=8) { printf("Only 8 bits image hase color palette.\n"); return -1; } } for(i=0;i<256;i++) { pal[i].rgbReserved=0; pal[i].rgbBlue=i; pal[i].rgbGreen=i; pal[i].rgbRed=i; } } if(fwrite(pal,sizeof(RGBQUAD),256,fp)!=256) { printf("Error: can not write the color palette.\n"); fclose(fp); return -1;} } return 0; } } int SavePixelData(FILE* fp) { int height=bmih.biHeight; DWORD dwLineBytes=GetLineBytes(bmih.biWidth,bmih.biBitCount); D if(!bReadPixel) { printf("Please read the pixel data at first.\n"); return -1; } } if(fwrite(imgData,height*dwLineBytes,1,fp)!=1) { printf("Error: can not write the pixel data.\n"); fclose(fp); return -1; } } return 0; }

表示オプション

横に並べて表示:
変化行の前後のみ表示: