帮酷LOGO
0 0 评论
文章标签:DLL  plai  重新取样  
Screenshot -

介绍

:i resampling resampling resampling resampling resampling resampling resampling resampling resampling resampling resampling resampling resampling resampling Libor Libor Libor 实际上,我确实需要一个类似于GDI的位图的工具。"

图书馆

Resample.dll 是一个小型动态库,它输出两个重采样函数。 设计的目标是类似 WIN32 GDI API接口和行为。

函数方案很简单: 假设我们有一个 GDI HBITMAP ( 例如通过 LoadImage 从文件加载),称为 hBmp,它的大小是 w x h,我们需要将它调整到 wNew x hNew。 通过以下方式调用库提供的函数 CreateResampledBitmap,我们可以完成上述任务:

hBmpNew = CreateResampledBitmap(hdc, hBmp, wNew, hNew, STOCK_FILTER_LANCZOS8);

注意,当已经获得的句柄不再需要时,必须删除它。 另一个导出函数是 CreateUserFilterResampledBitmap,它允许调用方提供自定义筛选器函数指针。

确认

这篇文章是基于Libor的一个 Libor: 图像大小的大小优于 GDI+。 我只是将 C# 代码移植到纯( 修改算法一点),并将它的打包在一个DLL中。 所有的股票过滤器都是Libor的原始文章所使用的,最终可以作为参考。

背景

要使用代码,需要对 WIN32 GDI API有一般的理解。 需要稍微深入了解GDI位图和C 语言,以便于 hack的库内部化。 要使用自定义筛选器,对回调函数的熟悉可能有助于。

Sample resampling image, CP 图像采样示例。

Sample resampling image, CP 相同的图像 upsampled。

库引用

由于库只包含两个函数,所以我可以在经典的GDI文档风格中提供参考信息。

用股票过滤器进行重采样

CreateResampledBitmap

CreateResampledBitmap 函数创建与与指定设备上下文关联的设备兼容的重新配置位图。 在可用的股票过滤器之间选择重采样过滤器。

HBITMAP CreateResampledBitmap(
 HDC hdc, // handle to DC HBITMAP hBmpSource, // handle to original bitmap DWORD dwWidth, // width of the resampled bitmap, in pixels DWORD dwHeight, // height of the resampled bitmap, in pixels DWORD dwFilter // index of the stock resampling filter used);
参数
hdc
 [in] Handle to a device context
hBmpSource
 [in] Handle to the original bitmap
dwWidth
 [in] Specifies the resampled bitmap width, in pixels
dwHeight
 [in] Specifies the resampled bitmap height, in pixels
dwFilter
 [in] Specifies the index of the stock resampling filter
 Can be one of the following values
 STOCK_FILTER_BELL
 STOCK_FILTER_BOX
 STOCK_FILTER_CATMULLROM
 STOCK_FILTER_COSINE
 STOCK_FILTER_CUBICCONVOLUTION
 STOCK_FILTER_CUBICSPLINE
 STOCK_FILTER_HERMITE
 STOCK_FILTER_LANCZOS3
 STOCK_FILTER_LANCZOS8
 STOCK_FILTER_MITCHELL
 STOCK_FILTER_QUADRATIC
 STOCK_FILTER_QUADRATICBSPLINE
 STOCK_FILTER_TRIANGLE
返回值

函数成功后,返回值就是重采样位图的句柄。 如果函数失败,则返回值为 NULL。 若要获取扩展错误信息,请调用 GetLastError

备注
  • dwWidthdwHeight 裁剪到范围 1-4096
  • dwFilter 被封装在可用的库存过滤器范围( 例如。 dwFilter=STOCK_FILTER_TRIANGLE+1 成为 dwFilter=STOCK_FILTER_BELL )。

使用自定义过滤器进行重采样

CreateUserFilterResampledBitmap

CreateUserFilterResampledBitmap 函数创建与与指定设备上下文关联的设备兼容的重新配置位图。 重采样筛选器由调用方提供。

HBITMAP CreateUserFilterResampledBitmap(
 HDC hdc, // handle to DC HBITMAP hBmpSource, // handle to original bitmap DWORD dwWidth, // width of the resampled bitmap, in pixels DWORD dwHeight, // height of the resampled bitmap, in pixelsdouble (*pCustomFilter)(double), // custom filter function pointerdouble dRadius // custom filter radius);
参数
hdc
 [in] Handle to a device context
hBmpSource
 [in] Handle to the original bitmap
dwWidth
 [in] Specifies the resampled bitmap width, in pixels
dwHeight
 [in] Specifies the resampled bitmap height, in pixels
pCustomFilter
 [in] Specifies the pointer to the custom filter function.
dRadius
 [in] Radius of the custom filter.
返回值

函数成功后,返回值就是重采样位图的句柄。 如果函数失败,则返回值为 NULL。 若要获取扩展错误信息,请调用 GetLastError

备注
  • dwWidthdwHeight 裁剪到范围 1-4096
  • 半径应该是 pCustomFilter 函数的适当过滤器半径
  • Radius的合法范围为 0.0 -16.0.

使用代码

项目设置

要使用 Resample.dll 函数,应用程序必须:

  • 包含 Resample.h 头文件
  • Resample.lib 文件链接

这当然意味着 Visual Studio 环境必须能够找到头文件和库文件路径。

使用库非常简单,以下代码段从 test.bmp 加载位图,并使用 BOX stock过滤器对它进行重新采样:

...// load the original bitmaphBmp = (HBITMAP) LoadImage( hInstance, _T("test.bmp"),
 IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);if (! hBmp ) return FALSE;// create the 1024x768 resampled bitmap with stock filterhBmpResampled = CreateResampledBitmap(hdc, hBmp, 1024, 768, STOCK_FILTER_BOX);
...

下面显示了使用自定义过滤器的情况:

...// user-filter radiusconstdouble dRad = 3.0;
...// user-filter functiondouble myFilter( double x)
{
 if ( x <0.0 ) x = -x;
 if (x <dRad) return (dRad * dRad - 2 * dRad * x + x * x);
 return0.0;
}
...// load the original bitmaphBmp = (HBITMAP) LoadImage( hInstance, _T("test.bmp"),
 IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);if (! hBmp ) return FALSE;// create the 1024x768 resampled bitmap with user filterhBmpResampled = CreateUserFilterResampledBitmap(hdc, hBmp, 1024, 768, myFilter, dRad);
...

在以后的应用程序 WM_PAINT 消息处理程序中,可以将创建的HBITMAP 用于( 作为任何其他有效位图句柄),如下所示:

// WM_PAINT message handler...// hdc is the painting device contextHDC hMemdc = CreateCompatibleDC(hdc);if (hMemDC)
{
 HBITMAP hBmpOld = (HBITMAP) SelectObject(hMemdc, hBmpResampled);
 BitBlt(hdc, 0, 0, 1024, 768, hMemdc, 0, 0, SRCCOPY);
 SelectObject(hMemdc, hBmpOld);
 DeleteDC(hMemDC);
}
...

测试应用程序

我已经包含了一个测试应用程序项目,即 ResampleTestApp。 用户可以加载位图,然后在主窗口中显示加载的图像,而它的重采样的孪生窗口在子窗口内绘制。 用户可以选择重采样位图的筛选类型和缩放( 缩放)。 应用程序( 标准 C++ Windows 应用程序,无 MFC ) 虽然非常基本和粗糙,但允许尝试不同图像上的所有过滤器。 子窗口标题栏显示有关发生重采样的一些信息:

Child window title bar image

即:

  • 所使用过滤器的名称
  • 重采样图像的有效尺寸
  • 重采样有效比例
  • 用时

由于重置位图( 1-4096 )的尺寸范围限制,重采样有效比例可能会显著差异。

如果应用程序本身要比 4096 x/( 画图像的中心是居中和剪裁) 小,它调用重采样功能,即使窗口本身小于x 3072,它也会调用重采样功能,这是非常耗时的任务( 尤其是高质量的过滤器,像 Lanczos )。

Points of Interest

我已经修改了原始的Libor算法,以便:

  • 减少内存分配/取消分配调用( 内存分配在大块中)
  • 避免不必要的内存传送

生成的函数稍微快一点( trade: 代码比原来的。一个( 当然,这里还有 100%个纯非托管代码影响。) 更清晰。"。"。 通过设计,重采样发生在所有 RGBQUAD 组件上。 值得注意的是,重采取中间结果是 unsigned char 而不是 unsigned short (。由伦敦银行使用),这可能会降低质量。

历史记录

  • 19th 2007年12月: 首次发布


文章标签:plai  DLL  重新取样  

Copyright © 2011 HelpLib All rights reserved.    知识分享协议 京ICP备05059198号-3  |  如果智培  |  酷兔英语