#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <windows.h>
#include <FreeImage.h>
#include <cuda_runtime.h>
#include <npp.h> #pragma comment(lib, "FreeImage.lib")
#pragma comment(lib, "cudart.lib")
#pragma comment(lib, "nppi.lib") FIBITMAP* LoadImg( const char* szFile )
{
FREE_IMAGE_FORMAT nFif; if ( szFile == NULL || *szFile == )
{
return NULL;
} if ( ( nFif = FreeImage_GetFileType( szFile, ) ) == FIF_UNKNOWN )
{
if ( ( nFif = FreeImage_GetFIFFromFilename( szFile ) ) == FIF_UNKNOWN )
{
return NULL;
}
} if ( !FreeImage_FIFSupportsReading( nFif ) )
{
return NULL;
} return FreeImage_Load( nFif, szFile );
} int main( int argc, char* argv[] )
{
cudaError_t cuRet;
NppStatus nppRet;
BOOL fiRet;
FIBITMAP* pSrcBmp;
FIBITMAP* pDstBmp;
unsigned char* pSrcData;
unsigned char* pDstData;
Npp8u* pSrcDataCUDA;
Npp8u* pDstDataCUDA;
NppiSize oSrcSize;
NppiSize oDstSize;
NppiRect oSrcROI;
NppiRect oDstROI;
int nImgBpp;
int nSrcPitch;
int nDstPitch;
int nSrcPitchCUDA;
int nDstPitchCUDA;
double aBoundingBox[][];
double nAngle; if ( argc < )
{
return -;
} /* 载入文件 */
pSrcBmp = LoadImg( argv[] );
assert( pSrcBmp != NULL ); nImgBpp = ( FreeImage_GetBPP( pSrcBmp ) >> );
pSrcData = FreeImage_GetBits( pSrcBmp ); oSrcSize.width = ( int )FreeImage_GetWidth( pSrcBmp );
oSrcSize.height = ( int )FreeImage_GetHeight( pSrcBmp );
nSrcPitch = ( int )FreeImage_GetPitch( pSrcBmp ); oSrcROI.x = oSrcROI.y = ;
oSrcROI.width = oSrcSize.width;
oSrcROI.height = oSrcSize.height; nAngle = atof( argv[] ); /* 设置显卡,构建上下文 */
cuRet = cudaSetDevice( );
assert( cuRet == cudaSuccess ); /* 分配显存 */
switch ( nImgBpp )
{
case :
pSrcDataCUDA = nppiMalloc_8u_C1( oSrcSize.width, oSrcSize.height, &nSrcPitchCUDA );
break;
case :
pSrcDataCUDA = nppiMalloc_8u_C3( oSrcSize.width, oSrcSize.height, &nSrcPitchCUDA );
break;
case :
pSrcDataCUDA = nppiMalloc_8u_C4( oSrcSize.width, oSrcSize.height, &nSrcPitchCUDA );
break;
default:
assert( );
break;
}
assert( pSrcDataCUDA != NULL ); /* 将原图传入显存 */
cudaMemcpy2D( pSrcDataCUDA, nSrcPitchCUDA, pSrcData, nSrcPitch, oSrcSize.width * nImgBpp, oSrcSize.height, cudaMemcpyHostToDevice ); /* 计算旋转后长宽 */
nppiGetRotateBound( oSrcROI, aBoundingBox, nAngle, , );
oDstSize.width = ( int )ceil( fabs( aBoundingBox[][] - aBoundingBox[][] ) );
oDstSize.height = ( int )ceil( fabs( aBoundingBox[][] - aBoundingBox[][] ) ); /* 建目标图 */
pDstBmp = FreeImage_Allocate( oDstSize.width, oDstSize.height, nImgBpp << );
assert( pDstBmp != NULL ); pDstData = FreeImage_GetBits( pDstBmp ); nDstPitch = ( int )FreeImage_GetPitch( pDstBmp );
oDstROI.x = oDstROI.y = ;
oDstROI.width = oDstSize.width;
oDstROI.height = oDstSize.height; /* 分配显存 */
switch ( nImgBpp )
{
case :
pDstDataCUDA = nppiMalloc_8u_C1( oDstSize.width, oDstSize.height, &nDstPitchCUDA );
break;
case :
pDstDataCUDA = nppiMalloc_8u_C3( oDstSize.width, oDstSize.height, &nDstPitchCUDA );
break;
case :
pDstDataCUDA = nppiMalloc_8u_C4( oDstSize.width, oDstSize.height, &nDstPitchCUDA );
break;
}
assert( pDstDataCUDA != NULL );
cudaMemset2D( pDstDataCUDA, nDstPitchCUDA, , oDstSize.width * nImgBpp, oDstSize.height ); /* 处理 */
switch ( nImgBpp )
{
case :
nppRet = nppiRotate_8u_C1R( pSrcDataCUDA, oSrcSize, nSrcPitchCUDA, oSrcROI,
pDstDataCUDA, nDstPitchCUDA, oDstROI,
nAngle, - aBoundingBox[][], - aBoundingBox[][], NPPI_INTER_CUBIC );
break;
case :
nppRet = nppiRotate_8u_C3R( pSrcDataCUDA, oSrcSize, nSrcPitchCUDA, oSrcROI,
pDstDataCUDA, nDstPitchCUDA, oDstROI,
nAngle, - aBoundingBox[][], - aBoundingBox[][], NPPI_INTER_CUBIC );
break;
case :
nppRet = nppiRotate_8u_C4R( pSrcDataCUDA, oSrcSize, nSrcPitchCUDA, oSrcROI,
pDstDataCUDA, nDstPitchCUDA, oDstROI,
nAngle, - aBoundingBox[][], - aBoundingBox[][], NPPI_INTER_CUBIC );
break;
}
assert( nppRet == NPP_NO_ERROR ); cudaMemcpy2D( pDstData, nDstPitch, pDstDataCUDA, nDstPitchCUDA, oDstSize.width * nImgBpp, oDstSize.height, cudaMemcpyDeviceToHost ); fiRet = FreeImage_Save( FIF_BMP, pDstBmp, "ret.bmp" );
assert( fiRet ); nppiFree( pSrcDataCUDA );
nppiFree( pDstDataCUDA ); cudaDeviceReset(); FreeImage_Unload( pSrcBmp );
FreeImage_Unload( pDstBmp ); return ;
}

下面是所有通道的,扩展了一点。以后自己用

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <windows.h> #include <FreeImage.h> #include <cuda_runtime.h>
#include <npp.h> int main( int argc, char* argv[] )
{
cudaError_t cuRet;
NppStatus nppRet;
BOOL fiRet;
FIBITMAP* pSrcBmp;
FIBITMAP* pDstBmp;
unsigned char* pSrcData;
unsigned char* pDstData;
Npp8u* pSrcDataCUDA;
Npp8u* pDstDataCUDA;
NppiSize oSrcSize;
NppiSize oDstSize;
NppiRect oSrcROI;
NppiRect oDstROI;
int nSrcPitch;
int nDstPitch;
int nSrcPitchCUDA;
int nDstPitchCUDA;
double aBoundingBox[][];
double nAngle; /* 设置显卡,构建上下文 */
cuRet = cudaSetDevice( );
assert( cuRet == cudaSuccess ); /* 打开文件 */
pSrcBmp = FreeImage_Load( FIF_BMP, "1.bmp" );
assert( pSrcBmp != NULL ); pSrcData = FreeImage_GetBits( pSrcBmp );
assert( pSrcData != NULL ); oSrcSize.width = ( int )FreeImage_GetWidth( pSrcBmp );
oSrcSize.height = ( int )FreeImage_GetHeight( pSrcBmp );
nSrcPitch = ( int )FreeImage_GetPitch( pSrcBmp ); oSrcROI.x = oSrcROI.y = ;
oSrcROI.width = oSrcSize.width;
oSrcROI.height = oSrcSize.height; nAngle = ; /* 分配显存 */
pSrcDataCUDA = nppiMalloc_8u_C1( oSrcSize.width, oSrcSize.height, &nSrcPitchCUDA );
assert( pSrcDataCUDA != NULL ); /* 计算旋转后长宽 */
nppiGetRotateBound( oSrcROI, aBoundingBox, nAngle, , );
oDstSize.width = ( int )ceil( fabs( aBoundingBox[][] - aBoundingBox[][] ) );
oDstSize.height = ( int )ceil( fabs( aBoundingBox[][] - aBoundingBox[][] ) ); /* 建目标图 */
pDstBmp = FreeImage_Allocate( oDstSize.width, oDstSize.height, );
assert( pDstBmp != NULL ); pDstData = FreeImage_GetBits( pDstBmp ); nDstPitch = ( int )FreeImage_GetPitch( pDstBmp );
oDstROI.x = oDstROI.y = ;
oDstROI.width = oDstSize.width;
oDstROI.height = oDstSize.height; /* 分配显存 */
pDstDataCUDA = nppiMalloc_8u_C1( oDstSize.width, oDstSize.height, &nDstPitchCUDA );
assert( pDstDataCUDA != NULL ); cudaMemcpy2D( pSrcDataCUDA, nSrcPitchCUDA, pSrcData, nSrcPitch, oSrcSize.width, oSrcSize.height, cudaMemcpyHostToDevice );
cudaMemset2D( pDstDataCUDA, nDstPitchCUDA, , oDstSize.width, oDstSize.height ); /* 处理 */
nppRet = nppiRotate_8u_C1R( pSrcDataCUDA, oSrcSize, nSrcPitchCUDA, oSrcROI,
pDstDataCUDA, nDstPitchCUDA, oDstROI,
nAngle, - aBoundingBox[][], - aBoundingBox[][], NPPI_INTER_CUBIC );
assert( nppRet == NPP_NO_ERROR ); cudaMemcpy2D( pDstData, nDstPitch, pDstDataCUDA, nDstPitchCUDA, oDstSize.width, oDstSize.height, cudaMemcpyDeviceToHost ); fiRet = FreeImage_Save( FIF_BMP, pDstBmp, "2.bmp" );
assert( fiRet ); nppiFree( pSrcDataCUDA );
nppiFree( pDstDataCUDA ); cudaDeviceReset(); FreeImage_Unload( pSrcBmp );
FreeImage_Unload( pDstBmp ); return ;
}

cuda npp库旋转图片的更多相关文章

  1. python中用Pillow库进行图片处理

    一.Python中 PIL 图像处理库简介 PIL可以做很多和图像处理相关的事情: 图像归档(Image Archives).PIL非常适合于图像归档以及图像的批处理任务.你可以使用PIL创建缩略图, ...

  2. 【Thumbnailator】java 使用Thumbnailator实现等比例缩放图片,旋转图片等【转载】

    Thumbnailator概述:     Thumbnailator是与Java界面流畅的缩略图生成库.它简化了通过提供一个API允许精细的缩略图生成调整生产从现有的图像文件的缩略图和图像对象的过程, ...

  3. ios新手开发——toast提示和旋转图片加载框

    不知不觉自学ios已经四个月了,从OC语法到app开发,过程虽然枯燥无味,但是结果还是挺有成就感的,在此分享我的ios开发之路中的小小心得~废话不多说,先上我们今天要实现的效果图: 有过一点做APP经 ...

  4. Android开源库--PhotoView图片查看

    如果说我比别人看得更远些,那是因为我站在了巨人的肩上. github地址:https://github.com/chrisbanes/PhotoView 介绍 在一般的应用中,总会遇到查看图片的功能, ...

  5. Camera图片特效处理综述(Bitmap的Pixels处理、Canvas/paint的drawBitmap处理、旋转图片、裁截图片、播放幻灯片浏览图片<线程固定时间显示一张>)

    一种是直接对Bitmap的像素进行操作,如:叠加.边框.怀旧.(高斯)模糊.锐化(拉普拉斯变换). Bitmap.getPixels(srcPixels, 0, width, 0, 0, width, ...

  6. exif.js 旋转图片

    还是那个问题:网上的大胸弟们BB一大堆,没几个给的代码能用的,话不多说,直接上demo: 链接:https://pan.baidu.com/s/1jJ6vnt8 密码:swwm 不要忽视demo中的s ...

  7. vue 添加旋转图片 修改css transform 值

    //点击放大图片并旋转图片 conponents组建 <template>    <!-- 过渡动画 -->    <transition name="fade ...

  8. JQ 实现轮播图(3D旋转图片轮播效果)

    轮播图效果如下: 代码: <!DOCTYPE html> <html xmlns="/www.w3.org/1999/xhtml"> <head> ...

  9. php 简单的学习GD库绘制图片并传回给前端实现方式

    1.基本的GD库绘制图片汇总 2.后台实现小案例 <?php // $img = imagecreatetruecolor(200,40); // var_dump($img); // 利用GD ...

随机推荐

  1. javascript 和 CoffeeScript 里的类

    javascript不是面向对象的语言,它用函数来模拟类和继承. javascript里,提供一个类并不难: var Person,l4, z3; Person = function(name) { ...

  2. Codeforces 920F. SUM and REPLACE / bzoj 3211 花神游历各国

    题目大意: 一个数列 支持两种操作 1 把区间内的数变成他们自己的约数个数 2 求区间和 思路: 可以想到每个数最终都会变成2或1 然后我们可以线段树 修改的时候记录一下每段有没有全被修改成1或2 是 ...

  3. [Django基础] gunicorn启动django时静态文件的加载

    目前在用nginx+gunicorn对django进行部署 当我用gunicorn -w 4 -b 127.0.0.1:8080 myproject.wsig:application启动django时 ...

  4. thinkphp结合云之讯做短信验证码

    thinkphp结合云之讯做短信验证码先去云之讯注册账号 网址http://www.ucpaas.com/ 注册云之讯平台账号,即可免费获得10元测试费用测试够用啦 解压附件到 ThinkPHP\Li ...

  5. Django day30 自定义配置settings文件,分页器,版本控制

    一:自定义配置settings文件 1.有两套配置文件,默认配置,用户的配置 2.如果某个字段,用户配置了,就用用户的,如果没配置,就用默认的 二:分页器 1.三种分页: # 普通分页 from re ...

  6. Java 集合 ArrayList 需要知道的几个问题

    问:Arraylist 的动态扩容机制是如何自动增加的?简单说说你理解的流程? 答:当在 ArrayList 中增加一个对象时 Java 会去检查 Arraylist 以确保已存在的数组中有足够的容量 ...

  7. zb的生日-------搜索 和 动态规划

    简单的贪心算法 : http://love-oriented.com/pack/P01.html  说实话 我是喜欢 动态规划的.......但是省赛迫在眉睫 , 只好先 学 搜索了  ,  赶紧   ...

  8. python 画图

    1.根据实际图形,用符号画出原来图形 from PIL import Image import argparse #命令行输入参数处理 parser = argparse.ArgumentParser ...

  9. C# 文件操作【转】

    本文也收集了目前最为常用的C#经典操作文件的方法,具体内容如下:C#追加.拷贝.删除.移动文件.创建目录.递归删除文件夹及文件.指定文件夹下面的所有内容copy到目标文件夹下面.指定文件夹下面的所有内 ...

  10. WPF PasswordBox MVVM 实现

    由于PasswordBox.Password属性非依赖属性,所以不能作为绑定的目标,以下是本人的MVVM实现方法. PasswordBox.Password与TextBox.Text同步,TextBo ...