用于调整 DIB 图像大小并保持良好图像质量的快速代码
有很多算法可以调整图像大小 - lancorz、双三次、双线性等,但大多数算法都非常复杂,因此消耗太多的 CPU。
我需要的是快速相对简单的C++代码来以可接受的质量调整图像大小。
这是我当前正在做的一个示例:
for (int y = 0; y < height; y ++)
{
int srcY1Coord = int((double)(y * srcHeight) / height);
int srcY2Coord = min(srcHeight - 1, max(srcY1Coord, int((double)((y + 1) * srcHeight) / height) - 1));
for (int x = 0; x < width; x ++)
{
int srcX1Coord = int((double)(x * srcWidth) / width);
int srcX2Coord = min(srcWidth - 1, max(srcX1Coord, int((double)((x + 1) * srcWidth) / width) - 1));
int srcPixelsCount = (srcX2Coord - srcX1Coord + 1) * (srcY2Coord - srcY1Coord + 1);
RGB32 color32;
UINT32 r(0), g(0), b(0), a(0);
for (int xSrc = srcX1Coord; xSrc <= srcX2Coord; xSrc ++)
for (int ySrc = srcY1Coord; ySrc <= srcY2Coord; ySrc ++)
{
RGB32 curSrcColor32 = pSrcDIB->GetDIBPixel(xSrc, ySrc);
r += curSrcColor32.r; g += curSrcColor32.g; b += curSrcColor32.b; a += curSrcColor32.alpha;
}
color32.r = BYTE(r / srcPixelsCount); color32.g = BYTE(g / srcPixelsCount); color32.b = BYTE(b / srcPixelsCount); color32.alpha = BYTE(a / srcPixelsCount);
SetDIBPixel(x, y, color32);
}
}
上面的代码足够快,但是在放大图片时质量不佳。
因此,可能有人已经拥有用于扩展 DIB 的快速且良好的 C++ 代码示例?
注意:我之前使用过 StretchDIBits - 当需要将 10000x10000 图片缩小到 100x100 大小时,速度非常慢,我的代码要快得多,我只是想要更高的
质量我正在使用自己的 SetPixel/GetPixel 函数,直接快速地处理数据数组,这不是设备上下文!
There is many algorithms to do image resizing - lancorz, bicubic, bilinear, e.g. But most of them are pretty complex and therefore consume too much CPU.
What I need is fast relatively simple C++ code to resize images with acceptable quality.
Here is an example of what I'm currently doing:
for (int y = 0; y < height; y ++)
{
int srcY1Coord = int((double)(y * srcHeight) / height);
int srcY2Coord = min(srcHeight - 1, max(srcY1Coord, int((double)((y + 1) * srcHeight) / height) - 1));
for (int x = 0; x < width; x ++)
{
int srcX1Coord = int((double)(x * srcWidth) / width);
int srcX2Coord = min(srcWidth - 1, max(srcX1Coord, int((double)((x + 1) * srcWidth) / width) - 1));
int srcPixelsCount = (srcX2Coord - srcX1Coord + 1) * (srcY2Coord - srcY1Coord + 1);
RGB32 color32;
UINT32 r(0), g(0), b(0), a(0);
for (int xSrc = srcX1Coord; xSrc <= srcX2Coord; xSrc ++)
for (int ySrc = srcY1Coord; ySrc <= srcY2Coord; ySrc ++)
{
RGB32 curSrcColor32 = pSrcDIB->GetDIBPixel(xSrc, ySrc);
r += curSrcColor32.r; g += curSrcColor32.g; b += curSrcColor32.b; a += curSrcColor32.alpha;
}
color32.r = BYTE(r / srcPixelsCount); color32.g = BYTE(g / srcPixelsCount); color32.b = BYTE(b / srcPixelsCount); color32.alpha = BYTE(a / srcPixelsCount);
SetDIBPixel(x, y, color32);
}
}
The code above is fast enough, but the quality is not ok on scaling pictures up.
Therefore, possibly someone already has fast and good C++ code sample for scaling DIBs?
Note: I was using StretchDIBits before - it was super-slow when was needed to downsize 10000x10000 picture down to 100x100 size, my code is much, much faster, I just want to have a bit higher quality
P.S. I'm using my own SetPixel/GetPixel functions, to work directly with data array and fast, that's not device context!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为什么要在CPU上做呢?使用 GDI,很有可能实现一些硬件加速。使用 StretchBlt 和 SetStretchBltMode。
在伪代码中:
Why are you doing it on the CPU? Using GDI, there's a good chance of some hardware acceleration. Use StretchBlt and SetStretchBltMode.
In pseudocode:
好吧,这就是答案,必须自己做...它对于放大图片非常有效(对于缩小我的初始代码也非常有效)。希望有人能找到它的好用处,它足够快并且产生非常良好的图像质量。
PS 请不要问我为什么不使用 StretchDIBits - 为那些了解系统 api 并不总是可用或可接受的人留下评论。
Allright, here is the answer, had to do it myself... It works perfectly well for scaling pictures up (for scaling down my initial code works perfectly well too). Hope someone will find a good use for it, it's fast enough and produced very good picture quality.
P.S. Please don't ask why I’m not using StretchDIBits - leave comments for these who understand that not always system api is available or acceptable.
再说一遍,为什么要在CPU上进行呢?为什么不使用 OpenGL / DirectX 和片段着色器?在伪代码中:
其中
着色器程序
是您正在使用的过滤方法。 GPU 在处理像素方面比 CPU/GetPixel/SetPixel 好得多。您可能可以在网络上找到许多不同过滤方法的片段着色器 - GPU Gems 是一个很好的起点。
Again, why do it on the CPU? Why not use OpenGL / DirectX and fragment shaders? In pseudocode:
where
shader program
is the filtering method you're using. The GPU is much better at processing pixels than CPU/GetPixel/SetPixel.You could probably find fragment shaders for lots of different filtering methods on the web - GPU Gems is a good place to start.