Aguarde...

2 de novembro de 2019

Orientação da imagem na web

Orientação da imagem na web

Atualmente, estou trabalhando em um pequeno projeto paralelo, no qual carrego imagens no meu servidor (usando entrada de arquivo e adicionalmente o destino de compartilhamento na Web) para disponibilizá-las a outras pessoas. Enquanto eu tinha a primeira versão de trabalho pronta rapidamente, havia um problema: ao enviar uma imagem em retrato do meu telefone, a imagem era mostrada com a orientação errada.

Neste artigo, você aprenderá sobre o status atual da orientação de imagem na Web, como corrigir a orientação de imagens usando o Node.js. e como os navegadores lidarão com isso no futuro.

Status atual #

Se você visualizar esta imagem (obtida nos exemplos de orientação exif ), ela pode ser exibida corretamente no modo retrato ou pode ser mostrada incorretamente 90 graus, girada para a esquerda.

Você provavelmente é um navegador no iOS se vir a palavra top na verdade na parte superior e outro navegador se vir a palavra top à esquerda. A razão para isso é que os dados EXIF ​​para esta imagem têm as informações Girar 90 CW para orientação.

Quando você incorpora a imagem usando <img>, ou background-imagea imagem será mostrada incorreta em todos os navegadores, exceto nos navegadores no iOS. No entanto, se você abrir a imagem diretamente, ela será exibida corretamente no Firefox, Chrome e Safari, mas ainda será mostrada incorretamente girada no Edge e no Internet Explorer. Que grande consistência!

A propriedade de orientação da imagem #

Ao procurar maneiras possíveis de corrigir a orientação usando CSS ou JavaScript, descobri a propriedade de orientação da imagem .

No momento, essa propriedade é suportada apenas no Firefox e você pode usá-la desta maneira para que os navegadores respeitem os dados EXIF ​​e corrijam a orientação:

img {    image-orientation: from-image;}

Ao procurar mais informações, também descobri que essa propriedade já está obsoleta, o que foi confuso para mim no início, porque essa propriedade seria uma maneira fácil de corrigir meu problema com a orientação da imagem, se ela fosse suportada por todos os navegadores.

Depois de ler um pouco mais sobre a questão do Github, aprendi que o plano é que todos os navegadores respeitem a orientação EXIF ​​no futuro e, portanto, usem image-orientation: from-imagepor padrão. Ótimo, é isso que eu quero!

Corrigindo a orientação com Node.js #

Aprendemos até agora que há bastante desacordo entre os navegadores sobre como lidar com a orientação EXIF ​​e nenhuma maneira entre navegadores para corrigi-la facilmente no front-end. Resumindo, é uma bagunça e, como não queremos que alguns usuários vejam imagens quebradas , vamos ver como podemos corrigir isso usando o Node.js.

Primeiro, precisamos de um formulário para fazer upload de nossas imagens:

<form class="form" action="./upload" enctype="multipart/form-data" method="POST">    <label for="file">Select image: </label>    <input type="file" required name="file" multiple="" accept="image/*">    <input type="submit" value="Upload your photos"></form>

Depois de selecionar uma imagem e enviar o formulário, uma solicitação POST será feita para / upload, então vamos ver a rota de upload a seguir:

app.post('/upload', upload.array('file'), async(req, res, next) => {    const images = req.files;    for (image of images) {        await correctOrientation(image);    }    res.redirect('./show');});

Estamos usando a multer como um middleware aqui para processar as imagens e para cada imagem que chamamos correctOrientationpara corrigir a orientação.

Antes de analisarmos correctOrientation, aqui está a configuração de multer que estamos usando para salvar imagens em nossa pasta / uploads.

var storage = multer.diskStorage({    destination: function(req, file, cb) {        cb(null, path.join(__dirname, "uploads"));    },    filename: function(req, file, cb) {        cb(null, Date.now() + '__' + file.originalname);    }})const upload = multer({ storage: storage });

Então, vamos ver a parte interessante – a correção da orientação da imagem:

const readFileAsync = async(file) => {    return await new Promise((resolve, reject) => {        fs.readFile(file, async(err, data) => {            err ? reject(err) : resolve(data);        });    });};const correctOrientation = async(image) => {    let imageOrientation = false;    let rotateDeg = 0;    const buffer = modifyExif(await readFileAsync(path.join(__dirname, "uploads") + '/' + image.filename), data => {        imageOrientation = data && data["0th"] && data["0th"]["274"] ? data["0th"]["274"] : false;        if (imageOrientation) {            if (imageOrientation === 1) {                imageOrientation = false;            } else {                data["0th"]["274"] = 1; // reset EXIF orientation value            }        }    });    if (imageOrientation) {        switch (imageOrientation) {            case 3:                rotateDeg = 180;                break;            case 6:                rotateDeg = 270;                break;            case 8:                rotateDeg = 90;                reak;            default:                rotateDeg = 0;                break;        }        Jimp.read(buffer, (err, lenna) => {            if (err) {                console.log('err', err);                return;            }            lenna                .rotate(rotateDeg) // correct orientation                .write(path.join(__dirname, "uploads") + '/' + image.filename); // save        });    }};

Primeiro, definimos o readFileAsyncque transforma a função fs.readFile em uma promessa.

Agora, vamos ver o que temos na função real. Primeiro, estamos usando o pacote modify-exif para definir o valor da orientação EXIF ​​para cada imagem com o valor 1 (o padrão) se já não fosse 1 .

Depois de alterar as informações EXIF, agora usamos o jimp para girar a imagem de acordo com o valor de orientação EXIF ​​obtido anteriormente e salve a imagem novamente.

E é isso – todas as imagens agora são mostradas corretamente em todos os navegadores.

Você pode encontrar o exemplo completo no Github.

Conclusão #

A partir de agora, o único navegador que respeita a orientação EXIF ​​são os navegadores no iOS, mas há esperança de que todos os outros navegadores, mais cedo ou mais tarde, também os honrem e mostrem a orientação correta. Dessa forma, esse problema seria resolvido automaticamente e nós, desenvolvedores, temos um problema a menos para lidar.

No entanto, no momento, a única maneira de corrigir o problema de orientação é removendo os dados de orientação EXIF ​​e girando a imagem adequadamente, o que pode ser feito manualmente ou usando seu backend favorito. Também seria possível corrigi-lo no lado do cliente usando JavaScript, mas eu desaconselho, pois devemos terceirizar o menos possível o trabalho pesado para o front-end e, portanto, para o usuário.

Codificação feliz e não se esqueça de informar ao seu navegador favorito que eles devem respeitar a orientação EXIF ​​e corrigir esse problema.

Postado em Blog
Escreva um comentário