没有合适的资源?快使用搜索试试~ 我知道了~
任意角度的高质量的快速的图像旋转.doc
4星 · 超过85%的资源 需积分: 10 18 下载量 51 浏览量
2009-06-16
17:57:27
上传
评论
收藏 366KB DOC 举报
温馨提示
试读
62页
摘自网上的同名资源。经过自己整理。不想下载的自己搜"任意角度的高质量的快速的图像旋转".
资源推荐
资源详情
资源评论
高质量的快速的图像缩放 全文 分为:
上篇 近邻取样插值和其速度优化
中篇 二次线性插值和三次卷积插值
下篇 三次线性插值和 MipMap 链
图形图像处理-之-高质量的快速的图像缩放 上篇 近邻取样插值和其速度优化
( 2007.06.06 更新测试数据,编译器由 vc6 改为 vc2005,CPU 由赛扬 2G 改为 AMD64x2
4200+(2.1G) )
(2007.01.02 更新)
tag:图像缩放,速度优化,定点数优化,近邻取样插值,二次线性插值,三次线性插值,
MipMap 链,三次卷积插值,MMX,SSE,SSE2,CPU 缓存优化
摘要:首先给出一个基本的图像缩放算法,然后一步一步的优化其速度和缩放质量;
正文:OO
为了便于讨论,这里只处理 32bit 的 ARGB 颜色;
代码使用 C++;涉及到汇编优化的时候假定为 x86 平台;使用的编译器为 vc2005;
为了代码的可读性,没有加入异常处理代码;
测试使用的 CPU 为 AMD64x2 4200+(2.37G) 和 Intel Core2 4400(2.00G);
速度测试说明:
只测试内存数据到内存数据的缩放
测试图片都是 800*600 缩放到 1024*768; fps 表示每秒钟的帧数,值越大表示函数越快
/////////////////////////////////////////////////////////////////////
///////////
//Windows GDI 相关函数参考速度:
//===================================================================
===========
// BitBlt544.7 fps //is copy 800*600 to 800*600
// BitBlt331.6 fps //is copy 1024*1024 to 1024*1024
// StretchBlt232.7 fps //is zoom 800*600 to 1024*1024
/////////////////////////////////////////////////////////////////////
///////////
A: 首先定义图像数据结构:
#defineasm__asm
typedefunsignedcharTUInt8;//[0..255]
structTARGB32//32bitcolor
{
TUInt8B,G,R,A;//Aisalpha
};
structTPicRegion//一块颜色数据区的描述,便于参数传递
{
TARGB32*pdata;//颜色数据首地址
longbyte_width;//一行数据的物理宽度(字节宽度);
//abs(byte_width)有可能大于等于 width*sizeof(TARGB32);
longwidth;//像素宽度
longheight;//像素高度
};
//那么访问一个点的函数可以写为:
inlineTARGB32&Pixels(constTPicRegion&pic,constlongx,constlong
y)
{
return((TARGB32*)((TUInt8*)pic.pdata+pic.byte_width*y))[x];
}
B: 缩放原理和公式图示:
缩放后图片OOOOOOOOOOO O原图片
(宽 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 的区域
中
voidPicZoom0(constTPicRegion&Dst,constTPicRegion&Src)
{
if((0==Dst.width)||(0==Dst.height)
||(0==Src.width)||(0==Src.height))return;
for(longx=0;x<Dst.width;++x)
{
for(longy=0;y<Dst.height;++y)
{
longsrcx=(x*Src.width/Dst.width);
longsrcy=(y*Src.height/Dst.height);
Pixels(Dst,x,y)=Pixels(Src,srcx,srcy);
}
}
}
/////////////////////////////////////////////////////////////////////
///////////
//速度测试:
//===================================================================
===========
// PicZoom019.4 fps
/////////////////////////////////////////////////////////////////////
///////////
D: 优化 PicZoom0 函数
a.PicZoom0 函数并没有按照颜色数据在内存中的排列顺序读写(内部循环递增 y 行
索引),将造成 CPU 缓存预读失败和内存颠簸导致巨大的性能损失,(很多硬件都有这种特性,
包括缓存、内存、显存、硬盘等,优化顺序访问,随机访问时会造成巨大的性能损失)
所以先交换 x,y 循环的顺序:
voidPicZoom1(constTPicRegion&Dst,constTPicRegion&Src)
{
if((0==Dst.width)||(0==Dst.height)
||(0==Src.width)||(0==Src.height))return;
for(longy=0;y<Dst.height;++y)
{
for(longx=0;x<Dst.width;++x)
{
longsrcx=(x*Src.width/Dst.width);
longsrcy=(y*Src.height/Dst.height);
Pixels(Dst,x,y)=Pixels(Src,srcx,srcy);
}
}
}
/////////////////////////////////////////////////////////////////////
///////////
//速度测试:
//===================================================================
===========
// PicZoom130.1 fps
/////////////////////////////////////////////////////////////////////
///////////
b.“(x*Src.Width/Dst.Width)”表达式中有一个除法运算,它属于很慢的操作(比一般
的加减运算慢几十倍!),使用定点数的方法来优化它;
voidPicZoom2(constTPicRegion&Dst,constTPicRegion&Src)
{
if((0==Dst.width)||(0==Dst.height)
||(0==Src.width)||(0==Src.height))return;
//函数能够处理的最大图片尺寸 65536*65536
unsigned long xrIntFloat_16=(Src.width<<16)/Dst.width+1;//16.16
格式定点数
unsigned long
yrIntFloat_16=(Src.height<<16)/Dst.height+1;//16.16 格式定点数
//可证明: (Dst.width-1)*xrIntFloat_16<Src.width 成立
for (unsigned long y=0;y<Dst.height;++y)
{
for (unsigned long x=0;x<Dst.width;++x)
{
unsigned long srcx=(x*xrIntFloat_16)>>16;
unsigned long srcy=(y*yrIntFloat_16)>>16;
Pixels(Dst,x,y)=Pixels(Src,srcx,srcy);
}
}
}
/////////////////////////////////////////////////////////////////////
///////////
//速度测试:
//===================================================================
===========
// PicZoom2185.8 fps
/////////////////////////////////////////////////////////////////////
///////////
c. 在 x 的循环中 y 一直不变,那么可以提前计算与 y 相关的值; 1.可以发现 srcy 的值
和 x 变量无关,可以提前到 x 轴循环之前;2.展开 Pixels 函数,优化与 y 相关的指针计算;
void PicZoom3(const TPicRegion& Dst,const TPicRegion& Src)
{
if((0==Dst.width)||(0==Dst.height)
||(0==Src.width)||(0==Src.height))return;
unsigned long xrIntFloat_16=(Src.width<<16)/Dst.width+1;
unsigned long yrIntFloat_16=(Src.height<<16)/Dst.height+1;
unsigned long dst_width=Dst.width;
TARGB32* pDstLine=Dst.pdata;
unsigned long srcy_16=0;
for (unsigned long y=0;y<Dst.height;++y)
{
TARGB32* pSrcLine=((TARGB32*)
((TUInt8*)Src.pdata+Src.byte_width*(srcy_16>>16)));
unsigned long srcx_16=0;
for (unsigned long x=0;x<dst_width;++x)
{
pDstLine[x]=pSrcLine[srcx_16>>16];
srcx_16+=xrIntFloat_16;
}
srcy_16+=yrIntFloat_16;
((TUInt8*&)pDstLine)+=Dst.byte_width;
}
}
/////////////////////////////////////////////////////////////////////
///////////
//速度测试:
//===================================================================
===========
// PicZoom3414.4 fps
剩余61页未读,继续阅读
资源评论
- baidu_166764072014-07-05还行,可以参考参考
夏虫……
- 粉丝: 34
- 资源: 14
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- unity开发教程.docx
- 代码使用Pygame库实现了一个简单的烟花模拟 核心逻辑包括烟花和粒子类的定义,处理位置、爆炸、尾迹和绘制等操作
- Matlab Simulink 电力电子仿真-Flyback(反激电路)电路分析
- tudou-android-release.apk
- 数据分析教程.docx
- 基于matlab实现用有限元法计算电磁场的Matlab工具 .rar
- 基于matlab实现有限元算法 计算电磁场问题 边界条件包括第一类边界和第二类边界.rar
- 基于matlab实现用于计算不同车重下的电动汽车动力性和经济性.rar
- 基于matlab实现遗传算法求解多车场车辆路径问题 有多组算例可以用.rar
- 浏览器.apk
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功