Dimensionar a imagem com a área de desenho javascript (sem problemas)
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);
o primeiro é uma marca de imagem redimensionada normal, e o segundo é tela. Repare como a tela não é tão suave. Como posso alcançar a "suavidade"?
6 answers
Podes usar descer para obter melhores resultados. A maioria dos navegadores parece usar interpolação linear em vez de bi-cúbico ao dimensionar imagens.
(Update foi adicionada uma propriedade de qualidade às especificações, imageSmoothingQuality
que está disponível apenas no Chrome.)
A menos que se opte por não suavizar ou pelo vizinho mais próximo, o navegador irá sempre interpolar a imagem depois de a reduzir como esta função como um filtro de baixa passagem para evitar suavizacao.
O Bi-linear usa 2x2 pixels para fazer a interpolação, enquanto o bi-cúbico usa 4x4 de modo a fazê-lo em etapas, poderá aproximar-se do resultado bi-cúbico ao usar a interpolação bi-linear, como é visto nas imagens 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>
Dependendo de quão drástico é o seu redimensionamento, pode saltar o PASSO 2 se a diferença for menor.
Na demonstração, você pode ver que o novo resultado é agora muito semelhante ao elemento imagem.
Uso de exemplo:
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
})
})
Uma Vez Que Trung Le Nguyen o violino de Nhat não está correcto de todo
(ele apenas usa a imagem original no último passo)
Eu escrevi meu próprio violino geral com comparação de desempenho:
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);
}
Criei uma biblioteca que lhe permite descer qualquer percentagem mantendo todos os dados de cores.
Https://github.com/danschumann/limby-resize/blob/master/lib/canvas_resize.js
O ficheiro que pode incluir no navegador. Os resultados serão parecidos com photoshop ou image magick, preservando todos os dados de cor, média de pixels, em vez de tomar próximo uns e deixar cair outros. Ele não usa uma fórmula para adivinhar as médias, ele leva a média exata.
Baseado na resposta do K3N, eu reescrevo o código geralmente para quem quiser
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 A DEMONSTRAÇÃO DO JSFIDDLE
Aqui está o meu demonstração 'ONLINE'Escrevi uma pequena js-utility para recortar e redimensionar a imagem na frente. Aqui está link no projecto GitHub. Também você pode obter blob da imagem final para enviá-lo.
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;