[求助]读取BMP的R,G,B,值请高手看一下问题出在哪?
我现在做的毕业设计是彩色图象的水印,需要把一副BMP图象的R,G,B,各个分量分别读出来然后再对各分量处理.最后再把处理后的数据写回BMP。下面的第一个程序我试了各种办法就是找不出错,请高手帮忙分析一下!
程序可以在*.TXT文件中输出图象位图文件头,信息头的主要数据,但其中的调色板读出的各颜色索引值不对,还有就是读出的R,G,B,三个二维数组的数值也不对(用自己编的READ.EXE,读DAT文件到记事本中0有许多 或是把三个分量分别写到BMP文件中但显示都只是一副紫色图)但大小是对的.
还想问一下就是数据处理完后怎么再把R,G,B值恢复为一副彩色图象,颜色索引值是不是还要重新确定一下?
下面是从BMP读取的主要数据:
bmp_img->width=256 and bmp_img->height=256 bits_per_pixel=8 bmp_type=g
the bmp file is notcompressed!
info_header_length = 1078
调色板的各颜色索引值:
Blue =1 Green=0 Red =0
Blue =189 Green=202 Red =0
Blue =63 Green=114 Red =0
Blue =104 Green=201 Red =0
Blue =219 Green=251 Red =0
Blue =106 Green=150 Red =0
Blue =57 Green=154 Red =0
Blue =64 Green=120 Red =0
Blue =31 Green=84 Red =0
Blue =107 Green=199 Red =0
Blue =84 Green=176 Red =0
Blue =128 Green=228 Red =0
Blue =64 Green=152 Red =0
Blue =177 Green=211 Red =0
Blue =128 Green=185 Red =0
Blue =203 Green=241 Red =0
Blue =52 Green=130 Red =0
Blue =94 Green=202 Red =0
Blue =209 Green=245 Red =0
Blue =52 Green=106 Red =0
Blue =143 Green=186 Red =0
Blue =49 Green=173 Red =0
Blue =105 Green=201 Red =0
Blue =115 Green=154 Red =0
Blue =82 Green=177 Red =0
Blue =96 Green=138 Red =0
Blue =143 Green=212 Red =0
Blue =219 Green=239 Red =0
Blue =41 Green=107 Red =0
Blue =188 Green=220 Red =0
Blue =135 Green=195 Red =0
Blue =13 Green=81 Red =0
Blue =196 Green=234 Red =0
Blue =136 Green=228 Red =0
Blue =164 Green=192 Red =0
Blue =56 Green=126 Red =0
Blue =72 Green=155 Red =0
Blue =21 Green=102 Red =0
Blue =104 Green=140 Red =0
Blue =48 Green=151 Red =0
Blue =160 Green=236 Red =0
Blue =196 Green=245 Red =0
Blue =151 Green=190 Red =0
Blue =151 Green=168 Red =0
Blue =92 Green=188 Red =0
Blue =119 Green=212 Red =0
Blue =197 Green=236 Red =0
Blue =71 Green=135 Red =0
Blue =136 Green=172 Red =0
Blue =144 Green=220 Red =0
Blue =136 Green=196 Red =0
Blue =21 Green=116 Red =0
Blue =60 Green=188 Red =0
Blue =22 Green=92 Red =0
Blue =94 Green=164 Red =0
Blue =136 Green=230 Red =0
Blue =194 Green=220 Red =0
Blue =105 Green=212 Red =0
Blue =107 Green=221 Red =0
Blue =86 Green=188 Red =0
Blue =118 Green=199 Red =0
Blue =118 Green=164 Red =0
Blue =180 Green=244 Red =0
Blue =34 Green=116 Red =0
Blue =253 Green=253 Red =253
Blue =164 Green=2 Red =135
Blue =0 Green=0 Red =0
Blue =0 Green=0 Red =0
Blue =0 Green=0 Red =0 以下各值就全为0了,个数是对的一共读了256个索引值
程序如下(在VC中运行的):
/* This program is to read and write bmp images 只是256色位图 图片为256*256的彩色LENA图*/
#include "Conio.h"
#include "stdlib.h"
#include "stdio.h"
#include "malloc.h"
#include "math.h"
#define SUCCESSED 0
#define FAILED 1
//typedef unsigned char BYTE
/* ---------------------- */
/* Global Variables */
/* ---------------------- */
typedef struct BMP_img
{
long width;
long height;
char bmp_type; /* 'c'=color; 'g'=graymap; */
unsigned char **mono;
}BMP_IMG;
typedef struct tagRGBQUAD {
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} RGBQUAD;
long info_header_length; /* the length of bmp image information head */
unsigned char *bmp_head_buffer; /* used for bmp head */
RGBQUAD *bmiColor; /*调色板数组*/
FILE *information; /*在.txt文件中输出BMP图象的主要数据*/
/* ---------------------- */
/* Global Functions */
/* ---------------------- */
int read_bmp(FILE *infile, BMP_IMG *bmp_img);
void get_bmp(BMP_IMG *img, long height, long width, char bmp_type);
void write_dat(FILE *fred,FILE *fgreen,FILE *fblue,BMP_IMG *bmp_img);
/* ------------ */
/* Main() */
/* ------------ */
int main()
{
int i,j;
char infilename[10],redfilename[10],greenfilename[10],bluefilename[10],inma[10];
FILE *fin, *fred,*fgreen,*fblue;
BMP_IMG img_in, img_out;
printf("input the sourse filename:\n");
scanf("%s",infilename);
if((fin=fopen(infilename,"rb"))==NULL)
{ printf("can't open the file\n");
exit(0);
}
printf("input the red filename(*.dat):\n");
scanf("%s",redfilename);
if((fred=fopen(redfilename,"wb"))==NULL)
{ printf("can't open the file\n");
exit(0);
}
printf("input the green filename(*.dat):\n");
scanf("%s",greenfilename);
if((fgreen=fopen(greenfilename,"wb"))==NULL)
{ printf("can't open the file\n");
exit(0);
}
printf("input the blue filename(*.dat):\n");
scanf("%s",bluefilename);
if((fblue=fopen(bluefilename,"wb"))==NULL)
{ printf("can't open the file\n");
exit(0);
}
printf("input the information filename(*.txt):\n");
scanf("%s",inma);
if((information=fopen(inma,"wb"))==NULL)
{printf("can't open the file\n");
exit(0);
}
if((read_bmp(fin, &img_in))==FAILED) {
fprintf(stderr, "\n Error: BMP read failed \n");
fclose(fin);
exit(-1);
}
fclose(fin);
if(img_in.bmp_type=='g') {
/* set up structure for output image */
get_bmp(&img_out, img_in.height, img_in.width, 'g');
/* pixel replication */
for(i=0;i<img_in.height;i++)
for(j=0;j<img_in.width;j++)
img_out.mono[i][j]=img_in.mono[i][j];
}
else {
fprintf(stderr, "\n Unknown image type \n");
exit(-1);
}
write_dat(fred,fgreen,fblue,&img_out);
fclose(information);
return SUCCESSED;
}
/* ---------------- */
/* read_bmp() */
/* ---------------- */
int read_bmp(FILE *infile, BMP_IMG *bmp_img)
{
int i,j;
long width, height;
int bits_per_pixel;
int compression;
unsigned char *temp; /* used for read the image data */
/* read the bmp image head information */
/* read the length and width of the input image */
fseek(infile, 0x12, SEEK_SET);
fread(&width, sizeof(long), 1, infile);
fseek(infile, 0x16, SEEK_SET);
fread(&height, sizeof(long), 1, infile);
bmp_img->width=width;
bmp_img->height=height;
fprintf(information, "\n bmp_img->width=%d and bmp_img->height=%d \n", bmp_img->width, bmp_img->height);
/* read bits/pixel and decide the type of the bmp image */
fseek(infile, 0x1C, SEEK_SET);
fread(&bits_per_pixel, sizeof(int), 1, infile);
if(bits_per_pixel==8)
bmp_img->bmp_type='g';
fprintf(information, "\n bits_per_pixel=%d \n", bits_per_pixel);
fprintf(information, "\n bmp_type=%c \n", bmp_img->bmp_type);
/* decide whether the bmp file is compressed */
fseek(infile, 0x1E, SEEK_SET);
fread(&compression, sizeof(int), 1, infile);
if(compression==0) {
fprintf(information, "\n the bmp file is not compressed! \n");
}
fseek(infile, 0x0A, SEEK_SET);
fread(&info_header_length, sizeof(int), 1, infile); /* the length of bmp image information head */
fprintf(information, "\n info_header_length = %d \n", info_header_length);
/* allocate the memory for bmp_head_buffer and read the info header of bmp file */
bmp_head_buffer=(unsigned char *)malloc(sizeof(unsigned char)*info_header_length);
if(bmp_head_buffer==NULL) {
fprintf(stderr, "\n Allocation error for bmp_head_buffer \n");
exit(-1);
}
fseek(infile, 0x00, SEEK_SET);
fread(bmp_head_buffer, info_header_length, 1, infile);/*取从文件开始到位图数据开始之间的数据偏移量*/
/* end of read the bmp head information*/
/*为调色板指针指向的地址分配一块内存空间*/
bmiColor = (RGBQUAD *)malloc(256 * sizeof(RGBQUAD));
/*从文件中读位图的调色板数据到bmiColor指向的缓冲区*/
fseek(infile,0x33,SEEK_SET);/*从此处读颜色索引值不知正确不?*/
fread(bmiColor, sizeof(RGBQUAD), 256, infile);
/*查看调色板信息*/
for(i=0;i<256;i++)
{
fprintf(information, " Blue =%d" , (*(bmiColor+i*sizeof(RGBQUAD))).rgbBlue);
fprintf(information, " Green=%d" , (*(bmiColor+i*sizeof(RGBQUAD))).rgbGreen);
fprintf(information, " Red =%d\n\n\n\n", (*(bmiColor+i*sizeof(RGBQUAD))).rgbRed);
}
/* allocate the memory for mono or color array */
if(bmp_img->bmp_type=='g')/*为**mono/***color分配存贮空间*/
get_bmp(bmp_img, bmp_img->height, bmp_img->width, 'g');
/* read the image data to mono or color array */
if(bmp_img->bmp_type=='g') {
temp=(unsigned char *)malloc(sizeof(unsigned char)*(bmp_img->width*bmp_img->height));
if(temp==NULL) {
fprintf(stderr, "\n Allocation error for temp in read_bmp() \n");
exit(-1);
}
fseek(infile, info_header_length, SEEK_SET);
if(fread(temp, sizeof(unsigned char), bmp_img->width*bmp_img->height, infile)!=(size_t)(bmp_img->width*bmp_img->height)) {
if(feof(infile)) fprintf(stderr, "\n Premature end of file %s \n", infile);
else fprintf(stderr, "\n File read error %s \n", infile);
return FAILED;
}
for(i=0;i<bmp_img->height;i++)
for(j=0;j<bmp_img->width;j++)
bmp_img->mono[i][j]=temp[i*bmp_img->width+j];
}
return SUCCESSED;
}
/* --------------- */
/* get_bmp() */
/* --------------- */
void get_bmp(BMP_IMG *img, long height, long width, char bmp_type)/*为**mono/***color分配存贮空间*/
{
int i;
img->width=width;
img->height=height;
img->bmp_type=bmp_type;
/* allocate the memory for mono and color */
if(img->bmp_type=='g') {
img->mono=(unsigned char **)malloc(sizeof(unsigned char *)*img->height);
if(img->mono==NULL) {
fprintf(stderr, "\n Allocation error for mono \n");
exit(-1);
}
for(i=0;i<img->height;i++)
{
img->mono[i]=(unsigned char *)malloc(sizeof(unsigned char)*img->width);
if(img->mono[i]==NULL) {
fprintf(stderr, "\n Allocation error for mono[%d] \n",i);
exit(-1);
}
}
}
}
/* ----------------- */
/* write_dat() */
/* ----------------- */
void write_dat(FILE *fred,FILE *fgreen,FILE *fblue,BMP_IMG *bmp_img)
{int i,j,n;
int red[256][256],green[256][256],blue[256][256];
for(i=255;i>=0;i--)
for(j=0;j<256;j++)
{ n=bmp_img->mono[i][j];//找到对应的颜色索引号
red[255-i][j]=bmiColor[n].rgbRed;
green[255-i][j]=bmiColor[n].rgbGreen;
blue[255-i][j]=bmiColor[n].rgbBlue;
}
fwrite(red,sizeof(unsigned char),bmp_img->width*bmp_img->height,fred);
fwrite(green,sizeof(unsigned char),bmp_img->width*bmp_img->height,fgreen);
fwrite(blue,sizeof(unsigned char),bmp_img->width*bmp_img->height,fblue);
fclose(fred);
fclose(fgreen);
fclose(fblue);
急切希望你的解答![em13]