现有bmp文件,拟遍历像素数据,将其中红色改为绿色。
若位图为8位,程序可正常执行;
若位图为24位,为何不能?
感激您的帮助!困惑了一下午了。代码如下:
for (long j=0;j<bi.biHeight;j++)
for(long i=0;i<bi.biWidth;i++)
{
switch(bi.biBitCount) {
case 8: //若为8位bmp,则将绿色0x01替换为红色0x03。
if (gFilechar[i+(bi.biHeight-j-1)*LineBytes]==0x01)
gFilechar[i+(bi.biHeight-j-1)*LineBytes]=0x03;
break; case 24: //若为24位,则将绿色0x00DC00替换为红色0xDC0000
if (gFilechar[i+(bi.biHeight-j-1)*LineBytes] == (unsigned char) 0x00DC00)
gFilechar[i+(bi.biHeight-j-1)*LineBytes] = (unsigned char) 0xDC0000);
break; }
}
若位图为8位,程序可正常执行;
若位图为24位,为何不能?
感激您的帮助!困惑了一下午了。代码如下:
for (long j=0;j<bi.biHeight;j++)
for(long i=0;i<bi.biWidth;i++)
{
switch(bi.biBitCount) {
case 8: //若为8位bmp,则将绿色0x01替换为红色0x03。
if (gFilechar[i+(bi.biHeight-j-1)*LineBytes]==0x01)
gFilechar[i+(bi.biHeight-j-1)*LineBytes]=0x03;
break; case 24: //若为24位,则将绿色0x00DC00替换为红色0xDC0000
if (gFilechar[i+(bi.biHeight-j-1)*LineBytes] == (unsigned char) 0x00DC00)
gFilechar[i+(bi.biHeight-j-1)*LineBytes] = (unsigned char) 0xDC0000);
break; }
}
解决方案 »
- FromHandle不能获取类外的hdc吗???
- 为什么在初始化中非模态对话框显示空白
- unsigned long在我电脑里为什么是倒着排的?
- 请问如何让程序开机时自动启动,但不让其在msconfig中显示?
- 拜教高手一个很实用的问题,欢迎进入!
- 大3学生为了课程设计将要跳楼,救命的快来。。。
- 为什么我在winxp下安装WH_CBT和WH_CALLWNDPROC钩子时一起动就死机????
- 问个菜问题,在vc.net下写c++代码。。。
- 100分求救!怎样使RichEdit中光标所在行背景色用特定颜色,像UltraEdit那样?
- 关于应用程序调用dll的问题
- 急求下段代码的多线程内存问题
- 取进程ID
gFilechar[i+(bi.biHeight-j-1)*LineBytes] == (unsigned char) 0x00DC00
gFilechar[i+(bi.biHeight-j-1)*LineBytes] = (unsigned char) 0xDC0000unsigned char是单字节长,上面的两个强转后都是0
for(char k=2;k>=0;k--){
matchcolor += gFilechar[i*3+(bi.biHeight-j-1)*LineBytes+k]<<(k*8)
}
if (matchcolor == 0x00DC00){
gFilechar[i+(bi.biHeight-j-1)*LineBytes] = 0xDC
gFilechar[i+(bi.biHeight-j-1)*LineBytes+1] = 0;
gFilechar[i+(bi.biHeight-j-1)*LineBytes+2] = 0;
}24位,一个像素用三个字节保存像素值。
for(long i=0;i<bi.biWidth;i++)只能遍历图像三分之一行
matchcolor += gFilechar[i*3+(bi.biHeight-j-1)*LineBytes+2-k]<<(k*8)
2 调试时,matchcolor值为 -394752 -394758 -393216,请问如何查看十进制值为多少?比如0xDC0032;
3 感谢jasonshark(没暑假了...),unsigned char是单字节长,强转后是0;改为char应该可以吧。
4 感谢starshx(数星星)。答复语句中:for(char k=2;k>=0;k--){,我想当然地认为char 为笔误,应改为int。对吧?期待大家的帮助!
if (*(u_short *)gFilechar[i+(bi.biHeight-j-1)*LineBytes] == 0xDC00)
*(u_short *)gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] = 0xDC00;试下吧,瞎猜的~
if (*(u_short *)&gFilechar[i+(bi.biHeight-j-1)*LineBytes] == 0xDC00)
*(u_short *)&gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] = 0xDC00;
if (*(unsigned short *)&gFilechar[i+(bi.biHeight-j-1)*LineBytes] == (unsigned char) 0xDC00 || gFilechar[i+(bi.biHeight-j-1)*LineBytes + 2] == 0x00)*(unsigned short *)&gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] = (unsigned char) 0xDC00;
按照starshx(数星星)的思路,我设置:
for(long i=0;i<bi.biWidth*3;i++)
并进行判断:
if ((gFilechar[3*i+(bi.biHeight-j-1)*LineBytes]==0x00)&&(gFilechar[3*i+1+(bi.biHeight-j-1)*LineBytes]==0x00)&&(gFilechar[3*i+2+(bi.biHeight-j-1)*LineBytes]==0xDC))
{
gFilechar[3*i+(bi.biHeight-j-1)*LineBytes] = 0x00;
gFilechar[3*i+1+(bi.biHeight-j-1)*LineBytes] = 0xDC;
gFilechar[3*i+2+(bi.biHeight-j-1)*LineBytes] = 0x00;
}
为何始终不能满足条件呢?
for(long i=0;i<bi.biWidth*3;i++)
改为:
for(long i=0;i<bi.biWidth;i++)
但)&&(gFilechar[3*i+2+(bi.biHeight-j-1)*LineBytes]==0x00))可以。按照jasonshark(没暑假了...)的提示,改为:
(*(unsigned short *)&gFilechar[3*i+2+(bi.biHeight-j-1)*LineBytes]==0xDC)
也始终不能满足条件。
*(unsigned short *)&gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] = (unsigned short) 0xDC00;你的意思大概就是把RGB的0x00DC00改成0xDC0000, 对吧?
{
gFilechar[i+1+(bi.biHeight-j-1)*LineBytes] = 0xDC;
gFilechar[i+2+(bi.biHeight-j-1)*LineBytes] = 0x00;
}
但不知为何,if ((*(unsigned short *)&gFilechar[i+(bi.biHeight-j-1)*LineBytes]==0x00)&&(*(unsigned short *)&gFilechar[i+1+(bi.biHeight-j-1)*LineBytes]==0x00)&&(*(unsigned short *)&gFilechar[i+2+(bi.biHeight-j-1)*LineBytes]==0xDC))条件始终不能满足。三个条件分开,都可以。为何(()&&()&&())之后就不能满足呢?期盼指正!
if (gFilechar[i+(bi.biHeight-j-1)*LineBytes] = 0x00 ||
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] = 0xDC ||
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 2] = 0x00)
{
*(unsigned short *)&gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] = (unsigned short) 0xDC00;
}
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] == 0xDC ||
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 2] == 0x00)
{
gFilechar[i+(bi.biHeight-j-1)*LineBytes = 0x00;
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] = 0x00;
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 2] = 0xDC
}
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] == 0xDC &&
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 2] == 0x00)
{
gFilechar[i+(bi.biHeight-j-1)*LineBytes = 0x00;
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] = 0x00;
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 2] = 0xDC
}
关于是否需要数据转换的调试结果如下:
1 if (*(unsigned short *)&gFilechar[i+(bi.biHeight-j-1)*LineBytes]==0x00)与
if (gFilechar[i+(bi.biHeight-j-1)*LineBytes]==0x00):二者等同;
2 if (*(unsigned short *)&gFilechar[i+2+(bi.biHeight-j-1)*LineBytes]==0xDC)与
if (gFilechar[i+2+(bi.biHeight-j-1)*LineBytes]==0xDC)不同。前者有满足条件的数据,而后者没有。3 这是否意味着必须添加*(unsigned short *)&进行字符转换呢?关于颜色匹配的调试结果如下:
4 按照上述条件判断时,其中有颜色8C6400。判断是否(==0x64)(==0x00)皆有满足条件像素,但(==0x8C)始终没有满足条件的像素。
这就很奇怪,8C6400千真万确地存在,为何始终不能满足条件(==0x8C)呢?
if (*(unsigned short *)&gFilechar[i+(bi.biHeight-j-1)*LineBytes]==0x00)与
if (gFilechar[i+(bi.biHeight-j-1)*LineBytes]==0x00)是完全不同的判断,前者判断的是两个字节长的0, 后者判断的是单个字节长的0.
if( gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] == (unsigned char)0xDC )
{
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 1] = 0;
gFilechar[i+(bi.biHeight-j-1)*LineBytes + 2] = 0xDC;
}break;
还有一个问题就是你的gFilechar的下标运算是否正确?// 另:楼上的应该是B/G/R顺序。
1 if (*(unsigned short *)&gFilechar[i+2+(bi.biHeight-j-1)*LineBytes]==0xDC)与 if (gFilechar[i+2+(bi.biHeight-j-1)*LineBytes]==0xDC): 前者运行结果正确,后者不正确:按照jasonshark(没暑假了...) 的建议,*(unsigned short *)&是判断两个字节长度,可是不转换,结果不对;2 很奇怪,8C6400千真万确地存在,为何始终不能满足条件(==0x8C)呢?
甚至出现了相同的程序代码,可以识别出图片A中的颜色,却不能识别出图片B中的相同颜色。3 gFilechar的下标和颜色存储顺序(B/G/R)我检查过多次。不会有问题。4 百思不得其解,程序肯定有问题。希望高人告诉我问题1的答案,接着调试。
1 调试时,请问如何查看gFilechar[i+(bi.biHeight-j-1)*LineBytes] 十六进制值为多少?比如0xDC;
用#ifdef _DEBUG/ #endif 括起来,只在调试时用
if (((unsigned char)gFilechar[3*i+(bi.biHeight-j-1)*LineBytes ] == 0x8C)&&((unsigned char)gFilechar[3*i+(bi.biHeight-j-1)*LineBytes +1] == 0x64)&&((unsigned char)gFilechar[3*i+(bi.biHeight-j-1)*LineBytes +2] == 0x00))
{
gFilechar[3*i+(bi.biHeight-j-1)*LineBytes] = 0xBB;
gFilechar[3*i+(bi.biHeight-j-1)*LineBytes + 1] = 0xAA;
gFilechar[3*i+(bi.biHeight-j-1)*LineBytes + 2] = 0xDC;
}
转化为十六进制的调试代码如下:unsigned char c_i = gFilechar[3*i+(bi.biHeight-j-1)*LineBytes] ;
unsigned char c_i1 = gFilechar[3*i+(bi.biHeight-j-1)*LineBytes+1] ;
unsigned char c_i2 = gFilechar[3*i+(bi.biHeight-j-1)*LineBytes+2] ;
char s[99];
sprintf(s,"c=%x%x%x",c_i,c_i1,c_i2); 感谢一切!结贴喽。