Как средствами PHP получить Resolution (разрешение) изображения?

Kox

Новичок
Как средствами PHP получить Resolution (разрешение) изображения?

Доброго всем времени суток! Суть в следующем.
Пользователь загружает файлы картинок (jpeg, tiff) на сервер через php-скрипт. С помощью getimagesize() я получаю ширину и высоту в пикселях.
Но мне надо знать реальный размер изображения в сантиметрах.
Его я могу вычислить, зная разрешение (resolution - pixel/cm), по формуле:
Ширина/resolution = реальная ширина в сантиметрах. С длиной также.

Влпрос: Как узнать Resolution? Всем заранее спасибо.
 

whirlwind

TDD infected, paranoid
> Как узнать Resolution?
никак. в зависимости от того на чем смотрят. почитай у Темы Лебедева там есть что то про типовые стандарты.
 

Kox

Новичок
Автор оригинала: whirlwind
никак. в зависимости от того на чем смотрят. почитай у Темы Лебедева там есть что то про типовые стандарты.
В смысле на чем смотрят? Есть файл, например, TEST.JPG. Он в своих заголовках или еще где-то (не силен, к сожалению) несет в себе инфу о изображении. Это и Width, и Height, и Resolution наверное. И если getimagesize() может извлечь длину и ширину, то возможно какая-то другая функция может извлечь и DPI
 

whirlwind

TDD infected, paranoid
>В смысле на чем смотрят?

DPI тебе и нужен. На 17" 1024x768 у тебя одно DPI, а на 19" другое. В некоторых растровых форматах есть поля, которые позволяют рассчитать DPI (например BMP), но они почти всегда не актуальны. Почитай у лебедева там где то статья в куроводстве про пункты, переводы в DPI и все такое, может найдешь наиболее подходящий для себя метод.
 

Kox

Новичок
Автор оригинала: whirlwind
>DPI тебе и нужен.

To whirlwind: Сорри за неправильную терминологию. Нужно именно Resolution, а не DPI. Причем это нужно не для вывода на экран, а именно для вычисления свойств файла. Опишу проблему более детально:
Пользователь через мой скрипт загружает файл - изображение. Этот рисунок - его рекламный блок. Дальше мой скрипт отправляет этот файл в газету, где он (рекл. блок) должен быть напечатан. В газете жесткие требования к размерам блоков (ширина х высота) в мм. Мне надо точно знать, что файл, который загружает пользователь, устроит верстальщика этой газеты. А у верстальщика требования такие - размер блока например 100 х 50 мм.
Еще детальнее:
Файл размером 1000х500 пикселей. Его Resolution - 100 пикс/см. Реальный размер - 10х5 см. Все ок - подходит.
Файл размером 1000х500 пикселей. Его Resolution - 200 пикс/см. Реальный размер - 5х2,5 см. Ошибка - не подходит.

Не зависимо от Резолюции экрана размеры файлов в САНТИМЕТРАХ останутся такими же.

-~{}~ 23.11.06 13:19:

Автор оригинала: Bermuda
Для jpeg можно найти кое-что интересное в заголовке EXIF.
К сожалению, сервер хостера не сконфигурирован для работы с заголовками EXIF.

Но все равно спасибо за участие!
 

whirlwind

TDD infected, paranoid
> А у верстальщика требования такие - размер блока например 100 х 50 мм.

Могу посоветовать опираться на aspect ratio. Т.е. у тебя например есть конкретные величины аспекта для различных блоков (100/50 = 2), пользователь на сайте выбирает тип блока, ему показывается величина аспекта и рекомендуемые разрешения в пикселях. При загрузке, если это не рекомендуемое разрешение, но аспект соответствует (w/h = 2), просто масштабируешь картинку.

-~{}~ 23.11.06 14:04:

ЗЫ. повторяю - DPI то что тебе нужно (http://ru.wikipedia.org/wiki/DPI), но в других единицах. Просто в обычных растровых форматах он не используется. Если верстальщику отправляется какой нить psd или в векторе, это другое дело. Тут я уже не посоветую как из джпега конвертнуть, но если это сделать, то и разрешение указать сможешь. А указать ты его сможешь любой, главное что бы аспект соответствовал блокам.
 

Kox

Новичок
Спасибо за Аспект! Приятно разговаривать с умными людьми.
Но тут возможны варианты:
Аспект 100х50 = 2. и аспект 50х25 тоже =2.

Пользователь, к сожалению, далек ваще от технологий - мой босс. И файл изображения получает от дизайнера - третьего лица. Чем меньше я предоставлю пользователю вариантов выбора - тем меньше он ошибок допустит. И тем проще ему будет и он тем больше будет доволен. Получил файл от дизайнера - нажал кнопку ДОБАВИТЬ ФАЙЛ - мой скрипт закачал файл на сервер, вычислил его размеры (ШхВ мм) - сравнил с текущим медиа-планом - каким газетам нужен блок именно такого размера - и отправил. Все довольны.
 

whirlwind

TDD infected, paranoid
>Но тут возможны варианты:
Аспект 100х50 = 2. и аспект 50х25 тоже =2.

Ну да, правильно. Пропорции сохраняются, но при масштабировании 50x25 до 100х50 качество очень сильно пострадает. Значит помимо аспекта, для блока нужно добавить еще такой параметр как минимальное разрешение в пикселях (достаточно одного числа, например ширины). Т.е. при попытке загрузить 50х25 сказать пользователю что мол нельзя такое грузить.
 

Kox

Новичок
Мы говорим о размерах в миллиметрах. 50х25 мм - один из распространенных форматов рекламных объявлений. Открой любую газету. Другое дело - резолюшн. 50х25 (300 пикс/см) - нормально. 50х25 (72 пикс/см) - так себе. 50х25 (20 пикс/см) - плохо.
Мой скрипт не масштабирует изображения - просто сверяет размер в миллиметрах (или сантиметрах) - и отправляет. Файл изображения остается нетронутым.

Т.е. исходные данные - размер в пикселях. Вычисляю через getimagesize.
Результат нужен - размер в миллиметрах (сантиметрах). Поэтому и зацепился за Резолюшн.
 

whirlwind

TDD infected, paranoid
>Мы говорим о размерах в миллиметрах.

Какая разница? Пиксели - это относительные размеры, а миллимитры абсолютные. Все зависит от величины пикселя, который еще и не во всех случаях квадратный.

Вот смотри в гифе http://www.onicos.com/staff/iz/formats/gif.html нет ничего про _абсолютное_ разрешение, а в bmp http://local.wasp.uwa.edu.au/~pbourke/dataformats/bmp/ есть. Про jpeg тебе уже сказали. Но если графический формат не предусматривает расчет DPI то ты хоть тресни - его не узнаешь. По этому я и говорю, что проверить DPI нельзя. А принципиально это не важно. Если у тебя 50x25 цветных квадратиков, то ты никак не можешь сделать из этой картинки 100x50 без потери качества. По этому абсолютные величины не важны - возьми и напиши для своего случая 50x20x20пикс/см что у него не 20пикс/см, а 20000пикс/см - качество этой конкретной картинки не изменится, изменится только ее размер на бумаге с соответствующими последствиями.
 

Kox

Новичок
>По этому абсолютные величины не важны

Не злись.
Как раз для меня важны абсолютные величины.
Ок, оторвемся от ДПИ.
50x25 цветных квадратиков никто не собирается масштабировать - ни я, не верстальщик. Как вычислить абсолютные размеры, зная относительные?
 

С.

Продвинутый новичок
Kox, в картинках для веба НЕТ абсолютных размеров (кроме пикселей). Все выдается в разрешении 72 dpi, а абсолютный размер будет зависеть от характеристик и настроек монитора.

-~{}~ 23.11.06 18:18:

50х25 мм - один из распространенных форматов рекламных объявлений. Открой любую газету.
В вебе один из распространненых форматов рекламных объявлений 468х60 пикселей(!). Открой любой сайт.
 

Kox

Новичок
С. , мне эта картика не для веба нужна, а для печати на бумаге. В газете. Бумажной. Поэтому мне важен абсолютный размер - именно в миллиметрах или сантиметрах. Каринки одинакового размера - например 1000х500 пикселей (!!! - пикселей) на бумаге будут выглядеть по-разному.
 

С.

Продвинутый новичок
У тебя типогрaфия какие требования к изображениям предъявляет? 300 dpi? 350 dpi?

Если ширина 50 мм при 300 dpi, сколько пикселей в ширине будет? Помочь?
 

betik

Новичок
Автор оригинала: Kox
Каринки одинакового размера - например 1000х500 пикселей (!!! - пикселей) на бумаге будут выглядеть по-разному.
Как так?

А вообще,насколько мне известно, для печати из веб-совместимых (вроде) принимается только TIFF.
И никто не печатает из джепегов.
 

whirlwind

TDD infected, paranoid
>А вообще,насколько мне известно, для печати из веб-совместимых (вроде) принимается только TIFF

ну вот скорее всего так и есть

XResolution (282) = 204, 200, 300, 400, 408 (inches). RATIONAL.
The horizontal resolution of the TIFF-F image expressed in pixels
per resolution unit. The values of 200 and 408 have been added to
the historical TIFF-F values, for consistency with [T.30]. Some
existing TIFF-F implementations may also support values of 77
(cm). See section 3.8.2 for more information on inch/metric
equivalencies and other implementation details.

YResolution (283) = 98, 196, 100, 200, 300, 391, 400 (inches).
RATIONAL.
The vertical resolution of the TIFF-F image expressed in pixels
per resolution unit. The values of 100, 200, and 391 have been
added to the historical TIFF-F values, for consistency with
[T.30]. Some existing TIFF-F implementations may also support
values of 77, 38.5 (cm). See section 3.8.2 for more information
on inch/metric equivalencies and other implementation details.
http://www.ietf.org/rfc/rfc2306.txt
 

С.

Продвинутый новичок
В наши дни принимается все, что не попадя. Просто при рендеринге все конвертируется и ресамплируется в стандратные форматы и разрешения.

Kox, если тебе надо информацию из заголовков файлов, какого они метрического размера, то ищи спецификацию формата заголовков и парси их. Но учти два момента:

1. Не-полиграфические форматы (как JPEG) могут не содержать такой информации вообще. Например картинка с цифровой камеры какого размера выходит?

2. Надеяться, что клиент даст файл с правильно установленными размерами и разрешением - очень неосмотрительно. По моей статистике только один из десятка это может сделать. Треть даже пропорции сторон не может соблюсти. Половина вообще не знает как можно сделать картинку и скинет тебе Ворд файл.
 

Kox

Новичок
Спасибо всем за советы!
Отвечаю (возражаю) всем по порядку.
To С.: В медиа-плане больше сотни газет. У каждой требования к макету разные. Необходимые параметры - Ширина(мм) х Высота(мм) х DPI. Все это учитывает дизайнер, когда рисует. Естественно он не скинет мне Ворд файл.
А по поводу картинки с цифро-камеры: ее Реальный размер на бумаге - Ширина(пикс)/DPI. С длиной также.

To whirlwind: Ты стопроцентно прав, в основном это ТИФФ. Но некоторым нужен JPEG почему-то.

Еще момент. Допустим есть файл TEST.jpg.
Прямо в Виндовс, выделить его - Свойства - Сводка - Дополнительно. Что видим: Ширина, Высота, Разрешение по вертикали, Разрешение по горизонтали. Значит файл несет в себе инфу о DPI. Значит можно ее достать

-~{}~ 24.11.06 18:26:

Автор оригинала: betik
Как так?
Файл размером 1000х500 пикселей. Его Resolution - 100 пикс/см. Реальный размер - 10х5 см.
Файл размером 1000х500 пикселей. Его Resolution - 200 пикс/см. Реальный размер - 5х2,5 см.
 

С.

Продвинутый новичок
Автор оригинала: С.
тебе надо информацию из заголовков файлов ... ищи спецификацию формата заголовков и парси их.
-~{}~ 25.11.06 05:53:

http://www.w3.org/Graphics/JPEG/jfif.txt

-~{}~ 25.11.06 05:57:

Вот коротенькая функция, которая собирает информацию из JPEG заголовков. Я написал ее давно и по каким-то соображениям там нет разрешения. Если хочешь, то доработай на основании спецификации.

PHP:
<?
   define('HEADER_MIN',300);
   function get_image_info($filename)
   {
      $res=array('type'=>'undefined');
      $res['size']= filesize($filename);
      $header=HEADER_MIN;
      for ($trial=1; $trial<=2 && !isset($res['width']); $trial++)
      {
         $f= fopen($filename,'rb');
         if (!$f) return false;
         $buff= fread($f,$header);
         fclose($f);
         if (bin2hex(substr($buff,0,2))!='ffd8') return $res;
         $res['type']='jpeg';
         $offset=2;
         while ($offset<$header)
         {
            $segment=bin2hex(substr($buff,$offset,2));
            $segment_size= intval(bin2hex(substr($buff,$offset+2,2)),16);
            switch ($segment)
            {
            case 'ffc0':
            case 'ffc1':
            case 'ffc2':
            case 'ffc3':
               $res['segments'][]= array(
                  'marker'=>$segment,
                  'size'=>$segment_size,
                  'offset'=>$offset,
                  'height'=>$res['height']=intval(bin2hex(substr($buff,$offset+5,2)),16),
                  'width'=>$res['width']=intval(bin2hex(substr($buff,$offset+7,2)),16),
               );
               break;
            case 'fffe':
               $res['note']=substr($buff,$offset+4,$segment_size-2);
               break;
            }
            $offset+= 2+$segment_size;
         }
         $header=$res['size'];
         $res['trials']=$trial;
      }
      return $res;
   }
?>
 
Сверху