fix(StatusImageCrop): fix wrong initial image fit

The initial fit was computed for the square crop-window

updates: 5118
This commit is contained in:
Stefan 2022-05-20 23:05:19 +03:00 committed by Stefan Dunca
parent 07e711e30c
commit ee3effcdd1
2 changed files with 41 additions and 52 deletions

View File

@ -82,12 +82,7 @@ Item {
\qmlproperty rect StatusImageCropPanel::cropRect \qmlproperty rect StatusImageCropPanel::cropRect
\sa StatusImageCrop::cropRect \sa StatusImageCrop::cropRect
*/ */
property alias cropRect: cropEditor.cropRect readonly property alias cropRect: cropEditor.cropRect
/*!
\qmlproperty rect StatusImageCropPanel::cropRect
\sa StatusImageCrop::cropRect
*/
readonly property alias cropWindow: cropEditor.cropWindow
/*! /*!
\qmlproperty real StatusImageCrop::scrollZoomFactor \qmlproperty real StatusImageCrop::scrollZoomFactor
How fast is image scaled (zoomed) when using mouse scroll How fast is image scaled (zoomed) when using mouse scroll
@ -116,16 +111,11 @@ Item {
QtObject { QtObject {
id: d id: d
readonly property int referenceWindowWidth: 1000
function updateAspectRatio(newAR) { function updateAspectRatio(newAR) {
// Keep width and adjust height if(root.sourceSize.width === 0 || root.sourceSize.height === 0)
const eW = cropEditor.cropRect.width return
const w = (eW <= 0) ? cropEditor.sourceSize.width : eW cropEditor.setCropRect(cropEditor.fillContentInWindow(root.sourceSize, Qt.size(referenceWindowWidth, referenceWindowWidth / root.aspectRatio)))
const h = w/newAR
const c = (eW <= 0)
? Qt.point(cropEditor.sourceSize.width/2, cropEditor.sourceSize.height/2)
: Qt.point(cropEditor.cropRect.x + w/2, cropEditor.cropRect.y + cropEditor.cropRect.height/2)
const nR = Qt.rect(c.x - w/2, c.y-h/2, w, h)
cropEditor.setCropRect(nR)
} }
} }

View File

@ -123,12 +123,6 @@ Item {
e.g. to set the crop window to show and match image's AR use Qt.rect(0, 0, sourceSize.width, sourceSize.height) e.g. to set the crop window to show and match image's AR use Qt.rect(0, 0, sourceSize.width, sourceSize.height)
*/ */
readonly property rect cropRect: d.cropRect readonly property rect cropRect: d.cropRect
/*!
\qmlproperty rect StatusImageCrop::cropRect
The position and zis of the crop rectangle in item's space; without extra spacing
*/
readonly property alias cropWindow: d.cropWindow
/*! /*!
\qmlproperty real StatusImageCrop::aspectRatio \qmlproperty real StatusImageCrop::aspectRatio
*/ */
@ -146,7 +140,7 @@ Item {
\sa StatusImageCrop::source \sa StatusImageCrop::source
*/ */
readonly property size sourceSize: mainImage.sourceSize readonly property alias sourceSize: mainImage.sourceSize
/*! /*!
\qmlproperty real StatusImageCrop::scrToImgScale \qmlproperty real StatusImageCrop::scrToImgScale
@ -218,7 +212,7 @@ Item {
function getZoomRect(scale /*real*/) { function getZoomRect(scale /*real*/) {
const oldCenter = root.rectCenter(root.cropRect) const oldCenter = root.rectCenter(root.cropRect)
const inflatedRect = root.inflateRectBy(root.minimumCropRect(), 1/scale) const inflatedRect = root.inflateRectBy(d.minimumCropRect(), 1/scale)
return root.recenterRect(inflatedRect, oldCenter); return root.recenterRect(inflatedRect, oldCenter);
} }
@ -248,6 +242,42 @@ Item {
return Qt.rect(newCenter.x - target.width/2 , newCenter.y - target.height/2, target.width, target.height) return Qt.rect(newCenter.x - target.width/2 , newCenter.y - target.height/2, target.width, target.height)
} }
function fillContentInWindow(contentSize /*size*/, windowSize /*size*/) {
const contentAR = contentSize.width/contentSize.height
const windowAR = windowSize.width/windowSize.height
const heightBound = contentAR > windowAR
if(heightBound) {
const wWidth = contentSize.height * windowAR
const horizontalBorder = (contentSize.width - wWidth)/2
return Qt.rect(horizontalBorder, 0, wWidth, contentSize.height)
}
else {
const wHeight = contentSize.width / windowAR
const verticalBorder = (contentSize.height - wHeight)/2
return Qt.rect(0, verticalBorder, contentSize.width, wHeight)
}
}
QtObject {
id: d
property rect cropRect
onCropRectChanged: windowRect.requestPaint()
readonly property real zoomToFill: {
const rectangle = root.fillContentInWindow(root.sourceSize, d.cropWindowSize)
return d.currentZoom(root.sourceSize, Qt.size(rectangle.width, rectangle.height))
}
property size cropWindowSize: Qt.size(d.cropRect.width, d.cropRect.height)
//> 1.0 is the content represented by w fully inscribed in c
function currentZoom(c /*size*/, w /*size*/) {
const wScale = c.width/w.width
const hScale = c.height/w.height
return Math.max(wScale, hScale)
}
//> cropRect for minimum zoom: 1.0 //> cropRect for minimum zoom: 1.0
function minimumCropRect() { function minimumCropRect() {
const sourceAR = root.sourceSize.width/root.sourceSize.height const sourceAR = root.sourceSize.width/root.sourceSize.height
@ -259,44 +289,14 @@ Item {
minCropSize.width, minCropSize.height) minCropSize.width, minCropSize.height)
return res return res
} }
QtObject {
id: d
property rect cropRect: fillContentInSquaredWindow(root.sourceSize)
onCropRectChanged: windowRect.requestPaint()
readonly property real zoomToFill: {
const rectangle = fillContentInSquaredWindow(root.sourceSize)
return d.currentZoom(root.sourceSize, Qt.size(rectangle.width, rectangle.height))
}
property rect cropWindow
// Probably called from render thread, run async
signal updateCropWindow(rect newRect)
onUpdateCropWindow: cropWindow = newRect
function fillContentInSquaredWindow(c /*size*/) {
if(c.width > c.height) {
const border = (c.width - c.height)/2
return Qt.rect(border, 0, c.height, c.height)
}
else {
const border = (c.height - c.width)/2
return Qt.rect(0, border, c.width, c.width)
}
}
//> 1.0 is the content represented by w fully inscribed in c
function currentZoom(c /*size*/, w /*size*/) {
const wScale = c.width/w.width
const hScale = c.height/w.height
return Math.max(wScale, hScale)
}
} }
onWindowStyleChanged: windowRect.requestPaint() onWindowStyleChanged: windowRect.requestPaint()
onSourceSizeChanged: d.cropRect = d.fillContentInSquaredWindow(sourceSize) onRadiusChanged: windowRect.requestPaint()
onSourceSizeChanged: {
if(d.cropWindowSize.width > 0 && d.cropWindowSize.height > 0)
d.cropRect = root.fillContentInWindow(sourceSize, d.cropWindowSize)
}
Canvas { Canvas {
id: windowRect id: windowRect
@ -330,7 +330,6 @@ Item {
ctx.roundedRect(cW.x, cW.y, cW.width, cW.height, root.radius, root.radius) ctx.roundedRect(cW.x, cW.y, cW.width, cW.height, root.radius, root.radius)
ctx.fill() ctx.fill()
ctx.restore() ctx.restore()
d.updateCropWindow(cW)
} }
} }