图片缩放旋转Word格式.docx

上传人:b****6 文档编号:16203782 上传时间:2022-11-21 格式:DOCX 页数:50 大小:155.35KB
下载 相关 举报
图片缩放旋转Word格式.docx_第1页
第1页 / 共50页
图片缩放旋转Word格式.docx_第2页
第2页 / 共50页
图片缩放旋转Word格式.docx_第3页
第3页 / 共50页
图片缩放旋转Word格式.docx_第4页
第4页 / 共50页
图片缩放旋转Word格式.docx_第5页
第5页 / 共50页
点击查看更多>>
下载资源
资源描述

图片缩放旋转Word格式.docx

《图片缩放旋转Word格式.docx》由会员分享,可在线阅读,更多相关《图片缩放旋转Word格式.docx(50页珍藏版)》请在冰豆网上搜索。

图片缩放旋转Word格式.docx

#define 

asm 

__asm

typedef 

unsigned 

char 

TUInt8;

// 

[0..255]

struct 

TARGB32 

//32 

bit 

color

{

TUInt8 

B,G,R,A;

is 

alpha

};

TPicRegion 

//一块颜色数据区的描述,便于参数传递

TARGB32* 

pdata;

//颜色数据首地址

long 

byte_width;

//一行数据的物理宽度(字节宽度);

//abs(byte_width)有可能大于等于width*sizeof(TARGB32);

width;

//像素宽度

height;

//像素高度

//那么访问一个点的函数可以写为:

inline 

TARGB32&

Pixels(const 

TPicRegion&

pic,const 

x,const 

y)

return 

( 

(TARGB32*)((TUInt8*)pic.pdata+pic.byte_width*y) 

)[x];

}

B:

缩放原理和公式图示:

缩放后图片 

 

原图片

(宽DW,高DH) 

(宽SW,高SH)

(Sx-0)/(SW-0)=(Dx-0)/(DW-0) 

(Sy-0)/(SH-0)=(Dy-0)/(DH-0)

=>

Sx=Dx*SW/DW 

Sy=Dy*SH/DH

C:

缩放算法的一个参考实现

//给出一个最简单的缩放函数(插值方式为近邻取样,而且我“尽力”把它写得慢一些了:

D)

//Src.PColorData指向源数据区,Dst.PColorData指向目的数据区

//函数将大小为Src.Width*Src.Height的图片缩放到Dst.Width*Dst.Height的区域中

void 

PicZoom0(const 

Dst,const 

Src)

if 

(0==Dst.width)||(0==Dst.height)

||(0==Src.width)||(0==Src.height)) 

return;

for 

(long 

x=0;

x<

Dst.width;

++x)

y=0;

y<

Dst.height;

++y)

srcx=(x*Src.width/Dst.width);

srcy=(y*Src.height/Dst.height);

Pixels(Dst,x,y)=Pixels(Src,srcx,srcy);

//速度测试:

//PicZoom0 

19.4fps

D:

优化PicZoom0函数

a.PicZoom0函数并没有按照颜色数据在内存中的排列顺序读写(内部循环递增y行

索引),将造成CPU缓存预读失败和内存颠簸导致巨大的性能损失,(很多硬件都有这种特性,

包括缓存、内存、显存、硬盘等,优化顺序访问,随机访问时会造成巨大的性能损失)

所以先交换x,y循环的顺序:

PicZoom1(const 

//PicZoom1 

30.1fps

b.“(x*Src.Width/Dst.Width)”表达式中有一个除法运算,它属于很慢的操作(比一般

的加减运算慢几十倍!

),使用定点数的方法来优化它;

PicZoom2(const 

//函数能够处理的最大图片尺寸65536*65536

unsignedlongxrIntFloat_16=(Src.width<

<

16)/Dst.width+1;

//16.16格式定点数

unsignedlongyrIntFloat_16=(Src.height<

16)/Dst.height+1;

//可证明:

(Dst.width-1)*xrIntFloat_16<

Src.width成立

for(unsignedlongy=0;

{

for(unsignedlongx=0;

unsignedlongsrcx=(x*xrIntFloat_16)>

>

16;

unsignedlongsrcy=(y*yrIntFloat_16)>

Pixels(Dst,x,y)=Pixels(Src,srcx,srcy);

}

//PicZoom2 

185.8fps

c. 

在x的循环中y一直不变,那么可以提前计算与y相关的值;

1.可以发现srcy的值和x变量无关,可以提前到x轴循环之前;

2.展开Pixels函数,优化与y相关的指针计算;

voidPicZoom3(constTPicRegion&

Dst,constTPicRegion&

Src)

unsignedlongdst_width=Dst.width;

TARGB32*pDstLine=Dst.pdata;

unsignedlongsrcy_16=0;

TARGB32*pSrcLine=((TARGB32*)((TUInt8*)Src.pdata+Src.byte_width*(srcy_16>

16)));

unsignedlongsrcx_16=0;

dst_width;

pDstLine[x]=pSrcLine[srcx_16>

16];

srcx_16+=xrIntFloat_16;

srcy_16+=yrIntFloat_16;

((TUInt8*&

)pDstLine)+=Dst.byte_width;

//PicZoom3 

414.4fps

d.定点数优化使函数能够处理的最大图片尺寸和缩放结果(肉眼不可察觉的误差)受到了一

定的影响,这里给出一个使用浮点运算的版本,可以在有这种需求的场合使用:

PicZoom3_float(const 

//注意:

该函数需要FPU支持

doublexrFloat=1.000000001/((double)Dst.width/Src.width);

doubleyrFloat=1.000000001/((double)Dst.height/Src.height);

short 

RC_Old;

RC_Edit;

//设置FPU的取整方式 

为了直接使用fist浮点指令

FNSTCW 

RC_Old 

保存协处理器控制字,用来恢复

RC_Edit 

保存协处理器控制字,用来修改

FWAIT

OR 

RC_Edit, 

0x0F00 

改为 

RC=11 

使FPU向零取整 

FLDCW 

载入协处理器控制字,RC场已经修改

dst_width=Dst.width;

pDstLine=Dst.pdata;

double 

srcy=0;

(unsigned 

pSrcLine=((TARGB32*)((TUInt8*)Src.pdata+Src.byte_width*((long)srcy)));

/**//*

srcx=0;

pDstLine[x]=pSrcLine[(unsigned 

long)srcx];

//因为默认的浮点取整是一个很慢

//的操作!

所以才使用了直接操作FPU的内联汇编代码。

srcx+=xrFloat;

}*/

fld 

xrFloat 

//st0==xrFloat

fldz 

//st0==0 

st1==xrFloat

fist 

dword 

ptr 

srcx 

//srcx=(long)st0

pDstLine[x]=pSrcLine[srcx];

fadd 

st,st

(1) 

//st0+=st1 

fstp 

st

srcy+=yrFloat;

((TUInt8*&

//恢复FPU的取整方式

//PicZoom3_float 

286.2fps

e.注意到这样一个事实:

每一行的缩放比例是固定的;

那么可以预先建立一个缩放映射表格

来处理缩放映射算法(PicZoom3_Table和PicZoom3_float的实现等价);

PicZoom3_Table(const 

long* 

SrcX_Table 

new 

long[dst_width];

++x)//生成表 

SrcX_Table

SrcX_Table[x]=(x*Src.width/Dst.width);

pSrcLine=((TARGB32*)((TUInt8*)Src.pdata+Src.byte_width*srcy));

pDstLine[x]=pSrcLine[SrcX_Table[x]];

delete 

[] 

SrcX_Table;

//PicZoom3_Table 

390.1fps

f.为了加快缩放,可以采用根据缩放比例动态生成函数的方式来得到更快的缩放函数;

有点像编译器的工作原理;

要实现它需要的工作量比较大(或比较晦涩)就不再实现了;

(动态生成是一种不错的思路,但个人觉得对于缩放,实现它的必要性不大)

g.现代CPU中,在读取数据和写入数据时,都有自动的缓存机制;

很容易知道,算法中生

成的数据不会很快再次使用,所以不需要写入缓存的帮助;

在SSE指令集中增加了movntq

等指令来完成这个功能;

(尝试过利用CPU显式prefetcht0、prefetchnta预读指令或直接的mov读取指令等速度反

而略有下降:

但预读在copy算法中速度优化效果很明显)

PicZoom3_SSE(const 

//警告:

函数需要CPU支持MMX和movntq指令

srcy_16=0;

pSrcLine=((TARGB32*)((TUInt8*)Src.pdata+Src.byte_width*(srcy_16>

asm

push 

ebp

mov 

esi,pSrcLine

edi,pDstLine

edx,xrIntFloat_16

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 工作总结汇报

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1