处理bmp灰度图,为什么调色板会自动改变??

huaxu242 2007-04-30 12:10:03
用C编了个程序,读BMP8位灰度图,中值滤波后写出。噪声去的还可以。但是颜色却变成蓝绿色,如果读蓝绿色图再写出,颜色变成黄色,再次运行,变红色,最后终于又变回灰色。

我都没有动文件头和调色板,把1078个字节直接写入新文件的。怎么会这样呢?
而且编了个程序显示调色板信息。定义Palette[256][4],灰度图的调色板是正常的。但是别的图的调色板却在第10行出现问题。如下:

第九行:灰图,有色图都是9 9 9 0
但是第十行,灰图是10 10 10 0,蓝色图却变成13 10 13 10,然后是13 10 0 11,11 11 0 12,12 12 0 13。。。 就这样,颜色就错开了。。。别的图也是一样的道理。
因为灰度图我是用photoshop把彩色图加工得到的,防止是这方面原因,就只将54字节复制进新文件,调色板的数据自己写入。可是依然变蓝色,调色板也会紊乱,只是不是第10行开始,好像更靠前了。。。

而且我写出的图还会整体右偏2,3个像素。应该不是那个4像素偏移的问题,因为我的图是256*256的。所以怀疑也跟调色板错位有关


谁能帮忙解释这个怪异的东西。。。非常感谢阿~~~~~~~~~~~
...全文
1302 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
mymtom 2007-05-14
  • 打赏
  • 举报
回复
这是微软的fopen的BUG!
所以后来我的程序用fopen的时候总是加上 b, 以防不测!
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright © 2001-2004 The IEEE and The Open Group, All Rights reserved.
是这么定义的:
The mode argument points to a string. If the string is one of the following, the file shall be opened in the indicated mode. Otherwise, the behavior is undefined.

r or rb
Open file for reading.
w or wb
Truncate to zero length or create file for writing.
a or ab
Append; open or create file for writing at end-of-file.
r+ or rb+ or r+b
Open file for update (reading and writing).
w+ or wb+ or w+b
Truncate to zero length or create file for update.
a+ or ab+ or a+b
Append; open or create file for update, writing at end-of-file.
[CX] The character 'b' shall have no effect, but is allowed for ISO C standard conformance.
huaxu242 2007-05-14
  • 打赏
  • 举报
回复
给分了,给分同时是不是就同时结帖呢,那我那个小问题可以留言告诉我吗?嘻嘻。谢拉 :)
huaxu242 2007-05-14
  • 打赏
  • 举报
回复
你在啊,我其实一分钟之后就搞定了,把w+改成wb+。可惜登陆过期又忘密码,重新登之后人家说我暴力破解密码,禁言30分钟。。。

我犯这个错误是因为根本不知道有这个方式。。。谭浩强也没说阿,也怪自己没想到。。。你说了才恍然大悟。。。

有点好奇你怎么想到的呢,而且你怎么了解到文本和二进制会有哪个回车换行啊。。。
我不是学计算机的,对C也不熟。。。工作了也没人教。所以有些知识都不知道应该从哪获取。。。唉~

真的很谢谢你啊。。。明天我就可以交差了。。
mymtom 2007-05-14
  • 打赏
  • 举报
回复
以前做在对字库的时候遇到同样的问题,总是读不对!
呵呵!
huaxu242 2007-05-14
  • 打赏
  • 举报
回复
奇怪,结了帖还能回复? 我是说自己发帖子得到的帮助,看别人的帖子那多了去了。
huaxu242 2007-05-14
  • 打赏
  • 举报
回复
谢谢你,你的解释总是让人佩服,但是还是想知道这些知识从哪来呢,我第一次从论坛上得到帮助,但是不能总靠问别人啊。。。比如那个回车换行,就差一层窗户纸了,可我不知道就是不知道。。。
huaxu242 2007-05-13
  • 打赏
  • 举报
回复
楼上的谢谢你哈,觉得你说的貌似很有道理,不过我还没明白。
等明天琢磨琢磨。然后就给你分哈:)
mymtom 2007-05-13
  • 打赏
  • 举报
回复
LZ 问题解决了吗?
mymtom 2007-05-12
  • 打赏
  • 举报
回复
刚才有看了一下你的描述有错位呀又有
13 10 13 10
这正好是回车换行嘛!
99% 是这个原因了!
mymtom 2007-05-12
  • 打赏
  • 举报
回复
楼主用的是VC吗?如果是请到MSDN上查fopen
http://msdn2.microsoft.com/en-us/library/ms884702.aspx
里面有一句关于文本还是二进制方式话,可能是这个问题的原因

FILE *fopen( const char *filename, const char *mode );
mode: Type of access permitted
b
Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed.
If t or b is not given in mode, the default translation mode is defined by the global variable _fmode. If t or b is prefixed to the argument, the function fails and returns NULL.

你打开文件的时候可能被认为以text方式打开了!
我曾经遇到过类似的问题,足足调试了两天!
huaxu242 2007-05-11
  • 打赏
  • 举报
回复
顶起
huaxu242 2007-05-09
  • 打赏
  • 举报
回复
为什么没人理我啊~~~~~~~~~~~~是不是我发错地方了。。。
liuyaoyou 2007-05-08
  • 打赏
  • 举报
回复
灰度图的调色板不就应该是(0,0,0,0)(1,1,1,0)(2,2,2,0)……(255,255,255,0)么?没改过调色板的话估计就是你把偏移量弄错了,或者有可能灰度图的调色板只有出现过的有限几种颜色?而不同的图其调色板的颜色和其数量都不相同?
huaxu242 2007-05-08
  • 打赏
  • 举报
回复
回楼上的,它不是整体偏差,整体偏我还可以调整读取的位置,关键是前九行都是正常的,从第十行开始莫名其妙错乱,然后就永远偏差了。如下

第九行:灰图,有色图都是9 9 9 0
但是第十行,灰图是10 10 10 0,蓝色图却变成13 10 13 10,然后是13 10 0 11,11 11 0 12,12 12 0 13。。。 就这样,颜色就错开了。。。


=======
另外,我单步调试过了。也用view菜单中的内存选项看了内存变化。奇怪的是,将a.bmp
文件中的header信息读入并写到fp指向的b.bmp文件中时,直到最后一步,调色板所在的内存内容都是正常的。可是如果再读入b.bmp的header写入c.bmp,调色板内存就会看到如上错乱。。。
这是怎么回事啊
huaxu242 2007-05-07
  • 打赏
  • 举报
回复
顶起。。。
huaxu242 2007-04-30
  • 打赏
  • 举报
回复
程序如下

#include <stdlib.h>
#include <math.h>
#define XSIZE 640
#define YSIZE 480
#define OFFSET 1078


/* type convert */
void main ()
{
int bmp_read(unsigned char *image,char *filename);
int bmp_write(unsigned char *image,char *filename,char *filename_w);
int median(unsigned char *image,unsigned char *image_out);
int laplacian(unsigned char *image,unsigned char *image_out,float amp);
int tem(unsigned char *image,unsigned char *image_out,float amp);
unsigned char *image_gray;
unsigned char *image_gray_out;
char filename[128],filename_w[128];
printf("filename:");
scanf("%s",filename);
printf("filename_w:");
scanf("%s",filename_w);
image_gray=(unsigned char *)malloc(XSIZE*YSIZE);
if (image_gray==NULL)
printf("memory error\n");
image_gray_out=(unsigned char *)malloc(XSIZE*YSIZE);
if (image_gray_out==NULL)
printf("memory error\n");
if (bmp_read(image_gray,filename)==-1)
printf("open or memory error\n");
printf("read ok\n");
if (median(image_gray,image_gray_out))
printf("median ok\n");

if (bmp_write(image_gray_out,filename,filename_w)==-1)
printf("access error");
printf("write ok\n");
free(image_gray);
free(image_gray_out);
getch();
}

/*gray-read*/
int bmp_read(unsigned char *image,char *filename)
{
FILE *fp;
char fname_bmp[128];
unsigned char header[OFFSET];

sprintf(fname_bmp,"%s",filename);
if((fp=fopen(fname_bmp,"rb"))==NULL)
{printf("open error\n");
return -1;
}
fread(header,sizeof(unsigned char),OFFSET,fp);
fread(image,sizeof(unsigned char),XSIZE*YSIZE,fp);
fclose(fp);

return 0;
}
/*gray write*/
int bmp_write(unsigned char *image,char *filename,char *filename_w)
{
FILE *fp;
char fname_bmp[128];
unsigned char header[OFFSET];

sprintf(fname_bmp,"%s",filename);
if((fp=fopen(fname_bmp,"rb"))==NULL)
{printf("open error\n");
return -1;
}
fread(header,sizeof(unsigned char),OFFSET,fp);
fclose(fp);

sprintf(fname_bmp,"%s",filename_w);
if((fp=fopen(fname_bmp,"w+"))==NULL)
{printf("open error\n");
return -1;
}
fwrite(header,sizeof(unsigned char),OFFSET,fp);
fwrite(image,sizeof(unsigned char),XSIZE*YSIZE,fp);
fclose(fp);
return 0;
}
/*median*/
int median(unsigned char *image,unsigned char *image_out)
{
int i,m,n,buf;

unsigned char c[9];
for (i=0;i<YSIZE*XSIZE-1;i++)
{ if(i<(XSIZE+1)||i>(YSIZE*XSIZE-XSIZE-1))
*(image_out+i)=0;
else{
c[0]=*(image+i-XSIZE-1);
c[1]=*(image+i-XSIZE);
c[2]=*(image+i-XSIZE+1);
c[3]=*(image+i-1);
c[4]=*(image+i);
c[5]=*(image+i+1);
c[6]=*(image+i+XSIZE-1);
c[7]=*(image+i+XSIZE);
c[8]=*(image+i+XSIZE+1);

for(n=0;n<9;n++){
for (m=0;m<8;m++){
if (c[m+1]<c[m]){
buf=c[m+1];
c[m+1]=c[m];
c[m]=buf;
}
}
}
*(image_out+i)=c[4];
}
}
return 1;
}
huaxu242 2007-04-30
  • 打赏
  • 举报
回复
那怎么单步运行啊。。我用的vc。
搜了些设断点,单步调试的操作方法。。
可是我读取颜色表信息的语句应该放在哪啊。。。
jixingzhong 2007-04-30
  • 打赏
  • 举报
回复
为什么调色板会自动改变

不会,
检查程序。

增加断点,
单步运行程序,
在查看中添加 调色板对应的变量进行观察,
看看到了哪个语句的时候,变量被修改了 ~

69,377

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧