插值函数代码分析学习,用的CImage类load图像。

// Imagejoint.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Imagejoint.h"
#include "math.h"
#include <afxwin.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include <atlimage.h>//CImage类
#include <locale.h> // The one and only application object CWinApp theApp; using namespace std;
//双三次插值系数
double fs(double w)
{
double a=-0.5;
double fs;
if (abs(w)<=)
fs=(a+)*pow(abs(w),)-(a+)*pow(abs(w),)+;
else if (abs(w)>&&abs(w)<=)
fs=a*pow(abs(w),)-*a*pow(abs(w),)+*a*abs(w)-*a;
else
fs=;
return fs;
} HRESULT Imagejoint(PBYTE pbSrc,int iWidth,int iHeight,double dbRotate,double dbZoom,PBYTE pbTag); int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{ int nRetCode = ;//表示整数类型的函数返回码。n表示整数类型,Ret是Return的缩写,表示返回值,Code表示代码。
setlocale(LC_ALL,"chs");
HMODULE hModule = ::GetModuleHandle(NULL); if (hModule != NULL)
{
// initialize MFC and print and error on failure
CImage cImage;
HRESULT hResult; //初始化一些变量
int iWidth,iHeight,iBytePerPixel,iPitch;
int x,y;
PBYTE pbSrc=NULL,pbTag=NULL;//源图、目标图
PBYTE pbImage=NULL;//load图像后存在这
PDWORD pdwImage=NULL;//用于保存图像
double dbRotate=,dbZoom=; do{
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), ))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = ;
break;
}
// TODO: code your application's behavior here.
if(argc<)
{
_tprintf(_T("使用方法:Imagejoint 源图像文件 旋转角度 缩放倍数 输出文件\n"));
nRetCode= -;
break;
} _stscanf(argv[],_T("%lf"),&dbRotate);
_stscanf(argv[],_T("%lf"),&dbZoom);
if(!((dbRotate>= && dbRotate<) && (dbZoom>=0.25 && dbZoom<=)))
{
_tprintf(_T("“旋转角度” 或 “缩放倍数”参数错误!\n"));
nRetCode= -;
break;
}
//Load 图像到cImage对象中
hResult=cImage.Load(argv[]);
if(hResult!=ERROR_SUCCESS)
{
_tprintf(_T("源图像文件名错误!\n"));
nRetCode= -;
break;
} iWidth=cImage.GetWidth();
iHeight=cImage.GetHeight();
//分配源图内存
pbSrc = (PBYTE)malloc(iWidth*iHeight);
//分配目标图内存
if(dbZoom>) pbTag = (PBYTE)malloc(ceil(iWidth*dbZoom)*ceil(iHeight*dbZoom));
else pbTag = (PBYTE)malloc(iWidth*iHeight);
if(pbSrc==NULL || pbTag==NULL )
{
_tprintf(_T("内存申请错误!\n"));
nRetCode= -;
break;
}
//cImage数据存到pbImage,后再转换为源灰度图pbSrc
iPitch=cImage.GetPitch();
iBytePerPixel=(cImage.GetBPP()+)/;
if(iBytePerPixel==)
{
for(y=;y<iHeight;y++)
{ //load的图像数据放到pbImage
pbImage=(PBYTE)(PBYTE(cImage.GetBits())+iPitch*y);//得到的是图像初始像素地址
for(x=;x<iWidth;x++)
{
//pbImage转换为灰度图pbSrc
pbSrc[y*iWidth+x]=(pbImage[*x]*0.15+pbImage[*x+]*0.55+pbImage[*x+]*0.3);
}
}
}
cImage.Destroy();
//TO DO:执行操作
hResult=Imagejoint(pbSrc,iWidth,iHeight,dbRotate,dbZoom,pbTag);
if(hResult!=ERROR_SUCCESS)
{
_tprintf(_T("图像处理错误!\n"));
nRetCode= -;
break;
} //处理后保存图像
iWidth=ceil(iWidth*dbZoom);
iHeight=ceil(iHeight*dbZoom);
cImage.Create(iWidth,-iHeight,);
iPitch=cImage.GetPitch();
for(y=;y<iHeight;y++)
{
pdwImage=(PDWORD)(PBYTE(cImage.GetBits())+iPitch*y);
for(x=;x<iWidth;x++)
{
pdwImage[x]=pbTag[y*iWidth+x]*0x10101;
}
}
//待保存图像文件名
CString csTagName=argv[];
csTagName.Trim();
csTagName.MakeUpper();
if(csTagName.Right()!=_T(".BMP") ) csTagName.Append(_T(".BMP"));
hResult=cImage.Save(csTagName);
if(hResult!=ERROR_SUCCESS)
{
_tprintf(_T("图像结果保存错误!\n"));
nRetCode= -;
break;
}
_tprintf(_T("图像处理成功!\n"));
nRetCode= ERROR_SUCCESS;
break;
}while();
if(pbSrc) free(pbSrc);
if(pbTag) free(pbTag);
}
else
{
// 可以根据需求更改错误提示
_tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
nRetCode = ;
}
getchar();
return nRetCode;
} HRESULT Imagejoint(PBYTE pbSrc,int iWidth,int iHeight,double dbRotate,double dbZoom,PBYTE pbTag)
{
int size;
if(dbZoom>)
{
size=iWidth*iHeight;
}
else
{
size=ceil(iWidth*dbZoom)*ceil(iHeight*dbZoom);
}
//旋转中心为图像中心
double rx0=iWidth;
double ry0=iHeight;
double srcx,srcy,u,v;
int xOr,yOr;
//int zoom=ceil(dbZoom);
dbRotate=dbRotate*3.1415926/180.0;
for (int y=;y<dbZoom*iHeight;y++)
{
for (int x=;x<dbZoom*iWidth;x++)
{
srcx=(double)((x-rx0)*cos(dbRotate) - (y-ry0)*sin(dbRotate) + rx0) ;
srcy=(double)((x-rx0)*sin(dbRotate) + (y-ry0)*cos(dbRotate) + ry0) ;
srcx=srcx*/dbZoom;
srcy=srcy*/dbZoom;
xOr = floor(srcx);
yOr = floor(srcy);
u=srcx-xOr;
v=srcy-yOr; if( !(srcx>= && srcx<=iWidth && srcy>= && srcy<=iHeight))
{
pbTag[y**iWidth+x]=;//
}
else
{
double middle=
pbSrc[(yOr-)*iWidth+(xOr-)]*fs(+u)*fs(+v)+
pbSrc[(yOr)*iWidth+(xOr-)]*fs(+u)*fs(v)+
pbSrc[(yOr+)*iWidth+(xOr-)]*fs(+u)*fs(-v)+
pbSrc[(yOr+)*iWidth+(xOr-)]*fs(+u)*fs(-v)+ pbSrc[(yOr-)*iWidth+(xOr)]*fs(u)*fs(+v)+
pbSrc[(yOr)*iWidth+(xOr)]*fs(u)*fs(v)+
pbSrc[(yOr+)*iWidth+(xOr)]*fs(u)*fs(-v)+
pbSrc[(yOr+)*iWidth+(xOr)]*fs(u)*fs(-v)+ pbSrc[(yOr-)*iWidth+(xOr+)]*fs(-u)*fs(+v)+
pbSrc[(yOr)*iWidth+(xOr+)]*fs(-u)*fs(v)+
pbSrc[(yOr+)*iWidth+(xOr+)]*fs(-u)*fs(-v)+
pbSrc[(yOr+)*iWidth+(xOr+)]*fs(-u)*fs(-v)+ pbSrc[(yOr-)*iWidth+(xOr+)]*fs(-u)*fs(+v)+
pbSrc[(yOr)*iWidth+(xOr+)]*fs(-u)*fs(v)+
pbSrc[(yOr+)*iWidth+(xOr+)]*fs(-u)*fs(-v)+
pbSrc[(yOr+)*iWidth+(xOr+)]*fs(-u)*fs(-v); if(middle<=&&middle>=)
pbTag[y**iWidth+x]=middle;
else if(middle>)
pbTag[y**iWidth+x]=;
else
pbTag[y**iWidth+x]=;
}
}
}
//memcpy(pbTag,pbSrc,size);
return ERROR_SUCCESS;
}

【C++】插值函数代码分析学习的更多相关文章

  1. 对discuz的代码分析学习(三)mysql驱动

    一. 属性分析         1.tablepre :表名称前缀        2.version : 数据库版本        3.drivertype:驱动类型        4.querynu ...

  2. 对discuz的代码分析学习(二)首页文件

    如果当前地址栏存在查询字符,并且是一个数字,条件成立. 查询字符:www.baidu.com/index.php?aaa=bbb              aaa=bbb就是查询字符如果条件成立,则把 ...

  3. 对discuz的代码分析学习(一)目录结构

    主目录 DISCUZ用的是自己的框架,和其他框架应用一样属于单入口应用.主目录下的.php文件,大部分是应用的入口文件. home.php:家园入口,即论坛中类似博客的那个东西.index.php:首 ...

  4. 对discuz的代码分析学习(四)论坛入口文件

    只是大致分析下执行流程,主要就是取得mod参数的值,根据取值加载控制器,控制器位置在最后一行指定了. 1 )定义应用名称,加载两个必要文件 define('APPTYPEID', 2); define ...

  5. 恶意代码分析学习之dll相关记录

    kernel32.dll 这是一个很常见的DLL,它包含核心系统功能,如访问和操作内存.文件和硬件,Kernel32.dl等等 Advapi32.dll 这个DLL提供了对核心Windows组件的访问 ...

  6. 初次踏上GUI编程之路(有点意思,详细介绍了菜鸟的学习之路)

    初次踏上GUI编程之路 —— 我的Qt学习方法及对Qt认识的不断转变 -> 开始接触GUI与开始接触Qt: 话说,我第一次看见“Qt”这一个名词,好像是在CSDN网站的主页上吧,因为CSDN好像 ...

  7. Java Collections 源码分析

    Java Collections API源码分析 侯捷老师剖析了不少Framework,如MFC,STL等.侯老师有句名言: 源码面前,了无秘密 这句话还在知乎引起广泛讨论. 我对教授程序设计的一点想 ...

  8. Cardinal样条曲线的Javascript实现(代码篇)

    由上一篇文章得到了Cardinal曲线的矩阵表达式,下面就这个矩阵表达式就可以来对曲线进行插值了. 这里选用了JS来实现,完全是因为之前交作业的时候还不知道怎么在Xcode里建完整的C++OpenGL ...

  9. jQuery源码逐行分析学习02(第一部分:jQuery的一些变量和函数)

    第一次尝试使用Office Word,方便程度大大超过网页在线编辑,不过初次使用,一些内容不甚熟悉,望各位大神见谅~ 在上次的文章中,把整个jQuery的结构进行了梳理,得到了整个jQuery的简化结 ...

随机推荐

  1. 1249: 人见人爱A^B

    题目描述 求A^B的最后三位数表示的整数. 说明:A^B的含义是“A的B次方”  输入 输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10000),如果 ...

  2. Flutter——Stack组件(层叠组件)、Align组件、Positioned组件

    Stack 表示堆的意思,我们可以用 Stack 或者 Stack 结合 Align 或者 Stack 结合 Positiond 来实现页面的定位布局. Stack组件 常用于两个子元素. Stack ...

  3. log:日志处理模块

    为了更好的跟踪程序,我们通常都会使用日志,当然在golang中也提供了相应的模块. 基本使用 可以直接通过log来调用格式化输出的方法. package main import "log&q ...

  4. 模块化开发之sea.js

    随着时间的推移,原生js越来越强大,es6中的improt,export已经可以实现模块化开发,但可惜的是现在的浏览器还不支持,需要进行编译,相信在不久的将来,一定会大行其道,今天我们来聊聊模块化开发 ...

  5. 迭代器 Iterator 是什么?(未完成)Iterator 怎么使用?(未完成)有什么特点?(未完成)

    迭代器 Iterator 是什么?(未完成)Iterator 怎么使用?(未完成)有什么特点?(未完成)

  6. TensorFlow utils

    1. def model_stats(): print("============================================================" ...

  7. ubuntu下后台服务的管理

    注册后台服务后都有脚本存在/lib/systemd/system路径下 如mysql为mysql.service 被service管理的进程被杀掉还是会重启的 应使用service XXX stop停 ...

  8. vue param和query两种传参方式

    1.传参方式 query传参方式 this.$router.push({ path: "/home", query: {code:"123"} }) param ...

  9. Selenium(七)多窗口切换、等待方法、alert对话框处理

    一.多窗口切换 1.打开百度首页 2.在百度中搜索博客园 3.从搜索结果中跳转到博客园 4.博客园首页和百度搜索页面切换 handle:句柄 二.等待方法 time.sleep(5) 先导入方法 参数 ...

  10. idea 查看类继承关系的快捷键

    类似eclipse ctrl+t的快捷键,idea中是ctrl+H