快速代码调整DIB图像和保持良好的图像质量
Quick code to resize DIB image and maintain good img quality
有许多算法可以做图像调整- 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);
}
}
上面的代码足够快,但是在缩放图片时质量不太好
因此,可能有人已经有快速和好的c++代码示例缩放dib ?
注意:我之前使用的是StretchDIBits -当需要将10000x10000的图片缩小到100x100的大小时,它是超级慢的,我的代码要快得多,我只是想有更高的质量注:我使用自己的SetPixel/GetPixel函数,直接与数据数组和快速工作,这是不是设备上下文!
为什么要在CPU上做呢?使用GDI,很有可能会有一些硬件加速。使用StretchBlt和SetStretchBltMode
在伪代码: create source dc and destination dc using CreateCompatibleDC
create source and destination bitmaps
SelectObject source bitmap into source DC and dest bitmap into dest DC
SetStretchBltMode
StretchBlt
release DCs
好吧,这就是答案,我必须自己做…对于缩放图片,它工作得非常好(对于缩放我的初始代码也工作得非常好)。希望有人能找到一个好的用途,它的快足够,并产生非常好的图像质量。
for (int y = 0; y < height; y ++)
{
double srcY1Coord = (y * srcHeight) / (double)height;
int srcY1CoordInt = (int)(srcY1Coord);
double srcY2Coord = ((y + 1) * srcHeight) / (double)height - 0.00000000001;
int srcY2CoordInt = min(maxSrcYcoord, (int)(srcY2Coord));
double yMultiplierForFirstCoord = (0.5 * (1 - (srcY1Coord - srcY1CoordInt)));
double yMultiplierForLastCoord = (0.5 * (srcY2Coord - srcY2CoordInt));
for (int x = 0; x < width; x ++)
{
double srcX1Coord = (x * srcWidth) / (double)width;
int srcX1CoordInt = (int)(srcX1Coord);
double srcX2Coord = ((x + 1) * srcWidth) / (double)width - 0.00000000001;
int srcX2CoordInt = min(maxSrcXcoord, (int)(srcX2Coord));
RGB32 color32;
ASSERT(srcX1Coord < srcWidth && srcY1Coord < srcHeight);
double r(0), g(0), b(0), a(0), multiplier(0);
for (int xSrc = srcX1CoordInt; xSrc <= srcX2CoordInt; xSrc ++)
for (int ySrc = srcY1CoordInt; ySrc <= srcY2CoordInt; ySrc ++)
{
RGB32 curSrcColor32 = pSrcDIB->GetDIBPixel(xSrc, ySrc);
double xMultiplier = xSrc < srcX1Coord ? (0.5 * (1 - (srcX1Coord - srcX1CoordInt))) : (xSrc >= srcX2Coord ? (0.5 * (srcX2Coord - srcX2CoordInt)) : 0.5);
double yMultiplier = ySrc < srcY1Coord ? yMultiplierForFirstCoord : (ySrc >= srcY2Coord ? yMultiplierForLastCoord : 0.5);
double curPixelMultiplier = xMultiplier + yMultiplier;
if (curPixelMultiplier > 0)
{
r += (curSrcColor32.r * curPixelMultiplier); g += (curSrcColor32.g * curPixelMultiplier); b += (curSrcColor32.b * curPixelMultiplier); a += (curSrcColor32.alpha * curPixelMultiplier);
multiplier += curPixelMultiplier;
}
}
color32.r = BYTE(r / multiplier); color32.g = BYTE(g / multiplier); color32.b = BYTE(b / multiplier); color32.alpha = BYTE(a / multiplier);
SetDIBPixel(x, y, color32);
}
}
注:请不要问我为什么不使用StretchDIBits -为那些理解系统api并不总是可用或可接受的人留下评论。
还是那句话,为什么要在CPU上做呢?为什么不使用OpenGL/DirectX和片段着色器?在伪代码:
upload source texture (cache it if it's to be reused)
create destination texture
use shader program
render quad
download output texture
,其中shader program
是您正在使用的过滤方法。GPU在处理像素方面比CPU/GetPixel/SetPixel要好得多。
你可能会在网上找到许多不同的过滤方法的片段着色器- GPU Gems是一个很好的开始。
相关文章:
- 将图像魔术转换命令转换为魔术++c++代码
- Visual Studio Community 代码分析的质量与 SAL 注释
- 如何通过用C++编写的代码将位图图像保存在Android设备中
- 如何将 MATLAB 图像处理库内置函数转换为 MATLAB 编码器代码生成不支持的 C++?
- 无法编译此图像旋转代码
- 我相信我为双链接列表编写的代码中的代码质量需要少量提高
- Qt QML:由c++代码提供的具有动态图像数量的UI
- 无法使用cv :: imwrite保存垫子图像在JNI本机代码OPENCV中
- 图像打开时出错(使用打开的 CV C++代码)
- 在C 或MATLAB中用于图像的CRF实现的代码
- 了解图像处理代码
- 现代 c++ 编译器是否自动矢量化代码以进行 24 位图像处理
- C ++或MATLAB代码来计算图像的类似HAAR的特征
- 使用 CMake 将资源(例如着色器代码、图像)嵌入到可执行文件/库中
- OpenCV代码将存储在列表中的描述符与新的图像描述符进行比较
- 包装使用OpenCV进行图像处理的C代码,以便与同样使用OpenCV的Python一起使用
- 未能加载图像错误代码2
- 如何在不损失c ++或opencv图像质量的情况下调整图像大小
- Qt c++ QWebView图像质量
- 快速代码调整DIB图像和保持良好的图像质量