Estou tentando criar uma imagem em miniatura no lado do cliente usando javascript e um elemento de tela, mas quando diminuo a imagem, ela parece terrível. Parece que foi reduzido no photoshop com a reamostragem definida como 'Vizinho mais próximo' em vez de Bicubic. Eu sei que é possível fazer com que isso pareça certo, porque este site pode fazê-lo bem usando uma tela também. Eu tentei usar o mesmo código que eles fazem, como mostrado no link "[Source]", mas ainda parece terrível. Há algo que estou faltando, alguma configuração que precisa ser definida ou algo assim?
EDITAR:
Estou tentando redimensionar um jpg. Eu tentei redimensionar o mesmo jpg no site vinculado e no photoshop, e parece bom quando reduzido.
Aqui está o código relevante:
reader.onloadend = function(e)
{
var img = new Image();
var ctx = canvas.getContext("2d");
var canvasCopy = document.createElement("canvas");
var copyContext = canvasCopy.getContext("2d");
img.onload = function()
{
var ratio = 1;
if(img.width > maxWidth)
ratio = maxWidth / img.width;
else if(img.height > maxHeight)
ratio = maxHeight / img.height;
canvasCopy.width = img.width;
canvasCopy.height = img.height;
copyContext.drawImage(img, 0, 0);
canvas.width = img.width * ratio;
canvas.height = img.height * ratio;
ctx.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvas.width, canvas.height);
};
img.src = reader.result;
}
EDIT2:
Parece que eu estava enganado, o site vinculado não estava melhorando o trabalho de reduzir o tamanho da imagem. Eu tentei os outros métodos sugeridos e nenhum deles parece melhor. É nisso que os diferentes métodos resultaram:
Photoshop:
Tela de pintura:
Imagem com renderização de imagem: optimizeQuality definido e dimensionado com largura / altura:
Imagem com renderização de imagem: optimizeQuality definido e dimensionado com -moz-transform:
Redimensionamento de tela no pixastic:
Eu acho que isso significa que o Firefox não está usando amostragem bicúbica como deveria. Vou ter que esperar até que eles realmente o adicionem.
EDIT3:
fonte
Respostas:
Então, o que você faz se todos os navegadores (na verdade, o Chrome 5 me deram um bom) não lhe forneceram uma qualidade de reamostragem suficientemente boa? Você os implementa você mesmo então! Ah, vamos lá, estamos entrando na nova era da Web 3.0, navegadores compatíveis com HTML5, compiladores jIT Javascript super otimizados, máquinas com vários núcleos (†), com toneladas de memória, do que você tem medo? Ei, tem a palavra java em javascript, para garantir o desempenho, certo? Eis o código gerador de miniaturas:
... com os quais você pode produzir resultados como estes!
de qualquer maneira, aqui está uma versão 'fixa' do seu exemplo:
Agora é hora de colocar seus melhores navegadores por aí e ver qual deles provavelmente aumentará a pressão sanguínea do seu cliente!
Umm, onde está minha etiqueta de sarcasmo?
(como muitas partes do código são baseadas no Anrieff Gallery Generator, ele também é coberto pela GPL2? Não sei)
† devido à limitação do javascript, o multi-core não é suportado.
fonte
Algoritmo rápido de redimensionamento / nova amostra de imagem usando o filtro Hermite com JavaScript. Suporte transparência, dá boa qualidade. Pré-visualização:
Atualização : versão 2.0 adicionada no GitHub (mais rápido, web workers + objetos transferíveis). Finalmente eu consegui trabalhar!
Git: https://github.com/viliusle/Hermite-resize
Demo: http://viliusle.github.io/miniPaint/
fonte
Experimente pica - é um redimensionador altamente otimizado com algoritmos selecionáveis. Veja a demonstração .
Por exemplo, a imagem original da primeira postagem é redimensionada em 120ms com filtro Lanczos e janela de 3px ou 60ms com filtro de caixa e janela de 0,5px. Para uma enorme imagem de 17mb, o redimensionamento de 5000x3000px leva ~ 1s no computador e 3s no celular.
Todos os princípios de redimensionamento foram descritos muito bem neste tópico, e o pica não adiciona ciência de foguetes. Mas é otimizado muito bem para os JIT-s modernos e está pronto para uso imediato (via npm ou bower). Além disso, ele usa trabalhadores da Web, quando disponíveis, para evitar congelamentos na interface.
Também pretendo adicionar o suporte à máscara de nitidez em breve, porque é muito útil após o downscale.
fonte
Eu sei que esse é um tópico antigo, mas pode ser útil para algumas pessoas, como eu, que meses depois estão atingindo esse problema pela primeira vez.
Aqui está um código que redimensiona a imagem toda vez que você a recarrega. Estou ciente de que isso não é ideal, mas forneço isso como uma prova de conceito.
Além disso, desculpe-me por usar o jQuery para seletores simples, mas me sinto muito à vontade com a sintaxe.
Minha função createImage é chamada uma vez quando o documento é carregado e depois é chamada toda vez que a janela recebe um evento de redimensionamento.
Eu testei no Chrome 6 e Firefox 3.6, ambos no Mac. Essa "técnica" consome o processador como se fosse sorvete no verão, mas funciona.
fonte
Eu coloquei alguns algoritmos para fazer a interpolação de imagens em matrizes de pixels de tela html que podem ser úteis aqui:
https://web.archive.org/web/20170104190425/http://jsperf.com:80/pixel-interpolation/2
Elas podem ser copiadas / coladas e podem ser usadas dentro dos profissionais da Web para redimensionar imagens (ou qualquer outra operação que exija interpolação - estou usando-as para desafiar imagens no momento).
Eu não adicionei o material de lanczos acima, então fique à vontade para adicioná-lo como uma comparação, se desejar.
fonte
Esta é uma função javascript adaptada do código da @ Telanor. Ao passar uma imagem base64 como primeiro argumento para a função, ela retorna a base64 da imagem redimensionada. maxWidth e maxHeight são opcionais.
fonte
Eu sugiro que você verifique este link e verifique se está definido como verdadeiro.
fonte
Se você está simplesmente tentando redimensionar uma imagem, eu recomendo a configuração
width
eheight
a imagem com CSS. Aqui está um exemplo rápido:Observe que o
height
ewidth
também pode ser definido usando JavaScript. Aqui está um exemplo de código rápido:Além disso, para garantir que a imagem redimensionada tenha boa aparência, adicione as seguintes regras de css ao seletor de imagens:
-ms-interpolation-mode: bicubic
: introduzir no IE7image-rendering: optimizeQuality
: introduzido no FireFox 3.6Pelo que sei, todos os navegadores, exceto o IE, usam um algoritmo bicúbico para redimensionar imagens por padrão, para que suas imagens redimensionadas fiquem bem no Firefox e Chrome.
Se definir o css
width
eheight
não funcionar, convém jogar com um csstransform
:-moz-transform: scale(sx[, sy])
-webkit-transform:scale(sx[, sy])
Se, por qualquer motivo, você precisar usar uma tela, observe que há duas maneiras de redimensionar uma imagem: redimensionando a tela com css ou desenhando a imagem em um tamanho menor.
Veja esta pergunta para mais detalhes.
fonte
Para redimensionar a imagem com largura menor que o original, eu uso:
e funciona =).
fonte
Eu obtive essa imagem clicando com o botão direito do mouse no elemento canvas no firefox e salvando como.
de qualquer maneira, aqui está uma versão 'fixa' do seu exemplo:
fonte
O problema com algumas dessas soluções é que elas acessam diretamente os dados de pixel e fazem um loop através deles para realizar a redução de amostragem. Dependendo do tamanho da imagem, isso pode consumir muitos recursos, e seria melhor usar os algoritmos internos do navegador.
A função drawImage () está usando um método de reamostragem de interpolação linear e vizinho mais próximo. Isso funciona bem quando você não está redimensionando mais da metade do tamanho original .
Se você fizer um loop para redimensionar no máximo metade de cada vez, os resultados serão muito bons e muito mais rápidos do que acessar dados de pixel.
Esta função reduz a amostra para metade de cada vez até atingir o tamanho desejado:
Créditos para este post
fonte
Então, algo interessante que encontrei há algum tempo enquanto trabalhava com telas que pode ser útil:
Para redimensionar o controle de tela por si só, você precisa usar os atributos
height=""
ewidth=""
(oucanvas.width
/canvas.height
elementos). Se você usar CSS para redimensionar a tela, ela realmente esticará (ou seja: redimensionará) o conteúdo da tela para caber na tela inteira (em vez de simplesmente aumentar ou diminuir a área da tela).Vale a pena tentar desenhar a imagem em um controle de tela com os atributos de altura e largura definidos para o tamanho da imagem e, em seguida, usar CSS para redimensionar a tela para o tamanho que você está procurando. Talvez isso usasse um algoritmo de redimensionamento diferente.
Também deve ser observado que a tela tem efeitos diferentes em navegadores diferentes (e até versões diferentes de navegadores diferentes). É provável que os algoritmos e as técnicas usadas nos navegadores mudem com o tempo (especialmente com o Firefox 4 e o Chrome 6 sendo lançados tão cedo, o que dará muita ênfase ao desempenho da renderização de telas).
Além disso, você também pode tentar o SVG, pois provavelmente também usa um algoritmo diferente.
Boa sorte!
fonte
Sinto que o módulo que escrevi produzirá resultados semelhantes ao photoshop, pois preserva os dados de cores calculando a média deles, sem aplicar um algoritmo. É meio lento, mas para mim é o melhor, porque preserva todos os dados de cores.
https://github.com/danschumann/limby-resize/blob/master/lib/canvas_resize.js
Ele não pega o vizinho mais próximo e descarta outros pixels, ou experimenta um grupo e mede uma média aleatória. É preciso a proporção exata que cada pixel de origem deve gerar no pixel de destino. A cor média do pixel na fonte será a cor média do pixel no destino, o que essas outras fórmulas, acho que não serão.
um exemplo de como usar está na parte inferior de https://github.com/danschumann/limby-resize
ATUALIZAÇÃO OUT 2018 : Atualmente, meu exemplo é mais acadêmico do que qualquer outra coisa. O Webgl é praticamente 100%, então é melhor redimensioná-lo para produzir resultados semelhantes, mas mais rápido. PICA.js faz isso, acredito. -
fonte
Converti a resposta do @ syockit e a abordagem de redução em um serviço Angular reutilizável para quem estiver interessado: https://gist.github.com/fisch0920/37bac5e741eaec60e983
Incluí as duas soluções porque ambas têm seus próprios prós / contras. A abordagem de convolução de lanczos é de qualidade mais alta, ao custo de ser mais lenta, enquanto a abordagem de downscaling gradual produz resultados razoavelmente antialias e é significativamente mais rápida.
Exemplo de uso:
fonte
Redimensionador de imagem Javascript rápido e simples:
https://github.com/calvintwr/blitz-hermite-resize
História
Isso é realmente depois de muitas rodadas de pesquisa, leitura e tentativa.
O algoritmo de redimensionamento usa o script Hermite do @ ViliusL (o redimensionador Hermite é realmente o mais rápido e produz resultados razoavelmente bons). Ampliado com os recursos que você precisa.
Organiza um trabalhador para redimensionar para que não congele seu navegador ao redimensioná-lo, diferente de todos os outros redimensionadores de JS existentes.
fonte
Obrigado @syockit por uma resposta incrível. no entanto, tive que reformatar um pouco da seguinte maneira para fazê-lo funcionar. Talvez devido a problemas de verificação do DOM:
fonte
Acabei de executar uma página de comparações lado a lado e, a menos que algo tenha mudado recentemente, não havia melhor downsizing (dimensionamento) usando canvas vs. css simples. Eu testei no FF6 Mac OSX 10.7. Ainda um pouco mole vs. o original.
No entanto, deparei-me com algo que fez uma enorme diferença e que estava usando filtros de imagem em navegadores que suportam telas. Você pode realmente manipular imagens da mesma forma que no Photoshop com desfoque, nitidez, saturação, ondulação, escala de cinza, etc.
Eu então encontrei um plug-in jQuery incrível, que facilita muito a aplicação desses filtros: http://codecanyon.net/item/jsmanipulate-jquery-image-manipulation-plugin/428234
Simplesmente aplico o filtro de nitidez logo após redimensionar a imagem, o que deve proporcionar o efeito desejado. Eu nem precisei usar um elemento de tela.
fonte
Procurando outra ótima solução simples?
Esta solução utilizará o algoritmo de redimensionamento do navegador! :)
fonte