如何快速将二级灰度转换成16级灰度

zhongyuanceshi 2010-04-24 09:57:54
有一个buffer,大小为size,buffer[size],每一个元素存储一个字节,比如:0x38,0xF0;每一个字节中的一位代表黑白一种颜色,如:0x38=0011 1000,表示:白白黑黑 黑白白白点像素,即二级灰度:一个像素点用一位表示。
现要将以上buffer转换成16级灰度:一个像素点要用4为表示,如0x38=0011 1000,对应的16级灰度为0x00,0xFF,0xF0,0x00。一个字节扩大4个字节size*4.
有什么好的方法?
...全文
302 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
haierpro 2010-04-26
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 zhongyuanceshi 的回复:]

引用 14 楼 haierpro 的回复:
5楼的代码可能好理解,但效率可是相当的低啊


效率低吗?你是怎么分析的?是否有效率更好的?
[/Quote]

效率真低不是因为联合体,而是因为位域操作
haierpro 2010-04-26
  • 打赏
  • 举报
回复

unsigned int gTranMap[256] =
{
0x00000000, 0x0000000F, 0x000000F0, 0x000000FF, 0x00000F00, 0x00000F0F, 0x00000FF0, 0x00000FFF,
0x0000F000, 0x0000F00F, 0x0000F0F0, 0x0000F0FF, 0x0000FF00, 0x0000FF0F, 0x0000FFF0, 0x0000FFFF,
0x000F0000, 0x000F000F, 0x000F00F0, 0x000F00FF, 0x000F0F00, 0x000F0F0F, 0x000F0FF0, 0x000F0FFF,
0x000FF000, 0x000FF00F, 0x000FF0F0, 0x000FF0FF, 0x000FFF00, 0x000FFF0F, 0x000FFFF0, 0x000FFFFF,
0x00F00000, 0x00F0000F, 0x00F000F0, 0x00F000FF, 0x00F00F00, 0x00F00F0F, 0x00F00FF0, 0x00F00FFF,
0x00F0F000, 0x00F0F00F, 0x00F0F0F0, 0x00F0F0FF, 0x00F0FF00, 0x00F0FF0F, 0x00F0FFF0, 0x00F0FFFF,
0x00FF0000, 0x00FF000F, 0x00FF00F0, 0x00FF00FF, 0x00FF0F00, 0x00FF0F0F, 0x00FF0FF0, 0x00FF0FFF,
0x00FFF000, 0x00FFF00F, 0x00FFF0F0, 0x00FFF0FF, 0x00FFFF00, 0x00FFFF0F, 0x00FFFFF0, 0x00FFFFFF,
0x0F000000, 0x0F00000F, 0x0F0000F0, 0x0F0000FF, 0x0F000F00, 0x0F000F0F, 0x0F000FF0, 0x0F000FFF,
0x0F00F000, 0x0F00F00F, 0x0F00F0F0, 0x0F00F0FF, 0x0F00FF00, 0x0F00FF0F, 0x0F00FFF0, 0x0F00FFFF,
0x0F0F0000, 0x0F0F000F, 0x0F0F00F0, 0x0F0F00FF, 0x0F0F0F00, 0x0F0F0F0F, 0x0F0F0FF0, 0x0F0F0FFF,
0x0F0FF000, 0x0F0FF00F, 0x0F0FF0F0, 0x0F0FF0FF, 0x0F0FFF00, 0x0F0FFF0F, 0x0F0FFFF0, 0x0F0FFFFF,
0x0FF00000, 0x0FF0000F, 0x0FF000F0, 0x0FF000FF, 0x0FF00F00, 0x0FF00F0F, 0x0FF00FF0, 0x0FF00FFF,
0x0FF0F000, 0x0FF0F00F, 0x0FF0F0F0, 0x0FF0F0FF, 0x0FF0FF00, 0x0FF0FF0F, 0x0FF0FFF0, 0x0FF0FFFF,
0x0FFF0000, 0x0FFF000F, 0x0FFF00F0, 0x0FFF00FF, 0x0FFF0F00, 0x0FFF0F0F, 0x0FFF0FF0, 0x0FFF0FFF,
0x0FFFF000, 0x0FFFF00F, 0x0FFFF0F0, 0x0FFFF0FF, 0x0FFFFF00, 0x0FFFFF0F, 0x0FFFFFF0, 0x0FFFFFFF,
0xF0000000, 0xF000000F, 0xF00000F0, 0xF00000FF, 0xF0000F00, 0xF0000F0F, 0xF0000FF0, 0xF0000FFF,
0xF000F000, 0xF000F00F, 0xF000F0F0, 0xF000F0FF, 0xF000FF00, 0xF000FF0F, 0xF000FFF0, 0xF000FFFF,
0xF00F0000, 0xF00F000F, 0xF00F00F0, 0xF00F00FF, 0xF00F0F00, 0xF00F0F0F, 0xF00F0FF0, 0xF00F0FFF,
0xF00FF000, 0xF00FF00F, 0xF00FF0F0, 0xF00FF0FF, 0xF00FFF00, 0xF00FFF0F, 0xF00FFFF0, 0xF00FFFFF,
0xF0F00000, 0xF0F0000F, 0xF0F000F0, 0xF0F000FF, 0xF0F00F00, 0xF0F00F0F, 0xF0F00FF0, 0xF0F00FFF,
0xF0F0F000, 0xF0F0F00F, 0xF0F0F0F0, 0xF0F0F0FF, 0xF0F0FF00, 0xF0F0FF0F, 0xF0F0FFF0, 0xF0F0FFFF,
0xF0FF0000, 0xF0FF000F, 0xF0FF00F0, 0xF0FF00FF, 0xF0FF0F00, 0xF0FF0F0F, 0xF0FF0FF0, 0xF0FF0FFF,
0xF0FFF000, 0xF0FFF00F, 0xF0FFF0F0, 0xF0FFF0FF, 0xF0FFFF00, 0xF0FFFF0F, 0xF0FFFFF0, 0xF0FFFFFF,
0xFF000000, 0xFF00000F, 0xFF0000F0, 0xFF0000FF, 0xFF000F00, 0xFF000F0F, 0xFF000FF0, 0xFF000FFF,
0xFF00F000, 0xFF00F00F, 0xFF00F0F0, 0xFF00F0FF, 0xFF00FF00, 0xFF00FF0F, 0xFF00FFF0, 0xFF00FFFF,
0xFF0F0000, 0xFF0F000F, 0xFF0F00F0, 0xFF0F00FF, 0xFF0F0F00, 0xFF0F0F0F, 0xFF0F0FF0, 0xFF0F0FFF,
0xFF0FF000, 0xFF0FF00F, 0xFF0FF0F0, 0xFF0FF0FF, 0xFF0FFF00, 0xFF0FFF0F, 0xFF0FFFF0, 0xFF0FFFFF,
0xFFF00000, 0xFFF0000F, 0xFFF000F0, 0xFFF000FF, 0xFFF00F00, 0xFFF00F0F, 0xFFF00FF0, 0xFFF00FFF,
0xFFF0F000, 0xFFF0F00F, 0xFFF0F0F0, 0xFFF0F0FF, 0xFFF0FF00, 0xFFF0FF0F, 0xFFF0FFF0, 0xFFF0FFFF,
0xFFFF0000, 0xFFFF000F, 0xFFFF00F0, 0xFFFF00FF, 0xFFFF0F00, 0xFFFF0F0F, 0xFFFF0FF0, 0xFFFF0FFF,
0xFFFFF000, 0xFFFFF00F, 0xFFFFF0F0, 0xFFFFF0FF, 0xFFFFFF00, 0xFFFFFF0F, 0xFFFFFFF0, 0xFFFFFFFF,
};

void Gray2ToGray16(unsigned char *buffer,int size)
{
int i,j=0;
unsigned int DesBuffer[5];
unsigned char *p1 = buffer;
unsigned char *p2 = buffer + size;
unsigned int *p3 = DesBuffer;

while(p1 < p2)
{
*p3++ = gTranMap[*p1++];
}

for(i=0;i<5;i++)
{
printf("0x%08x ",DesBuffer[i]);
}
return;
}

int main(int c,char *v[])
{
unsigned char buffer[5]={0x38,0xff,0xf0,0x07,0x78};
int i=0;

for(i=0;i<5;i++)
{
printf("0x%08x ",buffer[i]);
}
printf("\n");

Gray2ToGray16(buffer,5);

return 0;
}
zhongyuanceshi 2010-04-25
  • 打赏
  • 举报
回复

#include "stdafx.h"


#include <stdio.h>

typedef struct uuc
{
unsigned char c1:1;
unsigned char c2:1;
unsigned char c3:1;
unsigned char c4:1;
unsigned char c5:1;
unsigned char c6:1;
unsigned char c7:1;
unsigned char c8:1;
} Uuc;
typedef union
{
unsigned char unc;
Uuc uuc;
}UUc;
typedef struct unc
{
unsigned int n1:4;
unsigned int n2:4;
unsigned int n3:4;
unsigned int n4:4;
unsigned int n5:4;
unsigned int n6:4;
unsigned int n7:4;
unsigned int n8:4;
} Unc;
typedef union
{
unsigned int unn;
Unc uun;
}UNc;
unsigned int expend(unsigned char c)
{
UUc uc;
UNc un;
uc.unc=c;
un.unn=0;

un.uun.n1=uc.uuc.c1?0xf:0x0;
un.uun.n2=uc.uuc.c2?0xf:0x0;
un.uun.n3=uc.uuc.c3?0xf:0x0;
un.uun.n4=uc.uuc.c4?0xf:0x0;
un.uun.n5=uc.uuc.c5?0xf:0x0;
un.uun.n6=uc.uuc.c6?0xf:0x0;
un.uun.n7=uc.uuc.c7?0xf:0x0;
un.uun.n8=uc.uuc.c8?0xf:0x0;
return un.unn;
}

void Gray2ToGray16(unsigned char *buffer,int size)
{
int i,j=0;
unsigned char DesBuffer[5*4]={0x00};
unsigned int bufTmp;



for(i=0;i<5;i++)
{//分别将4字节类型拆开写成4个单字节
bufTmp=expend(buffer[i]);
DesBuffer[j]=(unsigned char)(bufTmp>>24);//出错:0xc0000005,Access Violation
DesBuffer[++j]=(unsigned char)((bufTmp>>16)&0x000000ff);
DesBuffer[++j]=(unsigned char)((bufTmp>>8)&0x000000ff);
DesBuffer[++j]=(unsigned char)(bufTmp&0x000000ff);
j++;
}

for(i=0;i<5*4;i++)
{
printf("0x%02x ",DesBuffer[i]);
if((i+1)%4==0)
printf("\n");
}
}

int main(void)
{
unsigned char buffer[5]={0x38,0xff,0xf0,0x07,0x78};
int i=0;

for(i=0;i<5;i++)
{
printf("0x%02x ",buffer[i]);
}
printf("\n");

Gray2ToGray16(buffer,5);

return 0;
}


搞定了,不知道是否用联合体效率也低吗?
zhongyuanceshi 2010-04-25
  • 打赏
  • 举报
回复
5楼用联合体效率低吗?难道还比用for循环还低?怎样分析它效率是低的呢?

分别拆分了个字节。是少拆分了第二个字节。
zhongyuanceshi 2010-04-25
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 haierpro 的回复:]
5楼的代码可能好理解,但效率可是相当的低啊
[/Quote]

效率低吗?你是怎么分析的?是否有效率更好的?
zhongyuanceshi 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 haierpro 的回复:]
引用 4 楼 zhongyuanceshi 的回复:

这个应该算是很快了,但不切实际,每一个字都有几十个字节,也是不公开的,都做成了字模数据,有好几万字,每屏每次显示的字也是不一样的,所以提前计算所有情况是不实际的。


以字节为单位做映射表,也就256个元素,1位扩展为4位,那1个字节就扩展为4个字节了,也就256个int型,这很容实现啊
[/Quote]

不明白,是不是和3楼一样的意思呢?
zhongyuanceshi 2010-04-24
  • 打赏
  • 举报
回复
5楼不错,接分。
haierpro 2010-04-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zhongyuanceshi 的回复:]

这个应该算是很快了,但不切实际,每一个字都有几十个字节,也是不公开的,都做成了字模数据,有好几万字,每屏每次显示的字也是不一样的,所以提前计算所有情况是不实际的。
[/Quote]

以字节为单位做映射表,也就256个元素,1位扩展为4位,那1个字节就扩展为4个字节了,也就256个int型,这很容实现啊
zhanghui0070075 2010-04-24
  • 打赏
  • 举报
回复

#include <stdio.h>

typedef struct uuc
{
unsigned char c1:1;
unsigned char c2:1;
unsigned char c3:1;
unsigned char c4:1;
unsigned char c5:1;
unsigned char c6:1;
unsigned char c7:1;
unsigned char c8:1;
} Uuc;
typedef union
{
unsigned char unc;
Uuc uuc;
}UUc;
typedef struct unc
{
unsigned int n1:4;
unsigned int n2:4;
unsigned int n3:4;
unsigned int n4:4;
unsigned int n5:4;
unsigned int n6:4;
unsigned int n7:4;
unsigned int n8:4;
} Unc;
typedef union
{
unsigned int unn;
Unc uun;
}UNc;
unsigned int expend(unsigned char c)
{
UUc uc;
UNc un;
uc.unc=c;
un.unn=0;

un.uun.n1=uc.uuc.c1?0xf:0x0;
un.uun.n2=uc.uuc.c2?0xf:0x0;
un.uun.n3=uc.uuc.c3?0xf:0x0;
un.uun.n4=uc.uuc.c4?0xf:0x0;
un.uun.n5=uc.uuc.c5?0xf:0x0;
un.uun.n6=uc.uuc.c6?0xf:0x0;
un.uun.n7=uc.uuc.c7?0xf:0x0;
un.uun.n8=uc.uuc.c8?0xf:0x0;
return un.unn;
}
int main(void)
{
unsigned char c=0x38;
printf("%x\n",c);
printf("%x\n",expend(c));
getchar();
return 0;
}

这个程序不错,你们试试
selooloo 2010-04-24
  • 打赏
  • 举报
回复

#include <stdio.h>

typedef struct uuc
{
unsigned char c1:1;
unsigned char c2:1;
unsigned char c3:1;
unsigned char c4:1;
unsigned char c5:1;
unsigned char c6:1;
unsigned char c7:1;
unsigned char c8:1;
} Uuc;
typedef union
{
unsigned char unc;
Uuc uuc;
}UUc;
typedef struct unc
{
unsigned int n1:4;
unsigned int n2:4;
unsigned int n3:4;
unsigned int n4:4;
unsigned int n5:4;
unsigned int n6:4;
unsigned int n7:4;
unsigned int n8:4;
} Unc;
typedef union
{
unsigned int unn;
Unc uun;
}UNc;
unsigned int expend(unsigned char c)
{
UUc uc;
UNc un;
uc.unc=c;
un.unn=0;

un.uun.n1=uc.uuc.c1?0xf:0x0;
un.uun.n2=uc.uuc.c2?0xf:0x0;
un.uun.n3=uc.uuc.c3?0xf:0x0;
un.uun.n4=uc.uuc.c4?0xf:0x0;
un.uun.n5=uc.uuc.c5?0xf:0x0;
un.uun.n6=uc.uuc.c6?0xf:0x0;
un.uun.n7=uc.uuc.c7?0xf:0x0;
un.uun.n8=uc.uuc.c8?0xf:0x0;
return un.unn;
}
int main(void)
{
unsigned char c=0x38;
printf("%x\n",c);
printf("%x\n",expend(c));
getchar();
return 0;
}
zhongyuanceshi 2010-04-24
  • 打赏
  • 举报
回复
这个应该算是很快了,但不切实际,每一个字都有几十个字节,也是不公开的,都做成了字模数据,有好几万字,每屏每次显示的字也是不一样的,所以提前计算所有情况是不实际的。
田暗星 2010-04-24
  • 打赏
  • 举报
回复
我来接分..

什么移位呀 难道比数组寻址还快嘛 搞麻烦了

每1个字节对应 4个字节 提前计算所有情况 保存到数组中 unsigned char HexGray[256][4]

比如 0x38 对应的是
HexGray[0x38][0] = 0x00;
HexGray[0x38][1] = 0xFF;
HexGray[0x38][2] = 0xF0;
HexGray[0x38][3] = 0x00;

这个最快啦
zhongyuanceshi 2010-04-24
  • 打赏
  • 举报
回复
联合体+位移,这可能是个好方法,能不能给个源程序调试先。我也实现了,只是效率不高。由于一屏LCD要显示的字有好几百字,一下子要转换好要显示对速度要求高
selooloo 2010-04-24
  • 打赏
  • 举报
回复
联合体+位移
selooloo 2010-04-24
  • 打赏
  • 举报
回复
int i,j;
unsigned char DesBuffer[5*4]={0x00};
unsigned int bufTmp;



for(i=0;i<5;i++)
{//分别将4字节类型拆开写成4个单字节
bufTmp=expend(buffer[i]);
DesBuffer[j]=(unsigned char)(bufTmp>>24);//出错:0xc0000005,Access Violation DesBuffer[j++]=(unsigned char)((bufTmp>>16)&0x000000ff);
DesBuffer[j++]=(unsigned char)((bufTmp>>8)&0x000000ff);
DesBuffer[j++]=(unsigned char)(bufTmp&0x000000ff);
}
你的j没初始化,而且你是拆分4个字节,上面只拆分了3个吧
haierpro 2010-04-24
  • 打赏
  • 举报
回复
5楼的代码可能好理解,但效率可是相当的低啊
zhongyuanceshi 2010-04-24
  • 打赏
  • 举报
回复
咋没人调试过呢?不知道是不是强制转换有问题?
zhongyuanceshi 2010-04-24
  • 打赏
  • 举报
回复
这里仅需将字节扩大就可以了。如果要是颜色种类也变化,该怎样实现呢?

unsigned char buffer[5]={0x38,0xff,0xf0,0x07,0x78};
写成unsigned char Desbuffer[20]={0x00,0xff,0xf0,0x00,0xff,0xff,0xff,0xff,....};

绿色部分调试出错。
Bestrem_9 2010-04-24
  • 打赏
  • 举报
回复
这个还是挺好的,目的实现了。
但是疑惑在条件表达式的时候,通过原来字节中对应的位的为0或1,而把其扩展位0xF或者0x0,这个意义感觉不是很大。仅仅是将"字节扩大了4倍",但是表示的颜色的种数好像没有变化。
[Quote=引用 5 楼 selooloo 的回复:]
C/C++ code

#include <stdio.h>

typedef struct uuc
{
unsigned char c1:1;
unsigned char c2:1;
unsigned char c3:1;
unsigned char c4:1;
unsigned char c5:1;
……
[/Quote]
zhongyuanceshi 2010-04-24
  • 打赏
  • 举报
回复

#include "stdafx.h"


#include <stdio.h>

typedef struct uuc
{
unsigned char c1:1;
unsigned char c2:1;
unsigned char c3:1;
unsigned char c4:1;
unsigned char c5:1;
unsigned char c6:1;
unsigned char c7:1;
unsigned char c8:1;
} Uuc;
typedef union
{
unsigned char unc;
Uuc uuc;
}UUc;
typedef struct unc
{
unsigned int n1:4;
unsigned int n2:4;
unsigned int n3:4;
unsigned int n4:4;
unsigned int n5:4;
unsigned int n6:4;
unsigned int n7:4;
unsigned int n8:4;
} Unc;
typedef union
{
unsigned int unn;
Unc uun;
}UNc;
unsigned int expend(unsigned char c)
{
UUc uc;
UNc un;
uc.unc=c;
un.unn=0;

un.uun.n1=uc.uuc.c1?0xf:0x0;
un.uun.n2=uc.uuc.c2?0xf:0x0;
un.uun.n3=uc.uuc.c3?0xf:0x0;
un.uun.n4=uc.uuc.c4?0xf:0x0;
un.uun.n5=uc.uuc.c5?0xf:0x0;
un.uun.n6=uc.uuc.c6?0xf:0x0;
un.uun.n7=uc.uuc.c7?0xf:0x0;
un.uun.n8=uc.uuc.c8?0xf:0x0;
return un.unn;
}

void Gray2ToGray16(unsigned char *buffer,int size)
{
int i,j;
unsigned char DesBuffer[5*4]={0x00};
unsigned int bufTmp;



for(i=0;i<5;i++)
{//分别将4字节类型拆开写成4个单字节
bufTmp=expend(buffer[i]);
DesBuffer[j]=(unsigned char)(bufTmp>>24);//出错:0xc0000005,Access Violation DesBuffer[j++]=(unsigned char)((bufTmp>>16)&0x000000ff);
DesBuffer[j++]=(unsigned char)((bufTmp>>8)&0x000000ff);
DesBuffer[j++]=(unsigned char)(bufTmp&0x000000ff);
}

for(i=0;i<5*4;i++)
{
printf("0x%02x ",DesBuffer[i]);
if(i%5)
printf("\n");
}
}

int main(void)
{
unsigned char buffer[5]={0x38,0xff,0xf0,0x07,0x78};
int i=0;

for(i=0;i<5;i++)
{
printf("0x%02x ",buffer[i]);
}
printf("\n");

Gray2ToGray16(buffer,5);

return 0;
}


用了5楼的好方法,具体将5个元素的数组转成20个数组,红色部分调试出错,啥原因?

69,382

社区成员

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

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