Спасибо, очень актуально, был бы интересен цикл статей на данную тематику, от себя могу добавить, что похожие решения есть для mp3 файлов, когда берутся или заменяются данные о песне (время, битрейт, исполнитель, группа и т.д.), то есть также парситься сам файл.
DPI – это количество точек (равно пикселей в нашем случае) на дюйм. В электронном виде картинка состоит из пикселей, а в реальном мире мы используем сантиметры (или дюймы). Вот DPI – это как раз коэффициент, который показывает, сколько в один дюйм реального мира мы помещаем пикселей. Чем больше – тем четче картинка. Например для монитора DPI равен примерно 96, в то время, как для качественной цветной печати надо 300. Изменяя DPI, можно изменять физические размеры в сантиметрах, оставляя неизменным количество точек. Вот как-то так.
Как я понимаю, в данном речь идет о генерации картинки, в исходных параметрах которой есть только физические размеры, а DPI (для пересчета сантиметров в пикселы) ставится по умолчанию 72 или 96. Если подставить больше – здесь 600, то при пересчете мы получим более качественную картинку.
Простая арифметика (используем для простоты дюймы в качестве едениц).
Есть некие данные, которые необходимо визуализировать (например график) высотой в 10 дюймов. Когда мы используем значения DPI для монитора (каковые в вебе считаются по умолчанию), то получаем следующее:
10 дюймов x 72dpi = 720 точек
Но если мы заставим генерироваться наш PNG с разрешением 600, то получим картинку такую
По-моему случай клинический. Я уже в двух местах указывал на векторную графику (указал бы больше, но раз в 5 минут не разгонишься), осталось только ссылку на вики дать для полного счастья…
Судя по вашим комментарием, вы не можете понять одну простую вещь – существует такой класс графики, как векторная, которая измеряется в сантиметрах, метрах и дюмах, т.е. еденицах физического мира. Как правило, вся информаци типа графиков, диаграмм и тому подобных вещей генерируется в векторной форме, и только потом растрируется (в тот же PNG, о котором идет речь в данном случае). Так вот именно в этот момент DPI играют определяющую роль.
Представьте себе, что вы отсканировали линейку. Фотка получилась размером 2540x1560 пикселей. Теперь распечатайте эту фотку так, чтобы размер линейки на листе бумаги совпал точь в точь с вашей реальной линейкой.
Если dpi нигде не указан, то вам придется вручную подбирать размер фотографии при печати, а с dpi этого делать не придется.
Исходный размер изображения: 2540x1560 пикселей, 300 dpi
Вычисляем размер фотографии в дюймах, получаем 8,46«x5,2». Соответственно на отпечатке фотография получится ровно столько сколько у нас получилось дюймов. Ни больше ни меньше.
Господа! Сколько можно переливать из пустого в порожнее? dpi принтера — это величина, которая должна волновать вас в последнюю очередь, т.к. во-первых точки на бумаге это не точки на экране — они не квадратные и не заданного цвета, а круглые и одного из базовых цветов картриджа. И преобразование экранного пикселя в несколько разноцветных точек краски на бумаге — это полностью забота драйвера принтера. Ему нужно только одно — размер. Либо его можно задать явно из программы, из которой ведётся печать, либо через те самые dpi, а в программ указать «масштаб 100%». Если не понимаете зачем в мире придумана та или иная вещь, это не значит что она не нужна.
Смотрите комментарий выше, в данном случае, как я понял, речь идет о конвертации сантиметров в точки.
А про вашу картинку – задавать ничего не надо. Просто когда вы будете распечатывать, вы можете либо посчитать размер картинки, которую возможно распечатать качественно (зная, что качественная печать – это 200-300 dpi). Либо наоборот, растянув ее на некое количество сантиметров, сможете оценить, насколько качественно она будет распечатана (опираясь на те же значения).
Повторюсь. Насколько я понял, автор топика генерирует картинку, исходя из некого размера в сантиметрах (точнее даже в метрах, но не суть важно). Отсюда вывод – чем больше будет DPI, тем более качественной будет сгенерированная картинка.
Бу-го-га! Векторная графика — она вообще в абстрактных единицах, которые мы можем масштабировать как нам будет угодно.
Всё, что тут пытаются сказать — это то, что DPI для рисунка — параметер вовсе необязательный и начинает играть только тогда, когда рисунок куда-то выводится (на монитор, на принтер...) От самого значения DPI «качество картинки» не изменится никак: сколько-то пикселей там было, столько и и будет. И по умолчанию на любое устройство картинка будет выведена пиксель-в-пиксель, как может устройство. Что, понятное, дело, обеспечит наилучшее качество передачи растра. Принудительное задание DPI может привести к тому, что картинка будет либо растянута, либо ужата. Оба варианта приведут к потере качества. Вот люди и недоумевают.
Это даже не рекомендация. Это некоторая гарантия того, что кому бы я не послал свой график и чьим бы принтером не воспользовался, распечатав его, все увидят миллиметровку нанесенную на нем действительно миллиметровой. =)
представьте, что вы вставили этот файл в текстовый редактор (пусть будет M$ Word). У вас есть линейка вверху и слева от страницы. Вот вы берете и изменяете размер картинки перетаскиванием её за уголок. Если вы уместили её в 1 дюйм — то у вас будет 500 dpi, а если на всю страницу, то 10 dpi (к примеру). Так вот, для печати dpi очень важны, так как нужно знать, какого размера нужно будет напечатать заданную картинку. То ли вместить ваши 500 точек в 1 дюйме на бумаге, то ли растянуть на весь лист A0. Качество будет соответствующее.
Могу привести еще примеры, если интересно
в вашем случае не фигурирует. это было как пример того, как можно «задать» dpi в редакторе для вашего файла.
другой пример — у вас есть 2 картинки — 9000*9000 и 3000*3000, с одинаковым 300 dpi их можно распечатать: первую на 3"*3", вторую на 10"*10".
как распечатать — открываете картинку в фотошопе и жмете печать не изменяя никаких настроек, увидите как раз такой эффект.
По будним дням с 9 до 18 с перерывом на обед.
Я не совсем понял ваш вопрос.
Вообще, как я понимаю, прописанный в картинке dpi изоморфен exif-тэгам, т.е. не используется напрямую при отображении, но может использоваться, например при печати. Как? Поясняю — зная dpi картинки и принтера получаем коэффициент масштабирования точек картинки в точки принтера.
50x50 пикселей (при 50 dpi) на печати даст ровно дюйм
1000x1000 пикселей (при 1000 dpi) на печати даст ровно дюйм
500x500 пикселей (при 1000 dpi) на печати даст полдюйма.
dpi принтера это кол-во точек краски на дюйм. т.е. если dpi картинки 300 а у принтера 1200 то он впечатает в один пиксел картинки 4 чернильных точки. но у принтера есть еще дефолтный dpi для картинок без dpi. сори за тавтологию
ппц…
вам делать нечего людей копипастами задрачивать?
а если вы не знаете какой dpi у принтера?
если вы продаете софт и какой там будет принтер вам не известно, а нужно отпечатать картинку строго 10*20 см???
Совершенно верно. В файле и с картинкой никаких метаморфоз не происходит. Это просто способ придать безразмерным пикселям какие-то реальные физические размеры и при этом не зависеть от разрешающей способности устройств вывода.
Дефолтные настройки принтера вообще не причем, он как печатал раньше с разрешением 300 dpi (600/1200) так и будет печатать в таком же разрешении. Текст например всегда печатается с разрешением равным как у принтера, а с графикой сложнее если не указано явного масштаба (читай dpi).
А всё проделанное выше лишь объясняет принтеру в каком масштабе печатать картинку. Например Вы фотки когда-нибудь печатали? Так вот, всё стало бы ясно сразу (ну или почти сразу) что как и почему.
Никто никого не победит. Просто принтер правильно смасштабирует эту картинку и на отпечатке она получится ровно столько дюймов сколько определено значением DPI.
Это зависит от софта. Подавляющее большинство смотрят на параметр dpi указанный для картинке и при печати экстраполируют ее до разрешения принтера (если оно отличается).
При этом если в файле не указан dpi, то за дефолт часто берется системное разрешение (например 96 dpi).
К тому же это вы знаете разрешение своего принтера, а если я хочу печатать картинку на разных принтерах? И хочу при этом получать всегда одинаковые физические размеры отпечатка. Кроме того текстовые редакторы, куда эту картинку вставляют, ничего не знают о разрешении принтера и картинка размещается на в редакторе с теми физическими размерами относительно листа, которые соответствуют dpi в файле, а в противном случае экранному (что неприемлемо).
Я могу распечатать квадратный дюйм из картинки любого размера. =)
Если я имею картинку 1x1px, то достаточно указать разрешение 1dpi.
Если 10x10 то 10dpi, а если скажем 10000x10000 то 10000dpi.
Также я получу картинку в один дюйм из файла 50x666 если пропишу ему по горизонтали 50dpi, а по вертикали 666dpi.
При печати во всех случаях я получу картинку в в один дюйм. Качество может быть разным, но если это квадрат малевича, то разницы не будет.
Я в своем классе могу задать графику любые физические размеры. При этом какой бы я dpi не задал, он будет на печати ровно с теми физическими размерами которые я указал, хотя будет сгенерировано разное количество пикселей.
ну так а откуда софт будет знать сколько нужно вместить пикселей картинки в этот дюйм на бумаге???
и откуда принтер будет знать, сколько нужно «выплюнуть» точек краски на бумагу для этого дюйма???
Формат хранение графических данных PNG не предусматривает сохранения информации о дюйма или сантиметрах. Вместо этого, как и все он хранит разрешение, в px/дюйм. Что являлось по мнению экспертов, когда придумывали стандарты являлось более грамотным решением. И я с ними согласен. Поскольку если хранить просто размеры в дюймах или сантиметрах, то всякий раз, когда мы захотим вырезать из картинки кусочек, или подрезать ее по краям графическому софту пришлось бы изменять не только разрешение в пикселях, но и заботится о метрические размерах. И если софт сделает это некорректно или не умеет этого, то мы бы получали искаженную информацию внутри файла и рисковали бы навсегда потерять сведения о реальных физических размерах картинки.
А что в этом плохого? Если на картинку будут смотреть из космоса, то использование разрешения в 1dpi будет единственной возможностью не получить графический файл для многокилометровой картинки в пару петабайт и не загрузить компьютер вычислениями на несколько лет.
В полиграфии параметр dpi используется повсеместно и они находят это вполне удобным. Например рекламные щиты печатаются реально с очень низким dpi, на них будут смотреть из далека, а работать гигантским файлом было бы много сложнее. Хотя плоттеры на которых эти щиты печатаются чаще всего используют гораздо большую разрешающую способность. Кроме того когда я передаю файл в печать, мне чаще всего ничего не известно о технике, которую они там используют. И не стану же я для каждого принтера, каждого печатающего устройства готовить свой, отдельный файл? Мне проще сгенерировать один с заданным разрешением, которого мне вполне достаточно и использовать его повсюду.
Кроме того параметр dpi позволяет судить о четкости и реальном разрешении картинки. Например я знаю, что для моих графиков разрешающей способности в 600dpi достаточно для 100% передачи всех нюансов и заложенной в них информации. Поэтому генерирую их и сохраняю всегда с таким разрешением в независимости от того, где собираюсь их печатать. Зачем порождать избыточные данные?
Поправлю только немного. Принтер печатает то, что ему отдаст компьютер. И настройки DPI принтера – это грубо говоря настройки качества печати. А вот понять в какой размер надо печатать должен компьютер, исользуя DPI.
Если не ошибаюсь, если принтер поддерживает Postscript, то он сам всё вычисляет исходя из dpi. Но в целом да, именно от софта (или драйверов) зависит как будет использоваться значение dpi и масштабироваться изображение.
Блин. Прочитал весь тред почти. Не смог удержаться.
dpi в файле нужны только для того, чтобы программе/человеку, который будет ее печатать было понятно каких размеров эта картинка при печати должна получиться.
Вы отсканировали картинку 10х10 см, сохранили ее в png, получили сколько-то на сколько-то пикселей, передали затем, например, верстальщику, а он понятия не имеет каких размеров был оригинал, потому что видит только пиксели.
Так вот, чтобы повторить оригинальный размер исходника при печати необходим какой-то параметр, в данном случае это dpi.
Т.е. этот параметр в исходном файле — информационное поле, ничего более.
Я для себя написал класс. Который принимает данные и генерирует особого вида графики по этим данным. Эти графики мне надо вставлять в документы в OpenOffice или же в Word и затем распечатывать.
Так вот, когда я хочу получить график размером 10x15см к примеру. То я передаю в свой класс эти размеры в сантиметрах, а также мне известно, что мой старенький лазерный принтер хорошо печатает с разрешением 600dpi. Эту цифру я тоже передаю в свой класс. В итоге получаю картинку 2362px × 3543px с прописанным внутри разрешением 600dpi. Теперь если я ее вставлю в «Word» или «OpenOffice Редактор текстов», то она там будет действительно 10x15см.
Я пересчитал, но Word об этом ничего не знает. Он понятия не имеет какого физического размера я хочу увидеть ее в документе. Раньше мне приходилось либо изменять разрешение в графическом редакторе, а потом сохранять и вставлять картинку в ворд. Либо сначала вставлять ее в Word, а потом там, в свойствах, указывать ее физические размеры на листе.
Фактически Word просто изменит при этом dpi по вертикали. Ни разрешение принтера, ни количество пикселей в картинке при этом не изменится. Они будут экстраполированы в разрешение принтера, только при передаче документа принтеру.
Да, вы правы. Но вероятность встретить ее в заголовке cгенерированным GD (а функция ищет первое такое вхождение) ничтожна и для моих личных целей хватило и такого примитива. В идеале конечно было бы неплохо пройтись по чункам.
Откуда уверенность, что она ничтожна? Алгоритм сжатия PNG как-то умеет избегать таких сочетаний? Вероятность появления в каждом куске кода IDAT ровно такая же, как у любой другой последовательности из 4-х символов — примерно один на 4 миллиона. При хорошей посещаемости это очень реальная цифра.
Алгоритм сжатия тут не причем. IDAT чанк как раз и содержит сжатые данные картинки. Так что до первого IDAT чанка у нас никакой сжатой графической информации в принципе не встречается.
В png-шках получаемых из GD перед первым IDAT чанком только стандартный идентификатор PNG и IHDR чанк содержащий:
Width: 4 bytes
Height: 4 bytes
Bit depth: 1 byte
Color type: 1 byte
Compression method: 1 byte
Filter method: 1 byte
Interlace method: 1 byte
Какова вероятность того, что в сочетании этих параметров или в CRC32 от них+заголовок мы получим последовательность байт которая будет соответствовать ASCII «pHYs»?
Я указал в топике, что не претендую на грамотный алгоритм вставки чанка, мне сей код нужен только чтобы для себя пару картинок в неделю генерить.
При желании можно даже подобрать все возможные сочетания для 17 байт, от которых считается CRC и получается равным IDAT, посмотреть, есть ли среди них вменяемые.
Даже грамотнее будет следуя спецификации зафиксировать первые 4 как IHDR, затем перебрать все возможные разрешения и сочетания параметров, их не так много.
Да, вы что! Так здорово все объяснялось! Мне как раз сегодня срочно нужно было 'въехать' в алгоритм генерации оптимальных изображений для печати. После прочтения я понял значение всех величин. Спасибо пишущим и реагирующим! Спасибо, Хабр!
Прописываем dpi в PNG с помощью PHP