En este artículo te voy a enseñar a rotar una imagen con HTML y JavaScript a través de canvas, de manera que podrás girar una imagen los grados que tú quieras, es decir, rotarla 90, 180, 270 o cualquier cantidad.
Veremos cómo cargar una imagen, pintarla en un canvas, agregarle rotación y después hacer cosas como descargar esa imagen o enviarla al backend que puede ser con Node, C#, PHP, etcétera.
Lo primero que haremos será dibujar nuestra imagen en un elemento canvas
en lugar de usar un elemento img
directamente en el HTML.
Aquí es importante mencionar que debemos cargar la imagen desde el mismo origen donde ejecutamos el script, y si no lo hacemos entonces debemos especificar el crossOrigin
de la imagen en anonymous
y agregar encabezados CORS en el servidor del otro origen.
const imagen = new Image();
imagen.src = "http://localhost/pusheen.png";
imagen.crossOrigin = "anonymous";
imagen.onload = () => {
let medidaMayor = imagen.width;
if (imagen.height > medidaMayor) {
medidaMayor = imagen.height;
}
$canvas.width = medidaMayor;
$canvas.height = medidaMayor;
context.drawImage(imagen, 0, 0);
};
En el ejemplo de arriba estoy cargando una imagen de localhost, y como mi script se carga en ese mismo origen no hay problema.
El tamaño del canvas es definido como un cuadrado en donde cada lado medirá la mayor medida de la imagen. Es decir, si el ancho es mayor que el alto, el canvas medirá ancho*ancho
, y si el alto es mayor entonces el canvas medirá alto*alto
.
Finalmente dibujamos la imagen en el canvas, para ello invocamos a drawImage
.
Hasta este punto tenemos la imagen dibujada en el canvas. Lo que sigue es trasladarnos al centro, rotar el canvas y volver a dibujar la imagen. Veamos la siguiente función:
const dibujarSegunGrados = (grados) => {
context.clearRect(0, 0, $canvas.width, $canvas.height);
context.save();
context.translate($canvas.width / 2, $canvas.height / 2);
context.rotate(grados * Math.PI / 180);
context.drawImage(imagen, -imagen.width / 2, -imagen.width / 2);
context.restore();
};
La función recibe los grados que se debe rotar la imagen con JS. Lo que hace es limpiar el canvas, guardar el contexto, trasladarse al centro, rotar, dibujar la imagen y restaurar el contexto. Ahora solo debemos pasarle la cantidad de grados y listo.
Nota: en este caso context
es el contexto del canvas obtenido con getContext
, y $canvas
es el elemento canvas obtenido con querySelector. Son variables globales que se explican mejor en el código completo.
Ahora solo falta rotar la imagen a la derecha o a la izquierda. Definimos una variable de grados con valor inicial en 0 y la aumentamos o restamos según sea rotada al a izquierda o derecha, luego invocamos a dibujarSegunGrados
:
$btnRotarDerecha.addEventListener("click", () => {
grados += 90;
dibujarSegunGrados(grados);
});
$btnRotarIzquierda.addEventListener("click", () => {
grados -= 90;
dibujarSegunGrados(grados);
});
El código completo con los botones y el canvas queda así:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="rotarDerecha">Derecha</button>
<button id="rotarIzquierda">Izquierda</button>
<button id="enviar">Enviar</button>
<canvas id="canvas"></canvas>
</body>
<script>
const $canvas = document.querySelector("#canvas");
const $btnRotarDerecha = document.querySelector("#rotarDerecha");
const $btnRotarIzquierda = document.querySelector("#rotarIzquierda");
const $btnEnviar = document.querySelector("#enviar");
const context = $canvas.getContext("2d");
const enviar = async () => {
const data = $canvas.toDataURL("image/png");
const fd = new FormData();
fd.append("imagen", data);
const respuestaHttp = await fetch("http://localhost/recibir.php", {
method: "POST",
body: fd,
});
const nombreImagenSubida = await respuestaHttp.json();
console.log({ nombreImagenSubida });
}
// https://parzibyte.me/blog
let grados = 0;
const imagen = new Image();
imagen.src = "./captura_codigo.png";
imagen.crossOrigin = "anonymous";
imagen.onload = () => {
let medidaMayor = imagen.width;
if (imagen.height > medidaMayor) {
medidaMayor = imagen.height;
}
$canvas.width = medidaMayor;
$canvas.height = medidaMayor;
context.drawImage(imagen, 0, 0);
};
$btnRotarDerecha.addEventListener("click", () => {
grados += 90;
dibujarSegunGrados(grados);
});
$btnRotarIzquierda.addEventListener("click", () => {
grados -= 90;
dibujarSegunGrados(grados);
});
$btnEnviar.addEventListener("click", async () => {
await enviar();
});
const dibujarSegunGrados = (grados) => {
context.clearRect(0, 0, $canvas.width, $canvas.height);
context.save();
context.translate($canvas.width / 2, $canvas.height / 2);
context.rotate(grados * Math.PI / 180);
context.drawImage(imagen, -imagen.width / 2, -imagen.width / 2);
context.restore();
};
</script>
</html>
Puedes probarlo en el siguiente enlace: https://parzibyte.github.io/ejemplos-javascript/rotar-imagen/
Si has abierto la demostración de cómo rotar la imagen con JS y HTML te habrás dado cuenta de que hay un botón que sirve para Enviar la imagen a un servidor.
Obviamente no funciona en la demostración porque no hay backend, pero funcionará si descargas y configuras el código. En el ejemplo tenemos el siguiente código que usa fetch para invocar al servidor con PHP y enviar el canvas como lo expliqué en mi post:
Por cierto, también puedes descargar la imagen una vez rotada:
Como sea, el código que envía la imagen al backend es el siguiente. No importa si usas Node, C#, Python… al final la imagen estará codificada en base64 en un valor del formulario con la clave imagen:
const enviar = async () => {
const data = $canvas.toDataURL("image/png");
const fd = new FormData();
fd.append("imagen", data);
const respuestaHttp = await fetch("http://localhost/recibir.php", {
method: "POST",
body: fd,
});
const nombreImagenSubida = await respuestaHttp.json();
console.log({ nombreImagenSubida });
}
(obviamente debes cambiar la ruta del backend de la línea 5)
Si la recibimos con PHP el código puede ser el siguiente:
<?php
$imagenCodificada = $_POST["imagen"];
$imagenCodificadaLimpia = str_replace("data:image/png;base64,", "", $imagenCodificada);
$imagenDecodificada = base64_decode($imagenCodificadaLimpia);
$nombreImagenGuardada = "imagen_" . uniqid() . ".png";
file_put_contents($nombreImagenGuardada, $imagenDecodificada);
echo json_encode($nombreImagenGuardada);
Y así es como podemos rotar la imagen en el cliente para luego almacenarla en el servidor. Hay varias combinaciones que puedes hacer con lo expuesto en este post, lo que resta es implementarlo.
Recuerda que cuando procesamos imágenes (por ejemplo, en este caso rotamos una imagen con HTML y JavaScript) es mejor dejar el trabajo pesado en el cliente, así no saturamos nuestro servidor.
Te dejo con más tutoriales de JavaScript en mi blog.
El día de hoy te mostraré cómo crear un servidor HTTP (servidor web) en Android…
En este post te voy a enseñar a designar una carpeta para imprimir todos los…
En este artículo te voy a enseñar la guía para imprimir en una impresora térmica…
Hoy te voy a mostrar un ejemplo de programación para agregar un módulo de tasa…
Los usuarios del plugin para impresoras térmicas pueden contratar licencias, y en ocasiones me han…
Hoy voy a enseñarte cómo imprimir el € en una impresora térmica. Vamos a ver…
Esta web usa cookies.