Devido a alguns motivos de compatibilidade móvel, um de nossos projetos requer que o front-end converta o PDF em uma interface que possa ser visualizada diretamente na página móvel. Para facilitar a solução, utilizamos o plug-in pdf.js, que pode converter pdf em canvas e desenhá-lo na página. Porém, durante o processo de teste, descobriu-se que no navegador móvel o conteúdo desenhado estava muito borrado (conforme mostrado abaixo, descobriu-se que isso era causado pela tela de alta definição do terminal móvel). Depois de resolver o problema, anote as razões e conclusões por escrito
Antes de explicar o problema, primeiro você precisa compreender alguns conhecimentos básicos sobre exibição móvel e cavans para facilitar uma exploração posterior. Se quiser ver os resultados diretamente, você pode rolar até o final.
Alguns conhecimentos básicos sobre telas Pixels físicos (DP)Pixels físicos também são chamados de pixels de dispositivos. Freqüentemente ouvimos que a resolução dos telefones celulares é de pixels físicos. Por exemplo, a resolução física do iPhone 7 é 750 * 1334. A tela é composta por pixels, o que significa que a tela possui 750 pixels na direção horizontal e 1334 pixels na direção vertical.
Pixel Independente de Dispositivo (DIP)Também chamados de pixels lógicos, por exemplo, os tamanhos do Iphone4 e do Iphone3GS são ambos de 3,5 polegadas. A resolução física do iphone4 é 640 * 980, enquanto o 3gs tem apenas 320 * 480. Se desenharmos uma imagem com largura de 320px de acordo com o. layout real, no iphone4 apenas metade da tela possui conteúdo e a outra metade está em branco. Para evitar esse problema, introduzimos pixels lógicos e definimos os pixels lógicos de ambos os celulares para 320px para facilitar o desenho.
Proporção de pixels do dispositivo (DPR)Os pixels independentes do dispositivo acima são, em última análise, para conveniência de cálculo. Unificamos os pixels lógicos do dispositivo, mas os pixels físicos representados por cada pixel lógico não são certos. , introduzimos o conceito de proporção de pixels do dispositivo (DPR)
Proporção de pixels do dispositivo = pixels do dispositivo / pixels lógicos DPR = DP / DIP
Existem muitas teorias mencionadas acima.
Como pode ser visto na figura acima, com o mesmo tamanho de pixels lógicos, uma tela de alta definição possui mais pixels físicos. Em uma tela normal, 1 pixel lógico corresponde a 1 pixel físico, enquanto em uma tela de alta definição com dpr = 2, 1 pixel lógico é composto por 4 pixels físicos. Esta é também a razão pela qual as telas de alta definição são mais delicadas.
Alguns conhecimentos básicos sobre tela Canvas desenha bitmapsEste é um ponto de conhecimento que todos que conhecem o canvas deveriam conhecer, e é também o cerne do problema que analisaremos a seguir.
Deixaremos a explicação dos bitmaps mais tarde. Agora só precisamos saber que a imagem desenhada pelo canvas é um bitmap.
As propriedades de largura e altura da telaOs atributos de largura e altura da tela são muito fáceis para os iniciantes cometerem erros. Essas duas propriedades são frequentemente confundidas com as propriedades de largura e altura em CSS.
Por exemplo, temos o seguinte código (1):
<largura da tela=600 altura=300 estilo=largura: 300px altura: 150px></canvas>
Se você ainda não consegue entender, você pode imaginá-lo como o seguinte código (2):
<!-- Os pixels de logo.png são 600 * 300 --><img style=width: 300px height: 150px src=logo.png />
A largura e altura padrão da tela são 300 * 150. Depois de definir css nela, a tela será dimensionada (observe que não é cortada) de acordo com a largura e altura definidas do css .
O código acima (1) pode ser explicado de uma forma mais popular, ou seja, um pixel lógico é na verdade preenchido por dois pixels de tela.
Uma discussão preliminar sobre as causas da ambiguidadeO texto acima é uma introdução a alguns conhecimentos básicos necessários, e a exploração formal começará a seguir.
Em primeiro lugar, mencionamos que usar canvas para desenhar imagens é bitmap, e os jpg e png que normalmente usamos também são bitmaps. Então, o que é um bitmap?
Bitmap, também chamado de mapa de pixels ou mapa raster, armazena e exibe imagens registrando a cor, profundidade, transparência e outras informações de cada ponto da imagem. Para ser mais concreto, você pode pensar em um bitmap como um enorme quebra-cabeça. Esse quebra-cabeça tem inúmeras peças e cada peça representa um pixel de cor sólida. Teoricamente, um pixel de bitmap corresponde a um pixel físico . Mas e se você usar uma tela de alta definição, como a tela retina da Apple, para visualizar uma imagem?
Suponha que temos o seguinte código, que será exibido na tela retina do iPhone 4:
<largura da tela=320 altura=150 estilo=largura: 320px altura: 150px></canvas>
Os pixels físicos do próprio iPhone 4 são 640 * 980, enquanto os pixels independentes do dispositivo são 320 * 480, o que significa que 1 pixel CSS é na verdade composto por 4 pixels físicos. Os pixels da tela são 320 * 150 e seus pixels CSS são. 320 * 150. Significa que 1 pixel css será composto por 1 elemento canvas, então a conversão está feita, Em uma tela retina, um pixel de tela (ou um pixel de bitmap) preencherá 4 pixels físicos. Como um único pixel de bitmap não pode ser dividido, ele só pode obter a cor mais próxima, fazendo com que a imagem fique desfocada.
Se você ainda estiver confuso, a imagem a seguir pode ilustrar como o bitmap é preenchido na tela retina:
O lado esquerdo da imagem acima mostra as regras de exibição em uma tela normal. Pode-se observar que existem 4 pixels de bitmap, enquanto a tela de alta definição à direita possui 16 pixels. Como os pixels não podem ser cortados, a cor muda.
Mas uma coisa que não foi explicada com clareza é por que a imagem obtém a cor mais próxima em vez de obter o valor original diretamente. Esse também é o culpado pelo desfoque.
O homem nos bastidores – tecnologia de suavizaçãoA seguir está o que um de meus colegas mais velhos me ajudou a explicar. Acabamos de dizer que cada elemento de bitmap é na verdade um pixel de cor sólida. Agora suponha que precisamos desenhar um número 0 em uma tela normal com um tamanho css de 4px * 4px e um dpr de 1. Então o que desenhamos deve ser parecido com a imagem a seguir, onde 1 representa pixels pretos e 0 representa pixels brancos.
Pode-se ver que quando o dpr é relativamente pequeno, nosso padrão 0 ainda é relativamente óbvio. Agora, se o tamanho do nosso CSS permanecer inalterado, mas a imagem for desenhada na tela retina, como será o efeito?
Sabemos que sob a tela retina, um pixel CSS representa 4 pixels físicos. Se não fizermos nenhum processamento, organizarmos diretamente de acordo com a matriz acima e expandirmos a matriz, descobriremos que sob a tela retina nosso padrão tem um. sensação irregular muito óbvia. A imagem claramente carece de um toque de Hue.
Se mudarmos um pouco a imagem, mude para a imagem a seguir
A imagem parece instantaneamente mais suave, mas o lugar que deveria ter sido preenchido com 4 0s tornou-se 3 1s mais 1 0. Na verdade, esse é o chamado processo de suavização da imagem. Para resolver a sensação irregular, a cor original é alterada. Nas fotos preenchidas com mais cores, para ficarem mais naturais, as juntas das fotos ficam com cores aproximadas. explica por que Ao preencher a cor acima, não é usada a cor original, mas a cor aproximada.
Resumo dos motivosApós a explicação acima, vamos agora resumir as seguintes conclusões Agora que os terminais móveis são populares e as telas de alta definição basicamente se tornaram populares, um pixel CSS de 1px representa na verdade 4 ou mais pixels físicos. No entanto, devido ao nosso problema de código, nosso pixel CSS de 1px e 1 pixel de tela são iguais, o que resulta em 1 pixel de tela que realmente precisa ser preenchido com 4 ou mais pixels físicos para garantir o processamento suave da imagem, o preenchimento O restante físico. os pixels usam uma aproximação da cor original, resultando em uma imagem borrada.
Ideias de soluçõesDepois de entender a causa do problema, é fácil resolvê-lo. A coisa mais importante para resolver o problema é equalizar um pixel da tela e um pixel físico.
Há um atributo devicePixelRatio pendurado no objeto window de navegadores de versões superiores, que é o dpr mencionado acima.
Quando a largura e a altura do CSS do elemento canvas são determinadas, podemos fazer isso
let canvas = document.getElementById('canvas');let ctx = canvas.getContext('2d');let dpr = window.devicePixelRatio; // Suponha que dpr seja 2// Obtenha a largura e a altura do css let { width: cssWidth, altura: cssHeight } = canvas.getBoundingClientRect();// De acordo com o dpr, expanda os pixels da tela para que um pixel da tela seja igual a um pixel físico canvas.width = dpr * cssWidth; canvas também se expande. Se o conteúdo do desenho for baseado no sistema de coordenadas original, o conteúdo será reduzido // então a escala do desenho precisa ser ampliada ctx.scale(dpr,dpr);Resumo da experiência
Muitas vezes, quando encontramos um problema, não podemos nos concentrar em resolvê-lo. Em vez disso, devemos compreender profundamente a causa do problema para podermos avançar melhor.
O texto acima é todo o conteúdo deste artigo. Espero que seja útil para o estudo de todos. Também espero que todos apoiem a Rede VeVb Wulin.