Files
hfut-bishe/client/core/image/ImageDecodeConfig.h
T
2026-05-14 13:30:06 +08:00

61 lines
2.3 KiB
C++

#pragma once
#include <QtGlobal>
#include <QImageReader>
#include <QRect>
#include <QSize>
#include <algorithm>
#include <cmath>
namespace core {
namespace image_decode {
/// 提高 Qt6 解码像素上限,避免大图被 reader 直接拒绝(单位 MB)
inline void prepareLargeImageReader() {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QImageReader::setAllocationLimit(4096);
#endif
}
/// 裁剪对话框等「仅预览」场景:像素上限(libvips 缩略与 Qt 回退共用)
[[maybe_unused]] constexpr qint64 kPreviewMaxPixels = 16LL * 1000 * 1000;
/// 编辑器 / 帧图替换:缩略像素上限(libvips 与 Qt 回退共用)
[[maybe_unused]] constexpr qint64 kWorkspaceMaxPixels = 48LL * 1000 * 1000;
/// 在 read() 前调用:若像素数超过 maxPixels,则 setScaledSize 按比例缩小(不解码全图)
inline void downscaleReaderIfExceeds(QImageReader& reader, qint64 maxPixels) {
const QSize sz = reader.size();
if (!sz.isValid() || sz.width() <= 0 || sz.height() <= 0) {
return;
}
const qint64 pixels = qint64(sz.width()) * qint64(sz.height());
if (pixels <= maxPixels) {
return;
}
const double s = std::sqrt(double(maxPixels) / double(pixels));
const int nw = std::max(1, int(std::lround(sz.width() * s)));
const int nh = std::max(1, int(std::lround(sz.height() * s)));
reader.setScaledSize(QSize(nw, nh));
}
/// 将 rect 从 fromSize 坐标系线性映射到 toSize(例如预览图上的选区 → 原图逻辑像素)
inline QRect mapRectBetweenSizes(const QRect& rect, const QSize& fromSize, const QSize& toSize) {
if (!rect.isValid() || fromSize.width() <= 0 || fromSize.height() <= 0 || toSize.width() <= 0 ||
toSize.height() <= 0) {
return {};
}
const qreal sx = qreal(toSize.width()) / qreal(fromSize.width());
const qreal sy = qreal(toSize.height()) / qreal(fromSize.height());
const int x0 = int(std::floor(qreal(rect.left()) * sx));
const int y0 = int(std::floor(qreal(rect.top()) * sy));
const int x1 = int(std::ceil(qreal(rect.right() + 1) * sx));
const int y1 = int(std::ceil(qreal(rect.bottom() + 1) * sy));
QRect out(x0, y0, x1 - x0, y1 - y0);
return out.normalized().intersected(QRect(0, 0, toSize.width(), toSize.height()));
}
} // namespace image_decode
} // namespace core