¡Hola! Hoy veremos cómo convertir una imagen de PNG a JPEG directamente en el navegador manteniendo la proporción de aspecto.
Código con comentarios:
// Exporta la función pngToJpeg para acceder desde otros módulos
/**
* @param {String} pngFile - Objeto File, obtenido cuando el usuario selecciona un archivo desde su dispositivo
*/
export function pngToJpeg(pngFile, maxWidth = 1200) {
// Crea una nueva promesa (Promise) para ejecutar operaciones con la imagen de forma asíncrona
return new Promise((resolve, reject) => {
// Crea un nuevo objeto FileReader para leer el contenido del archivo
const reader = new FileReader();
// Establece el manejador de eventos de carga del archivo
reader.onload = () => {
// Crea un nuevo objeto Image para cargar la imagen
const img = new Image();
// Establece el manejador de eventos de carga de la imagen
img.onload = () => {
// Crea un nuevo elemento canvas y obtiene su contexto 2D para dibujar
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
// Calcula la proporción de aspecto de la imagen original
const aspectRatio = img.width / img.height;
// Calcula los nuevos tamaños de la imagen basándose en el ancho máximo y la proporción de aspecto
const newWidth = maxWidth;
const newHeight = newWidth / aspectRatio;
// Establece los nuevos tamaños para el elemento canvas
canvas.width = newWidth;
canvas.height = newHeight;
// Dibuja la imagen en el canvas con los nuevos tamaños
context.drawImage(img, 0, 0, newWidth, newHeight);
// Convierte el contenido del canvas en un objeto Blob con formato JPEG y lo pasa como resultado de la promesa
canvas.toBlob((blob) => {
resolve(blob);
}, 'image/jpeg');
};
// Establece el manejador de eventos de error al cargar la imagen
img.onerror = (error) => {
reject(error);
};
// Establece la fuente de la imagen para el objeto Image (lo que hace que la imagen comience a cargarse)
img.src = reader.result;
};
// Establece el manejador de eventos de error al leer el archivo
reader.onerror = (error) => {
reject(error);
};
// Lee el contenido del archivo en formato Data URL utilizando FileReader
reader.readAsDataURL(pngFile);
});
}
Ejemplo de Uso
Estructura del proyecto:
mi-convertidor-imagen/
├── index.html
└── scripts/
└── imageConverter.js
1. index.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"> <!-- Esta línea agrega la codificación UTF-8 -->
<title>Conversor PNG a JPEG</title>
<script src="scripts/imageConverter.js" type="module"></script>
</head>
<body>
<h1>Convertidor de PNG a JPEG</h1>
<input type="file" id="pngFile">
<button id="convertirBtn">Convertir</button>
</body>
</html>
2. scripts/imageConverter.js
:
// Exporta la función pngToJpeg para acceder desde otros módulos
/**
* @param {String} pngFile - Objeto File, obtenido cuando el usuario selecciona un archivo desde su dispositivo
*/
export function pngToJpeg(pngFile, maxWidth = 1200) {
// Crea una nueva promesa (Promise) para ejecutar operaciones con la imagen de forma asíncrona
return new Promise((resolve, reject) => {
// Crea un nuevo objeto FileReader para leer el contenido del archivo
const reader = new FileReader();
// Establece el manejador de eventos de carga del archivo
reader.onload = () => {
// Crea un nuevo objeto Image para cargar la imagen
const img = new Image();
// Establece el manejador de eventos de carga de la imagen
img.onload = () => {
// Crea un nuevo elemento canvas y obtiene su contexto 2D para dibujar
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
// Calcula la proporción de aspecto de la imagen original
const aspectRatio = img.width / img.height;
// Calcula los nuevos tamaños de la imagen basándose en el ancho máximo y la proporción de aspecto
const newWidth = maxWidth;
const newHeight = newWidth / aspectRatio;
// Establece los nuevos tamaños para el elemento canvas
canvas.width = newWidth;
canvas.height = newHeight;
// Dibuja la imagen en el canvas con los nuevos tamaños
context.drawImage(img, 0, 0, newWidth, newHeight);
// Convierte el contenido del canvas en un objeto Blob con formato JPEG y lo pasa como resultado de la promesa
canvas.toBlob((blob) => {
resolve(blob);
}, 'image/jpeg');
};
// Establece el manejador de eventos de error al cargar la imagen
img.onerror = (error) => {
reject(error);
};
// Establece la fuente de la imagen para el objeto Image (lo que hace que la imagen comience a cargarse)
img.src = reader.result;
};
// Establece el manejador de eventos de error al leer el archivo
reader.onerror = (error) => {
reject(error);
};
// Lee el contenido del archivo en formato Data URL utilizando FileReader
reader.readAsDataURL(pngFile);
});
}
// Conectar la funcionalidad al botón directamente
document.getElementById('convertirBtn').addEventListener('click', async () => {
const pngFile = document.getElementById('pngFile').files[0];
if (!pngFile) {
alert('Por favor selecciona un archivo PNG.');
return;
}
try {
const jpegBlob = await pngToJpeg(pngFile);
const url = URL.createObjectURL(jpegBlob);
const link = document.createElement('a');
link.href = url;
link.download = 'convertido.jpeg';
link.click();
URL.revokeObjectURL(url);
} catch (error) {
console.error('Error al convertir:', error);
alert('Error al convertir la imagen.');
}
});
Este código convierte una imagen de PNG a JPEG manteniendo la proporción de aspecto.