如何将图像缩放的速度提高到photoshop那样快(100分)

  • 主题发起人 主题发起人 hitman007260
  • 开始时间 开始时间
原来先是贴在这里啊,这段C++程序。

只要知道指令集的十六进制码,就像我那边说的,用DB DW DD写一样能执行,只要CPU认识。
怎么查SSE指令,那就不知道了,有个很白痴的方法,就是用W32Dasm反汇编后搜指令,至少我曾经傻过...
 
木桩大侠,这个函数有逻辑错误吗?? 我老是搞不定
 
第三个没有什么问题吧,都是些类型转换,前两个汇编看不懂,那些punpcklbw psrlw 作什么用来者啊...
图像方面的算法我也无能为力啊。
 
前面的两个函数就是把
p_out[x_out * sizeof(DWORD) + 0] = (BYTE)(((int)p_in1[x1 * sizeof(DWORD) + 0] + (int)p_in2[x2 * sizeof(DWORD) + 0]) / 2);
p_out[x_out * sizeof(DWORD) + 1] = (BYTE)(((int)p_in1[x1 * sizeof(DWORD) + 1] + (int)p_in2[x2 * sizeof(DWORD) + 1]) / 2);
p_out[x_out * sizeof(DWORD) + 2] = (BYTE)(((int)p_in1[x1 * sizeof(DWORD) + 2] + (int)p_in2[x2 * sizeof(DWORD) + 2]) / 2);
p_out[x_out * sizeof(DWORD) + 3] = (BYTE)(((int)p_in1[x1 * sizeof(DWORD) + 3] + (int)p_in2[x2 * sizeof(DWORD) + 3]) / 2);
的运算用MMX指令来代替
 
最原始的函数是这个
unsigned int AverageResize32(void * out,int out_width,int out_height,int out_pitch,
const void * in,int in_width,int in_height,int in_pitch)
{
for(int y_out=0; y_out<out_height; ++y_out)
{
for(int x_out=0; x_out<out_width; ++x_out)
{
int y_in1 = max(0,(y_out - 0.5f) * in_height / out_height);
int x_in1 = max(0,(x_out - 0.5f) * in_width / out_width);
int y_in2 = (y_out + 0.5f) * in_height / out_height;
int x_in2 = (x_out + 0.5f) * in_width / out_width;

BYTE * p_out = (BYTE *)((int)out + out_pitch * y_out + x_out * sizeof(DWORD));
BYTE * p_in1 = (BYTE *)((int)in + in_pitch * y_in1 + x_in1 * sizeof(DWORD));
BYTE * p_in2 = (BYTE *)((int)in + in_pitch * y_in2 + x_in2 * sizeof(DWORD));
#if DOUBLE_AVERAGE
BYTE * p_in3 = (BYTE *)((int)in + in_pitch * y_in1 + x_in2 * sizeof(DWORD));
BYTE * p_in4 = (BYTE *)((int)in + in_pitch * y_in2 + x_in1 * sizeof(DWORD));
#endif

#if DOUBLE_AVERAGE
p_out[0] = (BYTE)(((int)p_in1[0] + (int)p_in2[0] + (int)p_in3[0] + (int)p_in4[0]) / 4);
p_out[1] = (BYTE)(((int)p_in1[1] + (int)p_in2[1] + (int)p_in3[1] + (int)p_in4[1]) / 4);
p_out[2] = (BYTE)(((int)p_in1[2] + (int)p_in2[2] + (int)p_in3[2] + (int)p_in4[2]) / 4);
p_out[3] = (BYTE)(((int)p_in1[3] + (int)p_in2[3] + (int)p_in3[3] + (int)p_in4[3]) / 4);
#else
p_out[0] = (BYTE)(((int)p_in1[0] + (int)p_in2[0]) / 2);
p_out[1] = (BYTE)(((int)p_in1[1] + (int)p_in2[1]) / 2);
p_out[2] = (BYTE)(((int)p_in1[2] + (int)p_in2[2]) / 2);
p_out[3] = (BYTE)(((int)p_in1[3] + (int)p_in2[3]) / 2);
#endif
}
}
return 0;
}
有没有错误?我该输入什马?
 
DOUBLE_AVERAGE 是编译器预定的常量吗?
 
凌霄图像批处理专家是一款图片批处理工具,它集批量图片格式转换、批量图片修改处理、批量重命名、批量调整尺寸、批量晒图导出、创建EXE文件、创建PDF文件于一体的图片批处理系统。凌霄图像批处理专家提供将近30种图片修改处理脚本命令(如调整亮度等)供您任意组合使用!她还可以让您轻松的将任意多的图像(图片)文件生成一个EXE或PDF文件,并提供多达150种的显示效果,方便您欣赏自己的图片,并轻易实现与家人、朋友分享!她支持多达11种(BMP, JPG,PNG, EXIF, GIF, WMF,ICO, TGA, PCX,TIFF, PPM )的基本图片格式输出。如果加上与他们等价的格式,则支持的打开图片类型超过30种。而且所有这些功能,您都可以在Windows资源管理器中通过右键菜单轻松使用。
下载地址:www.flyingspace.com
 
TO:hitman007260 正在研究MMX。可以以去看一下我的笔记,对你提供的C++代码感兴趣,试试先。
 
楼上的强人 帮帮忙
 
用graphics32控件吧。
开源免费的
 
哪里缩放的原理呀?看源码看的很累人,还可能有误解。希望哪位给出来!
To:hitman007260 C++源码我已经改出来了,但没用去试验正确以否,因为C++改过的指针在DELPHI中不是那么好用。
-------------------------------------------
var
__idecimal:integer = 4096

function AverageResize32VergeLine(p_out,p_in1,p_in2:PByte;x_verge,x_in2,x_delta:integer):integer;
begin

//ebx : x_in2
//ecx : x_out
//edi : p_out
//esi : p_in1
//edx : p_in2
asm

xor ecx,ecx
cmp ecx,x_verge
ja @__end

mov edi,p_out
mov esi,p_in1
mov edx,p_in2
mov ebx,x_in2
@__loop:
mov eax,ebx
shr eax,12
movd mm0,dword ptr [esi + eax * 4 + 0]
movd mm3,dword ptr [edx + eax * 4 + 0]

punpcklbw mm0,mm0
punpcklbw mm3,mm3
psrlw mm0,8
psrlw mm3,8
paddw mm0,mm3
psrlw mm0,1
packuswb mm0,mm0

movd dword ptr[edi + ecx * 4 + 0],mm0
add ebx,x_delta

inc ecx
cmp ecx,x_verge
jbe @__loop
@__end:
mov x_in2,ebx
end;
Result:= x_in2;
end;

procedure AverageResize32Line(p_out,p_in1,p_in2:PByte;
x_verge,out_width,x_in2,x_delta:integer);
begin

//ebx : x_in2
//ecx : x_out
//edi : p_out
//esi : p_in1
//edx : p_in2
asm
mov ecx,x_verge
cmp ecx,out_width
jae @__end

mov edi,p_out
mov esi,p_in1
mov edx,p_in2
mov ebx,x_in2
@__loop:
//#if DOUBLE_AVERAGE
mov eax,ebx
sub eax,x_delta
shr eax,12
movd mm0,dword ptr [esi + eax * 4 + 0]
movd mm1,dword ptr [edx + eax * 4 + 0]

mov eax,ebx
shr eax,12
movd mm2,dword ptr [esi + eax * 4 + 0]
movd mm3,dword ptr [edx + eax * 4 + 0]

punpcklbw mm0,mm0
punpcklbw mm1,mm1
punpcklbw mm2,mm2
punpcklbw mm3,mm3
psrlw mm0,8
psrlw mm1,8
psrlw mm2,8
psrlw mm3,8
paddw mm2,mm3
paddw mm0,mm1
paddw mm0,mm2
psrlw mm0,2
packuswb mm0,mm0
//#else
mov eax,ebx
sub eax,x_delta
shr eax,12
movd mm0,dword ptr [esi + eax * 4 + 0]

mov eax,ebx
shr eax,12
movd mm3,dword ptr [edx + eax * 4 + 0]

punpcklbw mm0,mm0
punpcklbw mm3,mm3
psrlw mm0,8
psrlw mm3,8
paddw mm0,mm3
psrlw mm0,1
packuswb mm0,mm0
//#endif
movd dword ptr[edi + ecx * 4 + 0],mm0
add ebx,x_delta

inc ecx
cmp ecx,out_width
jb @__loop
@__end:
end;
end;

function AverageResize32(Pout:Pointer;out_width,out_height,out_pitch:integer;
const Pin:Pointer;in_width,in_height,in_pitch:integer):integer;
var
y_delta,x_delta,y_verge,x_verge:integer;
p_out:PByte;
y_in2,x_in2:integer;
p_in1,p_in2:PByte;
y_out:integer;
begin

//边界值
y_delta := (__idecimal * in_height) div out_height;
x_delta := (__idecimal * in_width) div out_width;
y_verge := (in_height div out_height) div 2;
x_verge := (in_width div out_width) div 2;

// BYTE * p_out = (BYTE *)out;
p_out := PByte(Pout);

y_in2 := y_delta div 2;

//y边界条件
p_in1 := Pbyte(Pin);
p_in2 := PByte(integer(Pin) + in_pitch * (y_in2 div __idecimal));
for y_out:=0 to y_verge-1 do begin
//y,x边界条件
x_in2 := x_delta div 2;
x_in2 := AverageResize32VergeLine(p_out,p_in1,p_in2,x_verge,x_in2,x_delta);
AverageResize32Line(p_out,p_in1,p_in2,x_verge,out_width,x_in2,x_delta);

p_out := PByte(integer(p_out) + out_pitch);

y_in2 := y_in2+y_delta;
p_in2 := PByte(integer(p_in2) + in_pitch * (y_in2 div __idecimal));
y_in2 := y_in2 xor __idecimal; // ??????? %= 与
end;

p_in1 := PByte(Integer(Pin) + in_pitch * ((y_delta * y_out - y_delta div 2) div __idecimal));
p_in2 := PByte(Integer(Pin) + in_pitch * ((y_delta * y_out + y_delta div 2) div __idecimal));
for y_out:=y_verge-1 to out_height-1 do begin
//x边界条件
x_in2 := x_delta div 2;
x_in2 := AverageResize32VergeLine(p_out,p_in1,p_in2,x_verge,x_in2,x_delta);
AverageResize32Line(p_out,p_in1,p_in2,x_verge,out_width,x_in2,x_delta);

p_out := PByte(integer(p_out) + out_pitch);

y_in2 := y_in2+y_delta;
p_in1 := p_in2;
//p_in1 = (BYTE *)((int)p_in1 + in_pitch * (y_in2 / __idecimal));
p_in2 := PByte(Integer(p_in2) + in_pitch * (y_in2 div __idecimal));
y_in2 := y_in2 xor __idecimal;
end;

asm
emms;
end;
result := 0;
end;
 

Similar threads

后退
顶部