No siempre vamos a necesitar adjuntar una imagen en su totalidad, sería deseable facilitar la tarea al usuario antes de que pueda publicarla o subirla a la plataforma. Con algún mágico editor interactivo, capaz de visualizar la previa del recorte. Existen muchos plugins o extensiones que pueden ayudar a salir del paso pero nada a la altura de tu propio código Javascript Vanilla.
A continuación te mostraré como editar una imagen que se termina de adjuntar con el objetivo de transformar el recorte en puro Base64 (representación en texto de un archivo), ideal para guardar o mostrar en cualquier parte de tu HTML.
Demo
–> Pulsa para ver la DEMO interactiva <–
HTML
Dividimos la aplicación en 4 partes: el input donde introduciremos la imagen, la zona donde seleccionaremos el recorte que deseamos, canvas lugar para valorar el recorte y la generación de la imagen en base64.
<!-- Para el editor usaremos croppr.js, importamos sus CDNs -->
<script src="https://cdn.jsdelivr.net/gh/jamesssooi/Croppr.js@2.3.0/dist/croppr.min.js"></script>
<link href="https://cdn.jsdelivr.net/gh/jamesssooi/Croppr.js@2.3.0/dist/croppr.min.css" rel="stylesheet"/>
<h1>1 Introduce tu imagen</h1>
<!-- Input file donde se adjunta la imagen -->
<input type="file" id="image">
<h1>2 Recorta</h1>
<!-- Editor donde se recortará la imagen con la ayuda de croppr.js -->
<div id="editor"></div>
<h1>3 Previsualiza el resultado</h1>
<!-- Previa del recorte -->
<canvas id="preview"></canvas>
<h1>4 Resultado en Base64</h1>
<!-- Muestra de la imagen recortada en Base64 -->
<code id="base64"></code>
Javascript
Ahora vamos al corazón de la aplicación, el Javascript.
// Esperamos a que todo el HTML esté cargado antes de ejecutar Javascrip
document.addEventListener('DOMContentLoaded', () => {
// Input File
const inputImage = document.querySelector('#image');
// Nodo donde estará el editor
const editor = document.querySelector('#editor');
// El canvas donde se mostrará la previa
const miCanvas = document.querySelector('#preview');
// Contexto del canvas
const contexto = miCanvas.getContext('2d');
// Ruta de la imagen seleccionada
let urlImage = undefined;
// Evento disparado cuando se adjunte una imagen
inputImage.addEventListener('change', abrirEditor, false);
/**
* Método que abre el editor con la imagen seleccionada
*/
function abrirEditor(e) {
// Obtiene la imagen
urlImage = URL.createObjectURL(e.target.files[0]);
// Borra editor en caso que existiera una imagen previa
editor.innerHTML = '';
let cropprImg = document.createElement('img');
cropprImg.setAttribute('id', 'croppr');
editor.appendChild(cropprImg);
// Limpia la previa en caso que existiera algún elemento previo
contexto.clearRect(0, 0, miCanvas.width, miCanvas.height);
// Envia la imagen al editor para su recorte
document.querySelector('#croppr').setAttribute('src', urlImage);
// Crea el editor
new Croppr('#croppr', {
aspectRatio: 1,
startSize: [70, 70],
onCropEnd: recortarImagen
})
}
/**
* Método que recorta la imagen con las coordenadas proporcionadas con croppr.js
*/
function recortarImagen(data) {
// Variables
const inicioX = data.x;
const inicioY = data.y;
const nuevoAncho = data.width;
const nuevaAltura = data.height;
const zoom = 1;
let imagenEn64 = '';
// La imprimo
miCanvas.width = nuevoAncho;
miCanvas.height = nuevaAltura;
// La declaro
let miNuevaImagenTemp = new Image();
// Cuando la imagen se carge se procederá al recorte
miNuevaImagenTemp.onload = function() {
// Se recorta
contexto.drawImage(miNuevaImagenTemp, inicioX, inicioY, nuevoAncho * zoom, nuevaAltura * zoom, 0, 0, nuevoAncho, nuevaAltura);
// Se transforma a base64
imagenEn64 = miCanvas.toDataURL("image/jpeg");
// Mostramos el código generado
document.querySelector('#base64').textContent = imagenEn64;
document.querySelector('#base64HTML').textContent = '<img src="' + imagenEn64.slice(0, 40) + '...">';
}
// Proporciona la imagen cruda, sin editarla por ahora
miNuevaImagenTemp.src = urlImage;
}
});
Resultado final
Todo unido y organizado quedaría con la siguiente silueta.
<html>
<head>
<script src="https://cdn.jsdelivr.net/gh/jamesssooi/Croppr.js@2.3.0/dist/croppr.min.js"></script>
<link href="https://cdn.jsdelivr.net/gh/jamesssooi/Croppr.js@2.3.0/dist/croppr.min.css" rel="stylesheet"/>
<title>Recorta tu imagen y transforma a base64</title>
<script>
document.addEventListener('DOMContentLoaded', () => {
// Input File
const inputImage = document.querySelector('#image');
// Nodo donde estará el editor
const editor = document.querySelector('#editor');
// El canvas donde se mostrará la previa
const miCanvas = document.querySelector('#preview');
// Contexto del canvas
const contexto = miCanvas.getContext('2d');
// Ruta de la imagen seleccionada
let urlImage = undefined;
// Evento disparado cuando se adjunte una imagen
inputImage.addEventListener('change', abrirEditor, false);
/**
* Método que abre el editor con la imagen seleccionada
*/
function abrirEditor(e) {
// Obtiene la imagen
urlImage = URL.createObjectURL(e.target.files[0]);
// Borra editor en caso que existiera una imagen previa
editor.innerHTML = '';
let cropprImg = document.createElement('img');
cropprImg.setAttribute('id', 'croppr');
editor.appendChild(cropprImg);
// Limpia la previa en caso que existiera algún elemento previo
contexto.clearRect(0, 0, miCanvas.width, miCanvas.height);
// Envia la imagen al editor para su recorte
document.querySelector('#croppr').setAttribute('src', urlImage);
// Crea el editor
new Croppr('#croppr', {
aspectRatio: 1,
startSize: [70, 70],
onCropEnd: recortarImagen
})
}
/**
* Método que recorta la imagen con las coordenadas proporcionadas con croppr.js
*/
function recortarImagen(data) {
// Variables
const inicioX = data.x;
const inicioY = data.y;
const nuevoAncho = data.width;
const nuevaAltura = data.height;
const zoom = 1;
let imagenEn64 = '';
// La imprimo
miCanvas.width = nuevoAncho;
miCanvas.height = nuevaAltura;
// La declaro
let miNuevaImagenTemp = new Image();
// Cuando la imagen se carge se procederá al recorte
miNuevaImagenTemp.onload = function() {
// Se recorta
contexto.drawImage(miNuevaImagenTemp, inicioX, inicioY, nuevoAncho * zoom, nuevaAltura * zoom, 0, 0, nuevoAncho, nuevaAltura);
// Se transforma a base64
imagenEn64 = miCanvas.toDataURL("image/jpeg");
// Mostramos el código generado
document.querySelector('#base64').textContent = imagenEn64;
}
// Proporciona la imagen cruda, sin editarla por ahora
miNuevaImagenTemp.src = urlImage;
}
});
</script>
</head>
<body>
<h2>1 Introduce tu imagen</h2>
<!-- Input file donde se adjunta la imagen -->
<input type="file" id="image">
<h2>2 Recorta</h2>
<!-- Editor donde se recortará la imagen con la ayuda de croppr.js -->
<div id="editor"></div>
<h2>3 Previsualiza el resultado</h2>
<!-- Previa del recorte -->
<canvas id="preview"></canvas>
<h2>4 Resultado en Base64</h2>
<!-- Muestra de la imagen recortada en Base64 -->
<code id="base64"></code>
</body>
</html>
¿Alguna propuesta de mejora? Deja un comentario.
{{ comments.length }} comentarios