fix(rendering): Correct NImageRounded aspect ratio handling

This commit is contained in:
loner
2025-12-03 00:50:20 +08:00
parent 5a2aa8d6f6
commit e7ad7beb04
3 changed files with 16 additions and 51 deletions
+2 -29
View File
@@ -65,12 +65,6 @@ Item {
}
}
Image {
id: sizeHelper
source: imageDataUrl
visible: false
}
Rectangle {
anchors.fill: parent
color: Color.mSurface || "#f5f5f5"
@@ -101,32 +95,11 @@ Item {
}
Item {
id: imageContainer
anchors.fill: parent
anchors.margins: Style.marginS
NImageRounded {
id: imagePreview
anchors.centerIn: parent
readonly property real imageAspect: (sizeHelper.sourceSize.height > 0) ? sizeHelper.sourceSize.width / sizeHelper.sourceSize.height : 1.0
readonly property real containerAspect: (imageContainer.height > 0) ? imageContainer.width / imageContainer.height : 1.0
width: {
if (imageAspect > containerAspect) {
return imageContainer.width;
} else {
return imageContainer.height * imageAspect;
}
}
height: {
if (imageAspect > containerAspect) {
return imageContainer.width / imageAspect;
} else {
return imageContainer.height;
}
}
anchors.fill: parent
imagePath: imageDataUrl
visible: isImageContent && !loadingFullContent && imageDataUrl !== ""
radius: Style.radiusS
@@ -151,4 +124,4 @@ Item {
}
}
}
}
}
+14 -22
View File
@@ -54,41 +54,33 @@ void main() {
// Image.TileHorizontally = 5
// Image.Pad = 6
if (fillMode == 2) { // PreserveAspectCrop
// Calculate aspect ratios
if (fillMode == 1) { // PreserveAspectFit
float itemAspect = itemSize.x / itemSize.y;
float sourceAspect = sourceSize.x / sourceSize.y;
// Calculate the scale needed to cover the item area
vec2 scale;
if (sourceAspect > itemAspect) {
// Image is wider - fit height, crop sides
scale.y = 1.0;
scale.x = sourceAspect / itemAspect;
// Image is wider than item, letterbox top/bottom
imageUV.y = (qt_TexCoord0.y - 0.5) * (sourceAspect / itemAspect) + 0.5;
} else {
// Image is taller - fit width, crop top/bottom
scale.x = 1.0;
scale.y = itemAspect / sourceAspect;
// Image is taller than item, letterbox left/right
imageUV.x = (qt_TexCoord0.x - 0.5) * (itemAspect / sourceAspect) + 0.5;
}
// Apply scale and center
imageUV = (qt_TexCoord0 - 0.5) / scale + 0.5;
} else if (fillMode == 1) { // PreserveAspectFit
// Make letterbox area transparent
if (imageUV.x < 0.0 || imageUV.x > 1.0 || imageUV.y < 0.0 || imageUV.y > 1.0) {
alpha = 0.0;
}
} else if (fillMode == 2) { // PreserveAspectCrop
float itemAspect = itemSize.x / itemSize.y;
float sourceAspect = sourceSize.x / sourceSize.y;
vec2 scale;
if (sourceAspect > itemAspect) {
// Image is wider - fit width, letterbox top/bottom
scale.x = 1.0;
scale.y = itemAspect / sourceAspect;
// Image is wider than item, crop left/right.
imageUV.x = (qt_TexCoord0.x - 0.5) * (itemAspect / sourceAspect) + 0.5;
} else {
// Image is taller - fit height, letterbox sides
scale.y = 1.0;
scale.x = sourceAspect / itemAspect;
// Image is taller than item, crop top/bottom.
imageUV.y = (qt_TexCoord0.y - 0.5) * (sourceAspect / itemAspect) + 0.5;
}
imageUV = (qt_TexCoord0 - 0.5) * scale + 0.5;
}
// For Stretch (0) or other modes, use qt_TexCoord0 as-is
Binary file not shown.