/* 16真彩To 256灰度,还有更快的算法吗?*/
#include <time.h>
#include <conio.h>
#include <direct.h>
#include <string.h>
#include "windows.h"void Trace( // 通过错略计算函数fun1,fun2的速度比较哪个在速度上最优
const char *msg, // 显示信息
DWORD cirtimes, // 循环次数
void (*fun1)(void),
void (*fun2)(void)
)
{
time_t dd;
DWORD i;
// 显示信息
printf("\n--------< %s",msg);
// 让程序抢占CPU,消除部分由于程序启动造成的干扰
printf("\n Full cpu...");
dd=time(0);
for(i=0;i<0x10000000;i++);
printf("%d",time(0)-dd); // 粗略计算单循环需要的时间
printf("\n Circle...");
dd=time(0);
for(i=0;i<cirtimes;i++);
printf("%d",time(0)-dd); printf("\n Process times = %d",cirtimes); // 粗略计算fun1需要的时间
printf("\n Process fun1...");
dd=time(0);
for(i=0;i<cirtimes;i++)
(*fun1)();
printf("%d",time(0)-dd); // 粗略计算fun2需要的时间
printf("\n Process fun2...");
dd=time(0);
for(i=0;i<cirtimes;i++)
(*fun2)();
printf("%d",time(0)-dd);
printf("\n--------< end\n");
}
#define TIM_TRY4 0xFF1 // 循环次数
// 图象显示区域
#define NES_DISP_WIDTH 256
#define NES_DISP_HEIGHT 240// 存储图象的内存区域
BYTE pScreenMem[NES_DISP_WIDTH*NES_DISP_HEIGHT*2];/* 经过计算得到的16真彩图象
需要将这个图象进行灰度化然后拷贝到存储图象的内存区域
*/
WORD workframe[NES_DISP_WIDTH*NES_DISP_HEIGHT];/* 算法:
算法依据为:
已知某16真彩的象素数值为A, 由于16真彩采用15bit 即5,5,5表示红绿蓝
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|<-- 红 -->| |<-- 绿 -->| |<-- 蓝 -->| 设 红=R 绿=G 蓝=B
则:灰度级Gr=(R*0.299+G*0.587+B*0.114), 为了计算数度快,不采用浮点数,
即使用: Gr=(R*(0.299<<15)+G*(0.587<<15)+B*(0.114<<15))>>15
即: Gr= ( ( 9798*R + 19235*G + 3735*B)>>15);
则该象素的256灰度数值为RGB(Gr<<3,Gr<<3,Gr<<3);
需要得到的不是象素的256灰度数值RGB(Gr<<3,Gr<<3,Gr<<3);
而是以16真彩方式表示的数值即:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|<-- Gr -->| |<-- Gr -->| |<-- Gr -->|*//* 算法1 */
void Tool4Fun1()
{
int x,y,idx=0;
DWORD R,G,B,Gr,wColor;
WORD *lpbuf=(WORD*)pScreenMem;
/* Exchange 16-bit to 256 gray */
for ( y = 0; y < NES_DISP_HEIGHT; y++ )
{
for ( x = 0; x < NES_DISP_WIDTH; x++ )
{
wColor = workframe[ ( y << 8 ) + x ];
R = ( ( wColor & 0x7c00 ) >>10 );
G = ( ( wColor & 0x03e0 ) >>5 );
B = ( ( wColor & 0x001f ) );
Gr= ( ( 9798*R + 19235*G + 3735*B)>>15);
lpbuf[idx]=(WORD)((Gr<<10)|(Gr<<5)|Gr);
idx++;
}
}
}
/* 算法2 */
void Tool4Fun2()
{
int x,y,idx=0;
DWORD R,G,B,wColor;
WORD Gr1,Gr2;
WORD *lpbuf=(WORD*)pScreenMem;
/* Exchange 16-bit to 256 gray */
for ( y = 0; y < NES_DISP_HEIGHT; y++ )
{
for ( x = 0; x < NES_DISP_WIDTH; x+=2 )
{
wColor = ((workframe[ ( y << 8 ) + x ])<<16)|(workframe[ ( y << 8 ) + x +1]);
R = ( wColor & 0x7c007c00 );
G = ( wColor & 0x03e003e0 );
B = ( wColor & 0x001f001f );
Gr1= (WORD)(( 9798*(R>>26) + 19235*(G>>21) + 3735*(B>>16))>>15);
Gr2= (WORD)(( 9798*((R&0xFFFF)>>10) + 19235*((G&0xFFFF)>>5) + 3735*((B&0xFFFF)) )>>15);
lpbuf[idx++]=((Gr1<<10)|(Gr1<<5)|Gr1);
lpbuf[idx++]=((Gr2<<10)|(Gr2<<5)|Gr2);
}
}
}void Tool4()
{
Trace("Tool4",TIM_TRY4,&Tool4Fun1,&Tool4Fun2);
}
int main(int argc, char* argv[])
{
Tool4();
return 0;
}
解决方案 »
- VC网络编程如何发送结构体数据?
- 关于支持第三方插件的软件体系架构!!
- 用classwizzard给edit控件添加变量后出错
- 请问这样得到CListCtrl的第1个item的指针?50分在线等
- static void PASCAL Remove( LPCTSTR lpszFileName );中PASCAL 是嘛意思啊?
- 谁有《MFC Windows 程序设计》电子版?
- MDI中CDocManager的问题......
- 如何不断地,刷新视图Doc窗口内的曲线图象....
- 有没有像CFileDialog这类的,关于网络的标准对话框,就像安装网络打印机里面浏览网络的一样
- 大家好,我来了!!
- 大侠救急, vc编译好的程序不能运行, 出现如下错误:
- 大侠救急, vc编译好的程序不能运行,问题不能解决。急急急!!
void ConvertGray(PBYTE lpImgData,PBYTE lpResultImgData)
{
PUINT32 lpResultPtr;
PBYTE lpPtr;
unsigned int x,y;
unsigned int av=0xFFFF;
unsigned __int64 1=0x7C007C007C007C00,2=0x03E003E003E003E0,3=0x001F001F001F001F;
unsigned int off=(m_iDpi[m_nChannel]<<1);
unsigned int srcoff=(off<<2);
unsigned int GRAY;
DWORD dwLineBytes=(m_iWidth<<1);
DWORD dwBufSize=dwLineBytes*m_iHeight;
for(y=0;y<HEIGHT;y++)
{
lpResultPtr=(PUINT32)(lpResultImgData+(GrayImgDataSize-WIDTH-y*WIDTH));
lpPtr=lpImgData+dwBufSize-(y*m_iDpi[m_nChannel]+1)*dwLineBytes;
for(x=0;x<(WIDTH>>2);x++)
{
__asm{
pxor mm0,mm0
mov edx,dword ptr [lpPtr] //取32bit像素地址到edx
movd mm1,dword ptr [edx] //把Source像素取到mm1低32bit
pand mm1,av add edx,off
movd mm4,dword ptr[edx]
pand mm4,av
psllq mm4,16 add edx,off
movd mm5,dword ptr[edx]
pand mm5,av
psllq mm5,32 add edx,off
movd mm6,dword ptr[edx]
psllq mm6,48 por mm1,mm4
por mm1,mm5
por mm1,mm6; movq mm2,mm1
movq mm3,mm1 pand mm1,1
psrlw mm1,7
pand mm2,2
psrlw mm2,1
pand mm3,3
psllw mm3,3 paddusw mm1,mm2
paddusw mm1,mm3
psrlq mm1,2 packuswb mm1,mm0
movd GRAY,mm1
//mov edx,dword ptr [lpResultPtr]
//movd dword ptr [edx],mm1 //保存结果
}
lpPtr+=srcoff;
*lpResultPtr++=GRAY;
}
}
__asm emms
}
你这个代码到底有多快?
我写的那个东西,几乎已经达到了我的内存速度的上限了——我的是PC133的内存,PIII 700Mhz CPU