Fix computation errors in framing tool
* Compute image aspect ratio if required instead of leaving at 0 * Fix divide by zero error in computing framed size * Compute resize scale based on original crop * Reword "Current" aspect ratio to "As Image"
This commit is contained in:
parent
55480f40ea
commit
4358c2d7a6
@ -277,6 +277,10 @@ Dimensions upscaleToBBox(const Dimensions& img, const Dimensions& bbox) {
|
|||||||
double orientAspectRatio(const FramingParams& framing, const Dimensions& imgSize)
|
double orientAspectRatio(const FramingParams& framing, const Dimensions& imgSize)
|
||||||
{
|
{
|
||||||
double aspectRatio = framing.aspectRatio;
|
double aspectRatio = framing.aspectRatio;
|
||||||
|
if (aspectRatio == FramingParams::AS_IMAGE_ASPECT_RATIO) {
|
||||||
|
aspectRatio = imgSize.aspectRatio();
|
||||||
|
}
|
||||||
|
|
||||||
Orientation borderOrient = orient(framing, imgSize);
|
Orientation borderOrient = orient(framing, imgSize);
|
||||||
if ((borderOrient == Orientation::PORTRAIT && aspectRatio > 1.0) ||
|
if ((borderOrient == Orientation::PORTRAIT && aspectRatio > 1.0) ||
|
||||||
(borderOrient == Orientation::LANDSCAPE && aspectRatio < 1.0)) {
|
(borderOrient == Orientation::LANDSCAPE && aspectRatio < 1.0)) {
|
||||||
@ -407,12 +411,13 @@ Dimensions Framing::computeRelativeImageBBoxInFrame(const Dimensions& imgSize,
|
|||||||
// = frame_len * scale / (1 + 2 * scale)
|
// = frame_len * scale / (1 + 2 * scale)
|
||||||
double borderBasis = frameBasis * scale / imgFrameScale;
|
double borderBasis = frameBasis * scale / imgFrameScale;
|
||||||
|
|
||||||
// Compute image and border lengths for the non-basis side.
|
// Compute image and border lengths for the non-basis side
|
||||||
double imgBasisToOther = side == Side::WIDTH ? 1.0 / imgAspectRatio : imgAspectRatio;
|
double imgBasisToOther = side == Side::WIDTH ? 1.0 / imgAspectRatio : imgAspectRatio;
|
||||||
double borderBasisToOther = side == Side::WIDTH ? 1.0 / borderAspectRatio : borderAspectRatio;
|
double borderBasisToOther = side == Side::WIDTH ? 1.0 / borderAspectRatio : borderAspectRatio;
|
||||||
double imgOther = imgBasis * imgBasisToOther;
|
double imgOther = imgBasis * imgBasisToOther;
|
||||||
double borderOther = borderBasis * borderBasisToOther;
|
double borderOther = borderBasis * borderBasisToOther;
|
||||||
|
|
||||||
|
// Find the maximum allowed image size considering min size limits
|
||||||
double maxImageBasis = frameBasis;
|
double maxImageBasis = frameBasis;
|
||||||
double maxImageOther = frameOther;
|
double maxImageOther = frameOther;
|
||||||
if (framing.minSizeEnabled) {
|
if (framing.minSizeEnabled) {
|
||||||
@ -429,6 +434,12 @@ Dimensions Framing::computeRelativeImageBBoxInFrame(const Dimensions& imgSize,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Image is too large to satisfy requirements:
|
||||||
|
// a. Min border size limit not satisfied
|
||||||
|
// b. Basis size is too small for the requested aspect ratio
|
||||||
|
// (i.e. original image clipped)
|
||||||
|
//
|
||||||
|
// Resize the image so that it fits in bounds
|
||||||
if (imgOther > maxImageOther) {
|
if (imgOther > maxImageOther) {
|
||||||
imgOther = maxImageOther;
|
imgOther = maxImageOther;
|
||||||
imgBasis = imgOther / imgBasisToOther;
|
imgBasis = imgOther / imgBasisToOther;
|
||||||
@ -550,46 +561,24 @@ Dimensions Framing::computeFramedSize(const Dimensions& imgSize) const
|
|||||||
|
|
||||||
Dimensions Framing::computeSizeWithBorders(const Dimensions& imgSize) const
|
Dimensions Framing::computeSizeWithBorders(const Dimensions& imgSize) const
|
||||||
{
|
{
|
||||||
auto length = [](double img, double border) {
|
|
||||||
return img + 2.0 * border;
|
|
||||||
};
|
|
||||||
auto evalBorder = [](double side, double scale, double img) {
|
|
||||||
double otherSide = side * scale;
|
|
||||||
double totalBorder = otherSide - img;
|
|
||||||
return std::max(totalBorder, 0.0) * 0.5;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (framing.borderSizingMethod == BorderSizing::FIXED_SIZE) {
|
if (framing.borderSizingMethod == BorderSizing::FIXED_SIZE) {
|
||||||
return Dimensions(length(imgSize.width, framing.absWidth),
|
return Dimensions(imgSize.width + 2.0 * framing.absWidth,
|
||||||
length(imgSize.height, framing.absHeight));
|
imgSize.height + 2.0 * framing.absHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
Side side = pickReferenceSide(framing, imgSize);
|
Side side = pickReferenceSide(framing, imgSize);
|
||||||
double aspectRatio = orientAspectRatio(framing, imgSize);
|
double aspectRatio = orientAspectRatio(framing, imgSize);
|
||||||
|
|
||||||
// Compute the size with borders given the requested reference side length
|
|
||||||
// and aspect ratio
|
|
||||||
Dimensions borderSize;
|
|
||||||
double scale = framing.relativeBorderSize;
|
double scale = framing.relativeBorderSize;
|
||||||
|
|
||||||
|
Dimensions framedSize;
|
||||||
if (side == Side::WIDTH) {
|
if (side == Side::WIDTH) {
|
||||||
borderSize.width = imgSize.width * scale;
|
framedSize.width = (1.0 + 2.0 * scale) * imgSize.width;
|
||||||
double totalWidth = length(imgSize.width, borderSize.width);
|
framedSize.height = framedSize.width / aspectRatio;
|
||||||
borderSize.height = evalBorder(totalWidth, 1.0 / aspectRatio, imgSize.height);
|
|
||||||
} else {
|
} else {
|
||||||
borderSize.height = imgSize.height * scale;
|
framedSize.height = (1.0 + 2.0 * scale) * imgSize.height;
|
||||||
double totalHeight = length(imgSize.height, borderSize.height);
|
framedSize.width = framedSize.height * aspectRatio;
|
||||||
borderSize.width = evalBorder(totalHeight, aspectRatio, imgSize.width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (framing.minSizeEnabled) {
|
|
||||||
Dimensions minSize(static_cast<double>(framing.minWidth),
|
|
||||||
static_cast<double>(framing.minHeight));
|
|
||||||
borderSize = clampToBBox(borderSize, minSize, OUTSIDE_BBOX);
|
|
||||||
}
|
|
||||||
|
|
||||||
Dimensions framedSize(length(imgSize.width, borderSize.width),
|
|
||||||
length(imgSize.height, borderSize.height));
|
|
||||||
|
|
||||||
// Check if the computed frame size satsifies the requested aspect ratio
|
// Check if the computed frame size satsifies the requested aspect ratio
|
||||||
// without cutting off the original image. If the image is cut off, use
|
// without cutting off the original image. If the image is cut off, use
|
||||||
// the smallest frame that preserves the original image and still
|
// the smallest frame that preserves the original image and still
|
||||||
@ -1059,7 +1048,7 @@ ImProcFunctions::FramingData ImProcFunctions::framing(const FramingArgs& args) c
|
|||||||
result.enabled = true;
|
result.enabled = true;
|
||||||
result.imgWidth = std::round(adjusted.size.width);
|
result.imgWidth = std::round(adjusted.size.width);
|
||||||
result.imgHeight = std::round(adjusted.size.height);
|
result.imgHeight = std::round(adjusted.size.height);
|
||||||
result.scale = adjusted.scale;
|
result.scale = result.scale * adjusted.scale;
|
||||||
result.framedWidth = std::round(framedSize.width);
|
result.framedWidth = std::round(framedSize.width);
|
||||||
result.framedHeight = std::round(framedSize.height);
|
result.framedHeight = std::round(framedSize.height);
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ public:
|
|||||||
static constexpr int INDEX_CURRENT = 0;
|
static constexpr int INDEX_CURRENT = 0;
|
||||||
|
|
||||||
AspectRatios() :
|
AspectRatios() :
|
||||||
ratios{{M("GENERAL_CURRENT")}}
|
ratios{{M("GENERAL_ASIMAGE")}}
|
||||||
{
|
{
|
||||||
fillAspectRatios(ratios);
|
fillAspectRatios(ratios);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user