fix: prevent resizing of original file with withoutEnlargement on update (#12291)
This PR updates `generateFileData` to skip applying `resizeOptions` after updating an image if `resizeOptions.withoutEnlargement` is `true` and the original image size is smaller than the dimensions defined in `resizeOptions`. This prevents unintended re-resizing of already resized images when updating or modifying metadata without uploading a new file. This change ensures that: - Resizing is skipped if withoutEnlargement: true - Resizing still occurs if withoutEnlargement: false or unset This resolves an issue where images were being resized again unnecessarily when updating an upload. Fixes #12280
This commit is contained in:
@@ -43,6 +43,33 @@ export async function cropImage({
|
||||
sharpOptions.animated = true
|
||||
}
|
||||
|
||||
const { height: originalHeight, width: originalWidth } = dimensions
|
||||
const newWidth = Number(widthInPixels)
|
||||
const newHeight = Number(heightInPixels)
|
||||
|
||||
const dimensionsChanged = originalWidth !== newWidth || originalHeight !== newHeight
|
||||
|
||||
if (!dimensionsChanged) {
|
||||
let adjustedHeight = originalHeight
|
||||
|
||||
if (fileIsAnimatedType) {
|
||||
const animatedMetadata = await sharp(
|
||||
file.tempFilePath || file.data,
|
||||
sharpOptions,
|
||||
).metadata()
|
||||
adjustedHeight = animatedMetadata.pages ? animatedMetadata.height : originalHeight
|
||||
}
|
||||
|
||||
return {
|
||||
data: file.data,
|
||||
info: {
|
||||
height: adjustedHeight,
|
||||
size: file.size,
|
||||
width: originalWidth,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const formattedCropData = {
|
||||
height: Number(heightInPixels),
|
||||
left: percentToPixel(x, dimensions.width),
|
||||
|
||||
@@ -241,7 +241,7 @@ export const generateFileData = async <T>({
|
||||
})
|
||||
|
||||
// Apply resize after cropping to ensure it conforms to resizeOptions
|
||||
if (resizeOptions) {
|
||||
if (resizeOptions && !resizeOptions.withoutEnlargement) {
|
||||
const resizedAfterCrop = await sharp(croppedImage)
|
||||
.resize({
|
||||
fit: resizeOptions?.fit || 'cover',
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
relationSlug,
|
||||
unstoredMediaSlug,
|
||||
versionSlug,
|
||||
withoutEnlargeSlug,
|
||||
} from './shared.js'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
@@ -490,6 +491,19 @@ export default buildConfigWithDefaults({
|
||||
staticDir: path.resolve(dirname, './media/enlarge'),
|
||||
},
|
||||
},
|
||||
{
|
||||
slug: withoutEnlargeSlug,
|
||||
fields: [],
|
||||
upload: {
|
||||
resizeOptions: {
|
||||
width: 1000,
|
||||
height: undefined,
|
||||
fit: 'inside',
|
||||
withoutEnlargement: true,
|
||||
},
|
||||
staticDir: path.resolve(dirname, './media/without-enlarge'),
|
||||
},
|
||||
},
|
||||
{
|
||||
slug: reduceSlug,
|
||||
fields: [],
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
relationSlug,
|
||||
withMetadataSlug,
|
||||
withOnlyJPEGMetadataSlug,
|
||||
withoutEnlargeSlug,
|
||||
withoutMetadataSlug,
|
||||
} from './shared.js'
|
||||
import { startMockCorsServer } from './startMockCorsServer.js'
|
||||
@@ -69,6 +70,7 @@ let uploadsTwo: AdminUrlUtil
|
||||
let customUploadFieldURL: AdminUrlUtil
|
||||
let hideFileInputOnCreateURL: AdminUrlUtil
|
||||
let bestFitURL: AdminUrlUtil
|
||||
let withoutEnlargementResizeOptionsURL: AdminUrlUtil
|
||||
let consoleErrorsFromPage: string[] = []
|
||||
let collectErrorsFromPage: () => boolean
|
||||
let stopCollectingErrorsFromPage: () => boolean
|
||||
@@ -104,6 +106,7 @@ describe('Uploads', () => {
|
||||
customUploadFieldURL = new AdminUrlUtil(serverURL, customUploadFieldSlug)
|
||||
hideFileInputOnCreateURL = new AdminUrlUtil(serverURL, hideFileInputOnCreateSlug)
|
||||
bestFitURL = new AdminUrlUtil(serverURL, 'best-fit')
|
||||
withoutEnlargementResizeOptionsURL = new AdminUrlUtil(serverURL, withoutEnlargeSlug)
|
||||
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
@@ -1257,7 +1260,7 @@ describe('Uploads', () => {
|
||||
})
|
||||
|
||||
// without focal point update this generated size was equal to 1736
|
||||
expect(redDoc.sizes.focalTest.filesize).toEqual(1598)
|
||||
expect(redDoc.sizes.focalTest.filesize).toEqual(1586)
|
||||
})
|
||||
|
||||
test('should resize image after crop if resizeOptions defined', async () => {
|
||||
@@ -1355,6 +1358,35 @@ describe('Uploads', () => {
|
||||
await expect(page.locator('.file-field .file-details__remove')).toBeHidden()
|
||||
})
|
||||
|
||||
test('should skip applying resizeOptions after updating an image if resizeOptions.withoutEnlargement is true and the original image size is smaller than the dimensions defined in resizeOptions', async () => {
|
||||
await page.goto(withoutEnlargementResizeOptionsURL.create)
|
||||
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await page.getByText('Select a file').click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await wait(1000)
|
||||
await fileChooser.setFiles(path.join(dirname, 'test-image.jpg'))
|
||||
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000)
|
||||
|
||||
await page.locator('.file-field__edit').click()
|
||||
|
||||
// no need to make any changes to the image if resizeOptions.withoutEnlargement is actually being respected now
|
||||
await page.locator('button:has-text("Apply Changes")').click()
|
||||
await page.waitForSelector('button#action-save')
|
||||
await page.locator('button#action-save').click()
|
||||
await expect(page.locator('.payload-toast-container')).toContainText('successfully')
|
||||
await wait(1000)
|
||||
|
||||
const resizeOptionMedia = page.locator('.file-meta .file-meta__size-type')
|
||||
|
||||
// expect the image to be the original size since the original image is smaller than the dimensions defined in resizeOptions
|
||||
await expect(resizeOptionMedia).toContainText('800x800')
|
||||
})
|
||||
|
||||
describe('imageSizes best fit', () => {
|
||||
test('should select adminThumbnail if one exists', async () => {
|
||||
await page.goto(bestFitURL.create)
|
||||
|
||||
@@ -3,6 +3,7 @@ export const mediaSlug = 'media'
|
||||
export const relationSlug = 'relation'
|
||||
export const audioSlug = 'audio'
|
||||
export const enlargeSlug = 'enlarge'
|
||||
export const withoutEnlargeSlug = 'without-enlarge'
|
||||
export const focalNoSizesSlug = 'focal-no-sizes'
|
||||
export const focalOnlySlug = 'focal-only'
|
||||
export const reduceSlug = 'reduce'
|
||||
|
||||
Reference in New Issue
Block a user