Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 25 additions & 13 deletions src/shared/converters/image-converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ const supportedFormats = [
{ value: 'png', mimeType: 'image/png' },
]

// Get the supported format object based on a string input (either MIME type or format value)
const getSupportedFormat = ( formatString = '' ) => {
const requestedFormat = typeof formatString === 'string' ? formatString.trim().toLowerCase() : ''
const normalizedFormat = requestedFormat === 'image/jpg'
? 'image/jpeg'
: requestedFormat === 'jpeg'
? 'jpg'
: requestedFormat
return (
normalizedFormat.startsWith( 'image/' )
? supportedFormats.find( f => f.mimeType === normalizedFormat )
: supportedFormats.find( f => f.value === normalizedFormat )
) || supportedFormats[ 0 ]
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/**
* ImageConverter
* Client-side image converter using Canvas APIs.
Expand Down Expand Up @@ -178,7 +193,7 @@ class ImageConverter extends Converter {
// Draw image with cropping to maintain aspect ratio
ctx.drawImage( img, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, width, height )

const format = supportedFormats.find( f => f.value === outputFormat )
const format = getSupportedFormat( outputFormat )
// Only use quality for lossy formats
// const q = ( outputFormat === 'webp' || outputFormat === 'jpg' ) ? quality : undefined

Expand Down Expand Up @@ -227,10 +242,6 @@ class ImageConverter extends Converter {
isSmartOptimization = this.options?.isSmartOptimization || false,
} = options

let formatTo = options.format || this.options?.format || ''
formatTo = ( formatTo.startsWith( 'image/' ) ? supportedFormats.find( f => f.mimeType === formatTo )?.value : formatTo ) ||
'webp'

// Not an image; return original file unchanged.
if ( ! file.type || ! file.type.startsWith( 'image/' ) ) {
return {
Expand All @@ -240,14 +251,15 @@ class ImageConverter extends Converter {
}
}

const formatInfo = supportedFormats.find( f => f.value === formatTo )
const formatString = options.format || this.options?.format || ''
const format = getSupportedFormat( formatString )

// Check if the browser supports the desired output format
const testCanvas = document.createElement( 'canvas' )
if ( formatInfo && ! testCanvas.toDataURL( formatInfo.mimeType ).startsWith( `data:${ formatInfo.mimeType }` ) ) {
if ( format && ! testCanvas.toDataURL( format.mimeType ).startsWith( `data:${ format.mimeType }` ) ) {
// If not supported, skip conversion and return the original file
// eslint-disable-next-line no-console
console.error( '[Cimo] ' + formatTo + ' is not supported by the browser, please use another modern browser' )
console.error( '[Cimo] ' + format.value + ' is not supported by the browser, please use another modern browser' )
return {
file,
metadata: null,
Expand Down Expand Up @@ -297,7 +309,7 @@ class ImageConverter extends Converter {
const start = performance.now()

let convertedBlob
if ( formatTo === 'png' ) {
if ( format.value === 'png' ) {
const { default: imageCompression } = await import( /* webpackChunkName: "browser-image-compression" */ 'browser-image-compression' )
convertedBlob = await imageCompression( fileItem.file, {
useWebWorker: true,
Expand All @@ -306,7 +318,7 @@ class ImageConverter extends Converter {
// initialQuality: quality, // Use default
} )
} else {
convertedBlob = await this.convertImage( fileItem, formatTo, {
convertedBlob = await this.convertImage( fileItem, format.value, {
quality,
maxDimension: this.options?.maxDimension || 0,
} )
Expand All @@ -324,7 +336,7 @@ class ImageConverter extends Converter {
}

// Get the file extension for the new format
const extension = formatTo === 'jpeg' ? 'jpg' : formatTo
const extension = format.value === 'jpeg' ? 'jpg' : format.value
// Prepend a unique identified to the filename
// const prefix = Math.random().toString( 36 ).substring( 2, 10 )
const newName = file.name.replace( /\.[^/.]+$/, '' ) + '.' + extension
Expand All @@ -333,7 +345,7 @@ class ImageConverter extends Converter {
filename: newName,
originalFormat: file.type,
originalFilesize: file.size,
convertedFormat: formatInfo.mimeType,
convertedFormat: format.mimeType,
convertedFilesize: convertedBlob.size,
conversionTime: end - start,
compressionSavings: file.size > 0 ? convertedBlob.size / file.size : null,
Expand All @@ -343,7 +355,7 @@ class ImageConverter extends Converter {
// This ensures cross-context compatibility (iframe vs main window)
const fileConstructor = file.constructor
const outFile = new fileConstructor( [ convertedBlob ], newName, {
type: formatInfo.mimeType,
type: format.mimeType,
lastModified: Date.now(),
} )

Expand Down
Loading