您的位置:首页 > 其它

【C】bmp格式图片的二进制存储结构及其图形处理

2013-10-30 14:44 369 查看
扩展名为.bmp的图片文件,无压缩,最保真,占用空间最大,数据格式也最简单最基本。

因而比较适合作为理解计算机图形存储及处理原理的基础格式。

它本质上就是二进制文件 —— C语言最爱吃的东西。

博文首发地址:http://blog.csdn.net/duzixi

比如有一张图片看上去这样:



那么在计算机看来(用16进制表示)其实是这样的:



.....  当然后面还有很多很多 .....

这些数字按所包含的信息分成三个部分:

1. 文件头

2. Bmp图片头

3. 颜色序列

关于这些信息部分的详细内容会在后续补充。

这些数字会按照以下的方式被C语言“吃掉”,然后被随心所欲的处理。

源代码:

//
//  main.m
//  changeBmpFile
//
//  Created by 杜子兮 (duzixi.com) 13-11-1.
//  Copyright (c) 2013年 lanou3g.com All rights reserved.
//

#import <Foundation/Foundation.h>
#import "colorFunction.h"

int main(int argc, const char * argv[])
{

char *name = "/Users/duzixi/Desktop/org.bmp"; // 注意:图片文件所在本地路径
FILE *fp = fopen(name, "r");
if (!fp ) {
printf("原始文件不存在\n");
exit(1);
}

BmpFileInfo bmpInfo = {0};
fread(&bmpInfo.type, sizeof(char) , 2, fp);
fread(&bmpInfo.fileSize, sizeof(long) , 1, fp);
fread(&bmpInfo.offset, sizeof(int), 4, fp);
fread(&bmpInfo.other, sizeof(char),
bmpInfo.offset - sizeof(int) * 4 - sizeof(long) * 1 - sizeof(char) * 2, fp);

printf("bmpInfo size : %lu\n",sizeof(BmpFileInfo));
printf("bmpPoint size: %lu\n",sizeof(BmpPoint));

printf("file type    : %c%c\n",bmpInfo.type[0],bmpInfo.type[1]);
printf("file size    : %ld\n",bmpInfo.fileSize);
printf("file offset  : %d\n",bmpInfo.offset);
printf("file weigth  : %d\n",bmpInfo.weigth);
printf("file height  : %d\n",bmpInfo.height);
//    long size = bmpInfo.weigth * bmpInfo.height * 3;
//    printf("last size    : %ld\n",size);
//    printf("tail points  : %ld\n",(bmpInfo.fileSize - 54 - size) / 3);

BmpPoint *bmpPoints = malloc(bmpInfo.fileSize - 54);
BmpPoint *p = bmpPoints;

char editMode[10] = "";
printf("图片编辑模式:(gray,up,down,inverse,gbr,grb)\n");
scanf("%s",editMode);
PFColor pfc = getColorFunction(editMode);

for (int i = 0; i < (bmpInfo.fileSize - bmpInfo.offset) / 3 ; i++) {
fread(p, sizeof(BmpPoint), 1, fp);
dEditColor(p,pfc);
p++;
}
fclose(fp);

char newFileName[20] = "";
printf("储存为:\n");
scanf("%s",newFileName);

char nameNew[50] = "/Users/lotusiki/Desktop/";

strcat(nameNew,newFileName);
strcat(nameNew,".bmp");
FILE *fpn = fopen(nameNew, "w");

fwrite(&bmpInfo.type, sizeof(char), 2, fpn);
fwrite(&bmpInfo.fileSize, sizeof(long) , 1, fpn);
fwrite(&bmpInfo.offset, sizeof(int), 4, fpn);
fwrite(&bmpInfo.other, sizeof(char),28 , fpn);

for (int i = 0; i < (bmpInfo.fileSize - bmpInfo.offset) / 3 ; i++) {
fwrite(&bmpPoints->R, sizeof(char), 1, fpn);
fwrite(&bmpPoints->G, sizeof(char), 1, fpn);
fwrite(&bmpPoints->B, sizeof(char), 1, fpn);
bmpPoints++;
}

fclose(fpn);
return 0;
}

//
//  colorFunction.h
//  changeBmpFile
//
//  Created by 杜子兮(duzixi.com)  13-11-1.
//  Copyright (c) 2013年 lanou3g.com All rights reserved.
//

#import <Foundation/Foundation.h>

typedef struct bmpFileInfo{
char type[2];   // 2
long fileSize;  // 文件大小
int offset;     // 偏移量
int b;          // 预留
int weigth;     // 宽
int height;     // 高
char other[28];
}BmpFileInfo;

typedef struct bmpPoint{
unsigned char R;
unsigned char G;
unsigned char B;
}BmpPoint;

typedef void (*PFColor)(BmpPoint *p);
PFColor getColorFunction(char *);

typedef struct colorFunction{
char *name;
PFColor function;
}ColorFunction;

void dEditColor(BmpPoint *p,PFColor pf);
void grayColor(BmpPoint *p);
void downColor(BmpPoint *p);
void upColor(BmpPoint *p);
void inverseColor(BmpPoint *p);
void gbrColor(BmpPoint *p);
void grbColor(BmpPoint *p);
//
//  colorFunction.m
//  changeBmpFile
//
//  Created by 杜子兮(duzixi.com) 13-11-1.
//  Copyright (c) 2013年 lanou3g.com All rights reserved.
//

#import "colorFunction.h"

PFColor getColorFunction(char *fname){
ColorFunction cf[] = {
{"gray",grayColor},
{"down",downColor},
{"up",upColor},
{"inverse",inverseColor},
{"gbr",gbrColor},
{"grb",grbColor}
};
PFColor function = NULL;
for (int i = 0 ; i < (sizeof(cf)/sizeof(cf[0])); i++) {
if (strcmp(fname, cf[i].name) == 0) {
function = cf[i].function;
break;
}
}
return function;
}

void dEditColor(BmpPoint *p,PFColor pfc){
pfc(p);
}

void grayColor(BmpPoint *p){
unsigned char avg = 0;
avg = ((*p).R + (*p).G + (*p).B ) / 3;
(*p).R = avg;
(*p).G = avg;
(*p).B = avg;
}

void downColor(BmpPoint *p){
(*p).R = (*p).R / 2;
(*p).G = (*p).G / 2;
(*p).B = (*p).B / 2;
}

void upColor(BmpPoint *p){
(*p).R = ((*p).R * 1.5) > 255 ? 255 : ((*p).R * 1.5);
(*p).G = ((*p).G * 1.5) > 255 ? 255 : ((*p).G * 1.5);
(*p).B = ((*p).B * 1.5) > 255 ? 255 : ((*p).B * 1.5);
}

void inverseColor(BmpPoint *p){
(*p).R = 255 - (*p).R;
(*p).G = 255 - (*p).G;
(*p).B = 255 - (*p).B;
}

void gbrColor(BmpPoint *p){
unsigned char temp = 0;
temp = (*p).R;
(*p).R = (*p).G;
(*p).G = (*p).B;
(*p).B = temp;
}

void grbColor(BmpPoint *p){
unsigned char temp = 0;
temp = (*p).B;
(*p).B = (*p).G;
(*p).G = (*p).R;
(*p).R = temp;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: