As fotos das câmeras digitais geralmente são salvas como JPEG com uma etiqueta de "orientação" EXIF. Para exibir corretamente, as imagens precisam ser giradas / espelhadas, dependendo da orientação definida, mas os navegadores ignoram essas informações que renderizam a imagem. Mesmo em grandes aplicativos comerciais da Web, o suporte à orientação EXIF pode ser irregular 1 . A mesma fonte também fornece um bom resumo das 8 orientações diferentes que um JPEG pode ter:
Imagens de amostra estão disponíveis em 4 .
A questão é como girar / espelhar a imagem no lado do cliente, para que ela seja exibida corretamente e possa ser processada posteriormente, se necessário?
Existem bibliotecas JS disponíveis para analisar dados EXIF, incluindo o atributo de orientação 2 . O Flickr observou um possível problema de desempenho ao analisar imagens grandes, exigindo o uso de webworkers 3 .
As ferramentas do console podem reorientar corretamente as imagens 5 . Um script PHP para resolver o problema está disponível em 6
fonte
canvas.toDataURL()
e decodificar e salvá-lo no servidor.<img>
tag comum ?A transformação de contexto de Mederr funciona perfeitamente. Se você precisar extrair a orientação, use apenas esta função - não precisa de nenhuma biblioteca de leitura EXIF. Abaixo está uma função para redefinir a orientação na imagem base64. Aqui está um violino para isso . Também preparei um violino com demonstração de extração de orientação .
fonte
switch
não é necessário, pois essa transformação não faz nada. Além disso, considere usar emsrcOrientation > 4 && srcOrientation < 9
vez de[5,6,7,8].indexOf(srcOrientation) > -1
, porque é mais rápido e consome menos recursos (RAM e CPU). Não há necessidade de ter uma matriz lá. Isso é importante ao agrupar muitas imagens, onde cada bit conta. Caso contrário, resposta muito boa. Voto a favor!indexOf
ser comparado ao que você propôs. Eu executei um loop simples com 10M de iterações e foi 1400% mais rápido. Nice: D Muito obrigado!getOrientation
, estou curioso para saber se isso é eficiente em termos de desempenho.getOrientation
chamafileReader.readAsArrayBuffer
e, em seguida, chamamosURL.createObjectURL
e passamos o resultado pararesetOrientation
, que carrega esse URL como uma imagem. Isso significa que o arquivo de imagem será "carregado" / lido pelo navegador não uma vez, mas duas vezes, ou entendo errado?image-orientation: from-image
quando usados.E se
Então você pode usar essas transformações para transformar a imagem em orientação 1
Da orientação:
ctx.transform(1, 0, 0, 1, 0, 0);
ctx.transform(-1, 0, 0, 1, width, 0);
ctx.transform(-1, 0, 0, -1, width, height);
ctx.transform(1, 0, 0, -1, 0, height);
ctx.transform(0, 1, 1, 0, 0, 0);
ctx.transform(0, 1, -1, 0, height, 0);
ctx.transform(0, -1, -1, 0, height, width);
ctx.transform(0, -1, 1, 0, 0, width);
Antes de desenhar a imagem em ctx
fonte
ok, além da resposta @ user3096626, acho que será mais útil se alguém forneceu um exemplo de código, o exemplo a seguir mostrará como corrigir a orientação da imagem proveniente do URL (imagens remotas):
Solução 1: usando javascript (recomendado)
como a biblioteca load-image não extrai tags exif apenas de imagens de URL (arquivo / blob), usaremos as bibliotecas javascript exif-js e load-image , portanto, primeiro adicione essas bibliotecas à sua página da seguinte maneira:
Observe que a versão 2.2 do exif-js parece ter problemas, então usamos o 2.1
então basicamente o que faremos é
a - carregue a imagem usando
window.loadImage()
b - leia tags exif usando
window.EXIF.getData()
c - converta a imagem em tela e corrija a orientação da imagem usando
window.loadImage.scale()
d - coloque a tela no documento
aqui está :)
é claro que você também pode obter a imagem como base64 a partir do objeto canvas e colocá-la no atributo img src; portanto, usando o jQuery, você pode fazer;)
aqui está o código completo em: github: https://github.com/digital-flowers/loadimage-exif-example
Solução 2: usando html (hack do navegador)
existe um hack muito rápido e fácil, a maioria dos navegadores exibe a imagem na orientação correta se a imagem for aberta dentro de uma nova guia diretamente sem nenhum html (LOL, não sei por quê), então basicamente você pode exibir sua imagem usando iframe colocando o atributo iframe src como o URL da imagem diretamente:
Solução 3: usando css (apenas firefox e safari no ios)
existe um atributo css3 para corrigir a orientação da imagem, mas o problema está funcionando apenas no firefox e no safari / ios, ainda vale a pena mencionar, pois em breve estará disponível para todos os navegadores (informações de suporte do navegador do caniuse )
fonte
Para quem tem um arquivo de um controle de entrada, não sabe qual é a orientação, é um pouco preguiçoso e não deseja incluir uma grande biblioteca abaixo, é o código fornecido pelo @WunderBart combinado com a resposta à qual ele vincula ( https://stackoverflow.com/a/32490603 ) que localiza a orientação.
que pode ser facilmente chamado como tal
fonte
image/jpeg
vez do padrãoimage/png
e redimensionar a imagem de saída para uma largura máxima (400px no meu caso) fez uma enorme diferença. (isso funciona bem para as miniaturas, mas se você tem que mostrar a imagem completa, eu sugiro evitando base64 e simplesmente injetar o elemento canvas diretamente na página ...)A resposta do WunderBart foi a melhor para mim. Observe que você pode acelerá-lo muito se suas imagens geralmente são o caminho certo, simplesmente testando primeiro a orientação e ignorando o restante do código, se nenhuma rotação for necessária.
Reunindo todas as informações do wunderbart, algo assim;
fonte
-2
e-1
retornar degetOrientation
para não tentar girar imagens que não sejam jpg ou sem dados de rotação.file.slice()
otimização também, mas o verdadeiro impulso vem do uso de imagens eimage/jpeg
formato de saída menores para criar URLs de dados menores. (não há atraso perceptível mesmo para imagens de 10 megapixels).file.slice()
, pois você impedirá o suporte a fontes de imagem base64.Um forro alguém?
Eu não vi ninguém mencionar a
browser-image-compression
biblioteca . Tem uma função auxiliar perfeita para isso.Uso:
const orientation = await imageCompression.getExifOrientation(file)
Uma ferramenta tão útil de muitas outras maneiras também.
fonte
File
objetos, tanto quanto eu sei. A melhor coisa a seguir seria enviar a imagem e a orientação até o servidor e fazer a manipulação de arquivos lá. Ou você pode gerar uma string base64 usandocanvas
e otoDataURL
métodoEu criei uma classe envolvida em um módulo ES6 que resolve exatamente isso.
São 103 linhas, sem dependências e bastante bem estruturadas e documentadas, destinadas a serem fáceis de modificar / reutilizar.
Lida com todas as 8 orientações possíveis e é baseado em promessas.
Aqui está, espero que isso ainda ajude alguém: https://gist.github.com/vdavid/3f9b66b60f52204317a4cc0e77097913
fonte
Eu estou usando solução mista (php + css).
Os contêineres são necessários para:
div.imgCont2
recipiente necessário para girar;div.imgCont1
contêiner necessário para diminuir o zoom -width:150%
;div.imgCont
contêiner necessário para barras de rolagem, quando a imagem é zoomOut..
fonte
Além da resposta de @fareed namrouti,
Isso deve ser usado se a imagem precisar ser pesquisada a partir de um elemento de entrada de arquivo
fonte
Eu escrevi um pequeno script php que gira a imagem. Certifique-se de armazenar a imagem em favor de apenas recalcular cada solicitação.
Felicidades
fonte