Как я могу получить DPI от изображения в JS? - PullRequest
0 голосов
/ 30 января 2019

Я работаю на холсте HTML5, чтобы вычислить расстояние на изображении между двумя точками.Я хочу преобразовать это расстояние в пикселях в см.Я нашел формулу: пикселей * 2,54 / DPI.Итак, я хотел бы знать, возможно ли получить свойства изображения DPI в JS?Или я могу использовать самый простой способ для вычисления см из пикселей?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 31 января 2019

То, что вы запрашиваете, для извлечения физического отображаемого размера в см чего-либо цифрового, не может быть сделано без большого количества эвристик, то есть у нас, как у веб-разработчика, естьнет способа сделать это для всех наших посетителей.


О вашей формуле:

DPI - Точек на дюйм .

Это мера того, сколько точек может поместиться в одном дюйме.Это устройство обычно для принтеров или сканеров.Однако монитор не имеет точек, поэтому значение DPI для него не имеет значения.

Цифровые носители, подобные изображениям, могут включать в свои метаданные информацию DPI , но это толькоподсказка либо к настройкам сканера , использованным при генерации файла, либо к указанию автора на предполагаемый размер: напечатано .Только несколько специализированных программ будут использовать эту информацию, а ваш веб-браузер не использует их.

Digital Pixel - (растровый Picture-Cell).

Это наименьшая единица видимогоинформация в растровой графике .Эта информация может храниться разными способами, но не делится другими способами, кроме создания новых, поддельных данных.Обычно это « px », на который мы ссылаемся в 1920x1080px .
Чтобы упростить понимание, мы можем взять случай растровых изображений, где каждый цифровой пиксель представлен своим собственным набором битов в файле, чтобы еще раз упростить его, давайте возьмем пример 8-битного растрового изображения (одноцветное, обычно серого цвета).Здесь 8 бит используются для представления одного цифрового пикселя (цветовой точки).Например, мы можем создать растровое изображение размером 2x2px со следующей информацией:

[2, 125, 255, 125, 255]
 |   |    |    |    - pixel (2,2) 100% intensity
 |   |    |     - pixel (2,1) 50% intensity
 |   |     - pixel (1,2) 100% intensity
 |    - pixel (1,1) 50% intensity
  - width (nb of digital pixels per line)
/* height can be determined by the `length of data array / width` */

Остерегайтесь, хотя все растровые изображения не являются растровыми изображениями, и они не все имеют это отношение бит-пиксель ,но у всех них есть понятие цифрового пикселя, как в самом маленьком блоке информации о цвете, который они содержат.


С разъяснением этих двух понятий мы можем объяснить, что означает ваша формула:

const pxTocm = (pixels, DPI) => pixels * 2.54 / DPI;

Если мы возьмем растровое изображение размером 150 * 150 пикселей и распечатаем его на довольно хорошем струйном принтере с разрешением 300 точек на дюйм, эта формула правильно даст нам 1,27 см или 0,5 дюйма

Но это работает, только если нам известно печатное разрешение .


Хорошо, тогда давайте просто воспользуемся разрешением экрана.

PPI - число пикселей на дюйм *

Это то, что нам нужно для большинства мониторов.Очень похоже на DPI, здесь измеряется количество физических пикселей , которое монитор содержит в одном дюйме.
Что физических пикселей для монитора зависит от типа монитораиспользуется, но, например, в большинстве ЖК-мониторов один физический пиксель состоит из трех диодов, одного красного, зеленого и синего, также называемых субпикселями.

A photograph of sub-PIXEL display elements on a laptop's LCD screen
Вы можете видеть все три подпикселя, составляющие один пиксель.
Изображение предоставлено: CC-BY-SA 4.0 Krapteek88 для wikimedia.org

Таким образом, мы действительно могли бы переписать вашу формулу, чтобы она была

const pxTocm(pixels, PPI) => pixels * 2.54 / PPI;

Но это сработало бы, только если изображение отображалось с коэффициентом 100%, то есть одним цифровым пикселем занимает один физический пиксель , что редко встречается в сети, и, кроме того, нам нужно знать это значение PPI .

Из веб-API у нас нет способа узнать, что значение PPI .Мы даже не можем быть уверены, что отображаем на мониторе, это может быть лучевой проектор, для которого концепция PPI не имеет никакого значения.

Ближайшийявляется разрешением экрана (при Window.screen объекте, но это даст нам только число цифровых пикселей , которое удерживает дисплей; мы все еще пропускаем фактический физический размер этого дисплея.

PPI = Math.hypot(screen.width, screen.height) / physical_size_of_diagonal
// and we don't have any way to find this diagonal...

Но что такое window.devicePixelRatio, о котором я слышал, если не PPI моего экрана?

Чтобы объяснить это, нам сначала нужно объяснить, что такое CSS px

CSS px - Читается как «пиксель», но не как пиксель.

A px - это единица, , называемая W3C "магической единицейCSS ".Это значение зависит от поддержки и ее расстояния до глаз зрителя (!). Здесь вы можете найти довольно доступное объяснение того, что такое опорный пиксель для CSS.В принципе, он должен выглядеть одинаково, если вы смотрите на мониторе на опасном расстоянии, и если вы смотрите на телефоне на более близком расстоянии.

Я надеюсь, вы понимаете, как трудно это сопоставить среальное измерение.

window.devicePixelRatio

Это значение представляет количество физических пикселей, которые будут использоваться для отображения CSS px.
Это может были полезны, потому что с этим значением мы можем сопоставить точно один CSS px с количеством используемых физических пикселей.

Если бы мы знали, что на самом деле представляет CSS px, т. е. (мы на монитореили мобильное устройство или другое устройство?), и каково текущее разрешение PPI монитора нашего пользователя (но мы этого не делаем), тогда мы могли бы измерить отображаемый размер на мониторе.(Но мы не можем).

Так что да, мы можем на настольном мониторе 96PPI без масштабирования ОС получить вид или формулу @JuMoGar, представленные в их ответе (заметьте, что они ошиблись):

const CSSpxTocm = (CSSpx) => CSSpx * 2.54 / (96 / devicePixelRatio);

, где 96 - это жестко закодированное значение 96PPI, которое CSS px использует в единицах своих 96 дюймов.

Но попробуйте это на мобильном телефоне, и выПосмотрим, как это сломано. Как скрипка, если с мобильного легче.

const CSSpxTocm = (CSSpx) => CSSpx * 2.54 / (96 / devicePixelRatio);

console.log(CSSpxTocm(96) + 'cm');
.test {
  border-top: 3px solid blue;
  height: 10px;
  width: 96px;
}
<div class="test px"></div>

На мониторе моего ноутбука 125PPI (13,3 дюйма 1280x1080px) , это уже неправильно, заявив, что оно составляет 2,54 см,хотя в действительности он составляет около 2,2 см, но на моем телефоне Galaxy S6 он возвращает 10,16 см , тогда как IRL - примерно 1,7 см.

Почему?Поскольку экран имеет ~ 577 PPI, но все же он использует только один физический пиксель на CSS px.Это означает, что devicePixelRatio по-прежнему 1, но PPI , который так далек от ожидаемого 96, что эта формула возвращает абсурды. (диагональ экрана S6 составляет 5,1 дюйма, ~ 12,9 см)

0 голосов
/ 30 января 2019

Размер изображения в смс можно получить с помощью JavaScript.Позаботьтесь о том, чтобы значения DPI были разными на каждом устройстве, поэтому я использую window.devicePixelRatio, чтобы получить разрешение экрана, на котором отображается изображение (может быть NoteBook, Mobile, Tablet, ...).

В одну сторонуэто:

/* Convert px to cm */
function getSizeInCM(sizeInPX) {
   return sizeInPX * 2.54 / (96 * window.devicePixelRatio)
};

/* get width and height of an image in cms */
var img = document.getElementById('IMAGE_ID'),
var width = getSizeInCM(img.clientWidth),
var height = getSizeInCM(img.clientHeight);

Если вы хотите получить только пиксели одного изображения, это проще:

var imageWidth = document.getElementById("IMAGE_ID").width;
var imageHeigth = document.getElementById("IMAGE_ID").height;

// or...

var imageWidth = document.getElementById("IMAGE_ID").clientWidth;
var imageHeigth = document.getElementById("IMAGE_ID").clientHeight;

Еще один способ сделать это: вам понадобится дополнительная библиотека: Библиотека загрузки изображений Blueimp и используйте ее EXIF parsing extension

Вот код, который возвращает разрешение своих координат:

loadImage.parseMetaData(FILE, function(meta) {
    if (!meta.exif) { return; }

    var resX = meta.exif.get('XResolution');
    var resY = meta.exif.get('YResolution');
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...