tamaño subir seleccionar redimensionar modificar manipular imagenes imagen editar crear con cambiar antes javascript html5 image canvas html5-canvas

subir - Cambiar el tamaño de la imagen con javascript canvas(sin problemas)



redimensionar imagen javascript (6)

Estoy tratando de cambiar el tamaño de algunas imágenes con lienzo, pero no tengo ni idea de cómo suavizarlas. En photoshop, navegadores, etc., hay algunos algoritmos que utilizan (por ejemplo, bicúbico, bilineal) pero no sé si están integrados en el lienzo o no.

Aquí está mi violín: http://jsfiddle.net/EWupT/

var canvas = document.createElement(''canvas''); var ctx = canvas.getContext(''2d''); canvas.width=300 canvas.height=234 ctx.drawImage(img, 0, 0, 300, 234); document.body.appendChild(canvas);

La primera es una etiqueta de imagen de tamaño normal, y la segunda es lienzo. Observe cómo el lienzo uno no es tan suave. ¿Cómo puedo lograr ''suavidad''?


Basado en la respuesta de K3N, reescribo el código generalmente para cualquiera que quiera

var oc = document.createElement(''canvas''), octx = oc.getContext(''2d''); oc.width = img.width; oc.height = img.height; octx.drawImage(img, 0, 0); while (oc.width * 0.5 > width) { oc.width *= 0.5; oc.height *= 0.5; octx.drawImage(oc, 0, 0, oc.width, oc.height); } oc.width = width; oc.height = oc.width * img.height / img.width; octx.drawImage(img, 0, 0, oc.width, oc.height);

ACTUALIZAR JSFIDDLE DEMO

Aquí está mi DEMO ONLINE


Como el violín de Trung Le Nguyen Nhat no es correcto en absoluto (solo usa la imagen original en el último paso)
Escribí mi propio violín general con la comparación de rendimiento:

FIDDLE

Básicamente es:

img.onload = function() { var canvas = document.createElement(''canvas''), ctx = canvas.getContext("2d"), oc = document.createElement(''canvas''), octx = oc.getContext(''2d''); canvas.width = width; // destination canvas size canvas.height = canvas.width * img.height / img.width; var cur = { width: Math.floor(img.width * 0.5), height: Math.floor(img.height * 0.5) } oc.width = cur.width; oc.height = cur.height; octx.drawImage(img, 0, 0, cur.width, cur.height); while (cur.width * 0.5 > width) { cur = { width: Math.floor(cur.width * 0.5), height: Math.floor(cur.height * 0.5) }; octx.drawImage(oc, 0, 0, cur.width * 2, cur.height * 2, 0, 0, cur.width, cur.height); } ctx.drawImage(oc, 0, 0, cur.width, cur.height, 0, 0, canvas.width, canvas.height); }


Creé un servicio angular reutilizable para manejar el cambio de tamaño de alta calidad de imágenes / lienzos para cualquiera que esté interesado: https://gist.github.com/transitive-bullshit/37bac5e741eaec60e983

El servicio incluye dos soluciones porque ambos tienen sus propios pros / contras. El enfoque de la convolución lanczos es de mayor calidad a costa de ser más lento, mientras que el enfoque de reducción progresiva produce resultados razonablemente antialias y es significativamente más rápido.

Ejemplo de uso:

angular.module(''demo'').controller(''ExampleCtrl'', function (imageService) { // EXAMPLE USAGE // NOTE: it''s bad practice to access the DOM inside a controller, // but this is just to show the example usage. // resize by lanczos-sinc filter imageService.resize($(''#myimg'')[0], 256, 256) .then(function (resizedImage) { // do something with resized image }) // resize by stepping down image size in increments of 2x imageService.resizeStep($(''#myimg'')[0], 256, 256) .then(function (resizedImage) { // do something with resized image }) })


Creé una biblioteca que le permite reducir cualquier porcentaje manteniendo todos los datos de color.

https://github.com/danschumann/limby-resize/blob/master/lib/canvas_resize.js

Ese archivo puede incluir en el navegador. Los resultados se verán como photoshop o magia de imagen, conservando todos los datos de color, promediando píxeles, en lugar de tomar los cercanos y eliminar otros. No usa una fórmula para calcular los promedios, toma el promedio exacto.


Escribí small js-utility para recortar y cambiar el tamaño de la imagen en el front-end. Aquí hay un link en el proyecto GitHub. También puede obtener blob de la imagen final para enviarlo.

import imageSqResizer from ''./image-square-resizer.js'' let resizer = new imageSqResizer( ''image-input'', 300, (dataUrl) => document.getElementById(''image-output'').src = dataUrl; ); //Get blob let formData = new FormData(); formData.append(''files[0]'', resizer.blob); //get dataUrl document.getElementById(''image-output'').src = resizer.dataUrl;


Puede usar la bajada para obtener mejores resultados. La mayoría de los buscadores parecen usar interpolación lineal en lugar de bicúbica al cambiar el tamaño de las imágenes.

( Actualización Se ha agregado una propiedad de calidad a las especificaciones, imageSmoothingQuality , que actualmente solo está disponible en Chrome).

A menos que uno elija no suavizar o el vecino más cercano, el navegador siempre interpolará la imagen después de reducirla como esta función como un filtro de paso bajo para evitar el aliasing.

Bi-linear usa 2x2 pixeles para hacer la interpolación mientras que bi-cubic usa 4x4, así que al hacerlo en pasos puedes acercarte al resultado bicúbico mientras usas la interpolación bi-lineal como se ve en las imágenes resultantes.

var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var img = new Image(); img.onload = function () { // set size proportional to image canvas.height = canvas.width * (img.height / img.width); // step 1 - resize to 50% var oc = document.createElement(''canvas''), octx = oc.getContext(''2d''); oc.width = img.width * 0.5; oc.height = img.height * 0.5; octx.drawImage(img, 0, 0, oc.width, oc.height); // step 2 octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5); // step 3, resize to final size ctx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5, 0, 0, canvas.width, canvas.height); } img.src = "//i.imgur.com/SHo6Fub.jpg";

<img src="//i.imgur.com/SHo6Fub.jpg" width="300" height="234"> <canvas id="canvas" width=300></canvas>

Dependiendo de lo drástico que sea su tamaño, puede omitir el paso 2 si la diferencia es menor.

En la demostración, puede ver que el nuevo resultado ahora es muy similar al elemento de la imagen.