К счастью, API ввода / вывода изображений Java позволяет вам сделать это.Это также позволяет устанавливать метаданные изображения независимо от формата.Например, чтобы указать желаемый DPI, что я и хотел сделать.
Как оказалось, настройка dpi была менее простой, чем ожидалось…
Java-изображение I /O API - это плагин , для каждого формата файла, который вы хотите использовать, соответствующий плагин должен быть доступен.API предоставляет необходимые абстракции для написания нейтрального кода плагина и имеет хранилище доступных реализаций, которые можно запрашивать во время выполнения.Начиная с J2SE 6, каждый JRE должен предоставлять подключаемые модули для форматов файлов PNG, JPG и BMP (плюс некоторые другие, которые я еще не опробовал).
Спецификацией для установки метаданных изображения является стандарт (плагин нейтральный) спецификация формата метаданных.Как ни странно, спецификация представляет собой XML-схему.Правильно, если вы хотите установить DPI, вам нужно сделать это путем построения DOM -дерева с использованием IIOMetadataNodes и , объединить его состальное!Вздох ..
Обратите внимание, что плагины могут отличаться по своей поддержке стандартных метаданных:
В любом случае, соответствующие теги, когда вы хотите установить DPI: HorizontalPixelSize и VerticalPixelSize:
<!ELEMENT "HorizontalPixelSize" EMPTY>
<!-- The width of a pixel, in millimeters,
as it should be rendered on media -->
<!ATTLIST "HorizontalPixelSize" "value" #CDATA #REQUIRED>
<!-- Data type: Float -->
<!ELEMENT "VerticalPixelSize" EMPTY>
<!-- The height of a pixel, in millimeters,
as it should be rendered on media -->
<!ATTLIST "VerticalPixelSize" "value" #CDATA #REQUIRED>
<!-- Data type: Float -->
Обратите внимание, что в спецификации четко указано, что оба должны быть выражены вмиллиметры на точку.Как игнорировать вашу собственную спецификацию, Sun style
Sun реализовала эту спецификацию метаданных для своих плагинов PNG и JPG и включила ее в свои текущие дистрибутивы JDK и JRE.Соответствующие классы:
com.sun.imageio.plugins.png.PNGImageWriter
com.sun.imageio.plugins.jpeg.JPEGImageWriter
. Из пакета com.sun можно сказать, что они не являются частью J2SE API, но специфичны для реализации Sun.
Помните, как требовалась спецификациямиллиметры на точку?Итак, взгляните на следующую таблицу, чтобы увидеть, как Sun на самом деле реализовала спецификацию:
plug-in unit bug report date reported
PNGImageWriter dots per millimeter bug 5106305 23 sep 2004
JPEGImageWriter decimeter per dot bug 6359243 05 dec 2005
Эти ошибки были известны очень давно, и их исправления действительно просты.К сожалению, им был присвоен низкий приоритет, и они даже не оценивались на момент написания (июль 2008 г.).Отлично.И что теперь?
Ну, так как обходной путь настолько тривиален, я решил придерживаться API ввода / вывода изображения.Если вы дадите этим классам то, что они хотят, растровые изображения получатся хорошими.Чтобы гарантировать, что ваш код экспорта также работает на платформах, которые правильно реализуют спецификацию, он должен проверить фактические используемые классы реализации и компенсировать ошибки.
Если вы оказались в подобной ситуации, убедитесь, чтоВаш обходной код сможет справиться, когда ошибки будут исправлены в конце концов.Подробнее об этом в статье ' Как ошибки в API J2SE могут кусать вас дважды '.
О, и если вы используете instanceof для проверки на наличие экземпляров класса с ошибками, что не гарантируетсячтобы существовать на всех платформах, обязательно перехватывайте NoClassDefFoundError;)