По причинам совместимости с мобильными устройствами в одном из наших проектов требуется интерфейс для преобразования PDF в интерфейс, который можно просматривать непосредственно на мобильной странице. Чтобы облегчить решение, мы используем плагин pdf.js, который может конвертировать pdf в холст и рисовать его на странице. Однако в процессе тестирования было обнаружено, что в мобильном браузере нарисованный контент был очень размытым (как показано ниже). После анализа выяснилось, что это было вызвано экраном высокой четкости мобильного терминала. После решения проблемы запишите причины и выводы письменно.
Прежде чем объяснять проблему, вам сначала необходимо получить некоторые базовые знания о мобильном дисплее и каванах, чтобы облегчить дальнейшее исследование. Если вы хотите увидеть результаты напрямую, вы можете прокрутить до конца.
Некоторые базовые знания об экранах Физические пиксели (DP)Физические пиксели еще называют пикселями устройства. Мы часто слышим, что разрешение мобильных телефонов — это физические пиксели. Например, физическое разрешение iPhone 7 составляет 750*1334. Экран состоит из пикселей, то есть экран имеет 750 пикселей по горизонтали и 1334 пикселя по вертикали.
Независимый от устройства пиксель (DIP)Также называются логическими пикселями, например, размеры Iphone4 и Iphone3GS составляют 3,5 дюйма. Физическое разрешение iphone4 составляет 640 * 980, а у 3gs - только 320 * 480. Если мы нарисуем изображение шириной 320 пикселей в соответствии с. реальный макет, в iphone4 Только половина экрана содержит контент, а оставшаяся половина пуста. Чтобы избежать этой проблемы, мы ввели логические пиксели и установили логические пиксели обоих мобильных телефонов на 320 пикселей, чтобы облегчить рисование.
Соотношение пикселей устройства (DPR)Вышеуказанные пиксели, независимые от устройства, в конечном итоге предназначены для удобства вычислений. Мы унифицировали логические пиксели устройства, но физические пиксели, представленные каждым логическим пикселем, не являются определенными, чтобы определить взаимосвязь между физическими пикселями и логическими пикселями без масштабирования. , , мы представили понятие соотношения пикселей устройства (DPR).
Соотношение пикселей устройства = пиксели устройства / логические пиксели DPR = DP / DIP
Есть много теорий, упомянутых выше. Вот картинка для пояснения.
Как видно из приведенного выше рисунка, при одинаковом размере логических пикселей экран высокой четкости имеет больше физических пикселей. На обычном экране 1 логический пиксель соответствует 1 физическому пикселю, а на экране высокой четкости с dpr = 2 1 логический пиксель состоит из 4 физических пикселей. По этой же причине экраны высокой четкости более хрупкие.
Некоторые базовые знания о холсте Холст рисует растровые изображенияЭто важный момент, который должен знать каждый, кто знаком с Canvas, и это также суть проблемы, которую мы будем анализировать дальше.
Объяснение растровых изображений мы оставим позже. Сейчас нам нужно только знать, что изображение, нарисованное холстом, является растровым.
Свойства ширины и высоты холстаНовички очень легко могут ошибиться в атрибутах ширины и высоты холста. Эти два свойства часто путают со свойствами ширины и высоты в CSS.
Например, у нас есть следующий код (1):
<ширина холста=600 высота=300 стиль=ширина: 300 пикселей высота: 150 пикселей></canvas>
Если вы все еще не можете это понять, вы можете представить это в виде следующего кода (2):
<!-- Размер файла logo.png составляет 600 * 300 --><img style=width: 300px; height: 150px src=logo.png />
Ширина и высота холста по умолчанию — 300 * 150. После установки CSS холст будет масштабироваться (обратите внимание, не обрезан) в соответствии с установленными шириной и высотой CSS , которые совпадают с тегом img.
Приведенный выше код (1) на самом деле можно объяснить более популярным способом, то есть один логический пиксель фактически заполняется двумя пикселями холста.
Предварительное обсуждение причин двусмысленностиВышеизложенное представляет собой введение в некоторые необходимые базовые знания, а формальное исследование начнется ниже.
Прежде всего, мы упомянули, что использование холста для рисования изображений является растровым, а форматы jpg и png, которые мы обычно используем, также являются растровыми изображениями. Так что же такое растровое изображение?
Растровое изображение, также называемое пиксельной картой или растровой картой, хранит и отображает изображения, записывая цвет, глубину, прозрачность и другую информацию каждой точки изображения. Говоря более конкретно, вы можете думать о растровом изображении как об огромной головоломке. Эта головоломка состоит из бесчисленного количества частей, и каждая часть представляет собой сплошной цветной пиксель. Теоретически один растровый пиксель соответствует одному физическому пикселю . Но что, если для просмотра изображения использовать экран высокой четкости, например экран Retina от Apple?
Предположим, у нас есть следующий код, который будет отображаться на экране Retina iPhone 4:
<ширина холста=320 высота=150 стиль=ширина: 320 пикселей высота: 150 пикселей></canvas>
Физические пиксели самого iPhone 4 имеют размер 640 * 980, а пиксели, независимые от устройства, — 320 * 480, что означает, что 1 пиксель CSS фактически состоит из 4 физических пикселей. Пиксели холста имеют размер 320 * 150, а его пиксели CSS — 320 * 150. Это означает, что один пиксель CSS будет состоять из одного элемента холста, поэтому преобразование выполняется следующим образом: На экране Retina один пиксель холста (или один растровый пиксель) заполняет 4 физических пикселя. Поскольку один растровый пиксель не может быть разделен дальше, он может принимать только ближайший цвет, что приводит к размытию изображения.
Если вы все еще в замешательстве, следующая картинка может проиллюстрировать, как растровое изображение заполняется на экране Retina:
В левой части изображения выше показаны правила отображения на обычном экране. Видно, что имеется 4 растровых пикселя, а на экране высокой четкости справа — 16 пикселей. Поскольку пиксели нельзя разрезать, цвет меняется.
Но есть одна вещь, которая не была четко объяснена: почему изображение принимает ближайший цвет вместо того, чтобы напрямую принимать исходное значение. Это также является причиной размытия.
Человек за кулисами — технология сглаживанияВот что мне помог объяснить один из моих старших одноклассников. Только что мы сказали, что каждый элемент растрового изображения на самом деле представляет собой сплошной цветной пиксель. Теперь предположим, что нам нужно нарисовать число 0 на обычном экране с размером CSS 4 х 4 пикселя и dpr, равным 1. Тогда то, что мы рисуем, должно выглядеть как следующее изображение, где 1 представляет черные пиксели, а 0 — белые пиксели.
Видно, что когда dpr относительно мал, наш шаблон 0 все еще относительно очевиден. Теперь, если наш размер CSS останется неизменным, но изображение будет отображаться на экране сетчатки, каков будет эффект?
Мы знаем, что под экраном Retina один пиксель CSS представляет 4 физических пикселя. Если мы не будем выполнять какую-либо обработку, непосредственно упорядочим в соответствии с приведенной выше матрицей и расширим матрицу, мы обнаружим, что под экраном Retina наш шаблон имеет очень явное ощущение неровности. На изображении явно отсутствует намек на оттенок.
Если мы немного изменим изображение, поменяем его на следующую картинку
Изображение сразу становится мягче, но место, которое должно было быть заполнено 4 0, превратилось в 3 1 плюс 1 0. На самом деле это так называемый процесс сглаживания изображения. Чтобы устранить ощущение неровности, исходный цвет изменяется на изображениях, наполненных большим количеством цветов, чтобы сделать их более естественными, стыки изображений становятся приблизительными цветами. объясняет, почему при заливке цвета выше используется не исходный, а приблизительный цвет.
Краткое изложение причинПосле приведенного выше объяснения давайте теперь подведем итоги следующим выводам. Теперь, когда мобильные терминалы стали популярны, а экраны высокой четкости стали популярными, CSS-пиксель размером 1 пиксель фактически представляет собой 4 или более физических пикселя. Однако из-за нашей проблемы с кодом наши 1 пиксель CSS и 1 пиксель холста равны, в результате чего 1 пиксель холста фактически необходимо заполнить 4 или более физическими пикселями. Чтобы обеспечить плавную обработку изображения, заполнение оставшегося физического пикселя. пиксели используют приближение исходного цвета, что приводит к размытому изображению.
Идеи решенияКак только вы поймете причину проблемы, ее легко решить. Самое важное для решения проблемы — уравнять один пиксель холста и один физический пиксель.
В браузерах более поздних версий под объектом окна висит атрибут devicePixelRatio, который представляет собой упомянутый выше dpr.
Когда ширина и высота CSS элемента холста определены, мы можем сделать это
let Canvas = document.getElementById('canvas');let ctx = Canvas.getContext('2d');let dpr = window.devicePixelRatio; // Предположим, что dpr равно 2 // Получите ширину и высоту CSS let { width: cssWidth, высота: cssHeight } = Canvas.getBoundingClientRect();// Согласно dpr, расширяем пиксели холста так, чтобы один пиксель холста был равен одному физическому пикселю. Canvas.width = dpr * cssWidth; Canvas.height = dpr * cssHeight // При расширении холста система координат холст также расширяется. Если содержимое рисунка основано на исходной системе координат, содержимое будет уменьшено // поэтому масштаб рисунка необходимо увеличить ctx.scale(dpr,dpr);Краткое описание опыта
Часто, когда мы обнаруживаем проблему, мы не можем сосредоточиться на ее решении. Вместо этого нам следует глубоко понять причину проблемы, чтобы мы могли лучше двигаться вперед.
Выше приведено все содержание этой статьи. Я надеюсь, что она будет полезна для изучения всеми. Я также надеюсь, что все поддержат сеть VeVb Wulin.