2013-05-09 1 views
1

Есть ли Java-библиотека, которая может читать DPI из файла jpg (like pngj for PNG)? Это для кода на Android, поэтому я не могу использовать java.awt.image. *Как я могу прочитать DPI для JPG-файла на Android?

И если есть способ сделать это с помощью класса Bitmap Android, это было бы потрясающе.

+0

Почему это даже необходимо? данные DPI используются для печати, а не для экранов. когда вы помещаете файл в папки ресурсов, вы определяете, какую плотность использовать для изображения ... –

+0

Мы создаем PDF-файлы, и мы используем DPI для определения размера изображения на странице. –

+0

public static int dpToPixels (контекстный контекст, float dp) { \t final float scale = context.getResources(). GetDisplayMetrics(). Плотность; \t return (int) (dp * scale + 0.5f); \t} – JRowan

ответ

0

согласно wikipedia, это то, как работает JPEG метаданных:

первые 2 байта 0xFFD8 (SOI, как указано here). то, если есть метаданные, вы получаете 0xFFE0 (2 байта)

Если есть метаданные, сегмент длины (2 байта) сегмент идентификатора (5 байтов: 0x4A46494600), то сегмент версии (2 байта) , то плотность:

единицы плотности 1 байт: 0 для не указано, 1 для PPI, 2 для PPC.

Затем вы получаете плотность x (2 байта) и плотность y (2 байта).

так, короче, вам нужно пропустить 2 + 2 + 2 + 5 + 2 = 13 байт, читать 1 байт для типа единиц плотности, а если это не 0, читать еще 4 байта для значений плотности (x и y).

надеюсь, что это может помочь.


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

final InputStream inputStream=getResources().openRawResource(R.raw.tt); 
try 
    { 
    inputStream.skip(13); 
    final int densityType=inputStream.read(); 
    switch(densityType) 
    { 
    case 0: 
     Log.d("DEBUG","no density specified"); 
     break; 
    case 1: 
     Log.d("DEBUG","density in PPI"); 
     break; 
    case 2: 
     Log.d("DEBUG","density in PPC"); 
     break; 
    } 
    if(densityType!=0) 
    { 
    final byte[] densityValue=new byte[2]; 
    inputStream.read(densityValue); 
    final int xDensity=(densityValue[0]<<8)+densityValue[1]; 
    inputStream.read(densityValue); 
    final int yDensity=(densityValue[0]<<8)+densityValue[1]; 
    Log.d("DEBUG","xDensity:"+xDensity+" yDensity:"+yDensity); 
    } 
    } 
catch(final IOException e) 
    {} 
try 
    { 
    inputStream.close(); 
    } 
catch(final IOException e) 
    {} 

EDIT: я думаю, что байты «длина», не следует игнорировать, поскольку они представляют собой «Длина сегмента за исключением APP0 маркер ", поэтому, если он слишком мал, вы не можете прочитать часть плотности и можете читать вещи, которые не имеют ничего общего с плотностью.

Надеюсь, вы действительно поняли смысл, и его не так сложно исправить.

+0

Ваш образец кода не будет работать для любого файла JPEG, потому что теги jpeg могут быть в любом порядке, и вы делаете плохое предположение о позиции данных. Маркер APP0 содержит информацию о плотности (DPI), но обычно она недействительна. – BitBank

+0

вот почему я написал, что если вы найдете что-то не так, сообщите мне, что измениться, чтобы исправить это. так как я не эксперт в том, как пишутся jpeg (и большинство типов файлов), все, что я сделал, читается с некоторых веб-сайтов и записывает пример кода. если вы знаете, как исправить код, пожалуйста, скажите мне. –

+0

Я в основном уже дал вам ответ. Вам нужно пройти цепочку меток JPEG и найти FFE0. Затем код будет работать со всеми файлами JPEG. – BitBank

 Смежные вопросы

  • Нет связанных вопросов^_^