gpt4 book ai didi

c++ - 更快的位图重新缩放

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:22:13 25 4
gpt4 key购买 nike

我写了一个小函数来将图像重新缩放到特定大小而不裁剪它(通过添加黑色边框以适应它)并且它有效,但它在高分辨率下特别慢。请看一下并告诉我如何提高函数的效率。或者,如果有更好的代码,我可以使用它来获得相同的结果。

static int ReScale(char* srcBuffer, int srcLen, int srcStart, int srcStride, int srcHeight, VideoInfo::ePixelFormat srcPixelFormat,
char* dstBuffer, int dstLen, int dstStart, int dstStride, int dstHeight, VideoInfo::ePixelFormat dstPixelFormat, bool reverseCopy)
{
int srcPixelDepth = VideoInfo::GetPixelFormatSize(srcPixelFormat);
int srcWidth = static_cast<int>(floor(srcStride / static_cast<float>(srcPixelDepth)));
int dstPixelDepth = VideoInfo::GetPixelFormatSize(dstPixelFormat);
int dstWidth = static_cast<int>(floor(dstStride / static_cast<float>(dstPixelDepth)));

float resizeRatio = min(dstWidth / static_cast<float>(srcWidth), dstHeight / static_cast<float>(srcHeight));
int dstXOffset = static_cast<int>((dstWidth - (resizeRatio * srcWidth)) / 2.f);
int dstYOffset = static_cast<int>((dstHeight - (resizeRatio * srcHeight)) / 2.f);
ZeroMemory(dstBuffer + dstStart, dstLen);

srcBuffer += srcStart;
dstBuffer += dstStart;

dstWidth -= 2 * dstXOffset;
dstHeight -= 2 * dstYOffset;

int dstPixelOffset = 0;
int srcPixelOffset = 0;
for (int y = 0; y < dstHeight; y++)
{
dstPixelOffset = dstXOffset * dstPixelDepth + (y + dstYOffset) * dstStride;
for (int x = 0; x < dstWidth; x++)
{
srcPixelOffset = static_cast<int>(min(y / resizeRatio, srcHeight));
if (reverseCopy)
{
srcPixelOffset = srcHeight - (srcPixelOffset + 1);
}
srcPixelOffset = static_cast<int>(min(x / resizeRatio, srcWidth)) * srcPixelDepth + srcPixelOffset * srcStride;
if (srcPixelOffset + srcPixelDepth < srcLen && dstPixelOffset + dstPixelDepth < dstLen)
{
memcpy(dstBuffer + dstPixelOffset, srcBuffer + srcPixelOffset, srcPixelDepth);
}
dstPixelOffset += dstPixelDepth;
}
}
return 0;
}

编译器选项*:

/GS /analyze- /W3 /Zc:wchar_t /I"C:\Program Files (x86)\Microsoft Visual 
/Studio 12.0\VC\include" /I"C:\Program Files (x86)\Microsoft Visual
/Studio 12.0\VC\PlatformSDK\include" /I"C:\Program Files (x86)\Windows
/Kits\8.1\include" /Zi /Gm- /O2 /Fd"Release\vc120.pdb" /fp:precise /D
/"WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_WINDLL" /D
/"_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gz /Oy-/MD
/Fa"Release\" /EHsc /nologo /Fo"Release\" /Fp"Release\*****.pch"

分析结果 *: Profiling Result

最佳答案

重构函数以应用您的建议并启用 SSE2 和 fp:fast 选项。性能提高了 3 倍:

static int ReScale(char* srcBuffer, int srcLen, int srcStart, int srcStride, int srcHeight, VideoInfo::ePixelFormat srcPixelFormat,
char* dstBuffer, int dstLen, int dstStart, int dstStride, int dstHeight, VideoInfo::ePixelFormat dstPixelFormat, bool reverseCopy)
{
int srcPixelDepth = VideoInfo::GetPixelFormatSize(srcPixelFormat);
int srcWidth = static_cast<int>(floor(srcStride / static_cast<float>(srcPixelDepth)));
int dstPixelDepth = VideoInfo::GetPixelFormatSize(dstPixelFormat);
int dstWidth = static_cast<int>(floor(dstStride / static_cast<float>(dstPixelDepth)));

float resizeRatio = min(dstWidth / static_cast<float>(srcWidth), dstHeight / static_cast<float>(srcHeight));
int dstXOffset = static_cast<int>((dstWidth - (resizeRatio * srcWidth)) / 2.f);
int dstYOffset = static_cast<int>((dstHeight - (resizeRatio * srcHeight)) / 2.f);
ZeroMemory(dstBuffer + dstStart, dstLen);

srcBuffer += srcStart;
dstBuffer += dstStart;

dstWidth -= 2 * dstXOffset;
dstHeight -= 2 * dstYOffset;

int dstPixelOffset = 0;
int srcPixelOffset = 0;
int srcPixelYOffset = 0;
float srcPixelXOffset = 0;
float srcPixelXStride = 1 / resizeRatio;
int pixelDepthSize = min(srcPixelDepth, dstPixelDepth);
for (int y = 0; y < dstHeight; y++)
{
dstPixelOffset = dstXOffset * dstPixelDepth + (y + dstYOffset) * dstStride;
srcPixelYOffset = static_cast<int>(min(y / resizeRatio, srcHeight));
srcPixelYOffset = (reverseCopy ? (srcHeight - (srcPixelYOffset + 1)) : srcPixelYOffset) * srcStride;
srcPixelXOffset = 0;
for (int x = 0; x < dstWidth; x++)
{
srcPixelOffset = srcPixelYOffset + (static_cast<int>(min(srcPixelXOffset, srcWidth)) * srcPixelDepth);
if (srcPixelOffset + pixelDepthSize < srcLen && dstPixelOffset + pixelDepthSize < dstLen)
{
memcpy(dstBuffer + dstPixelOffset, srcBuffer + srcPixelOffset, pixelDepthSize);
}
dstPixelOffset += dstPixelDepth;
srcPixelXOffset += srcPixelXStride;
}
}
return 0;
}

特别感谢@MOehm、@Tafuri 和其他评论者

关于c++ - 更快的位图重新缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28825511/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com