Введение
Недавно я столкнулся с довольна интересной проблемой: при загрузке фотографий на сайт, с помощью php нужно было уменьшать картинки. Сделал, все хорошо работало, но почему-то попадались некоторые фотографии, которые при ресайзе сжимались не пропорционально. Для ресайза картинок использовал уже ни раз проверенную функцию, про которую уже писал. Начал анализировать исходные фотки, которые криво ресайзились и обнаружил, что все эти картинки имеют общее происхождение — они сделаны с мобильных устройств, работающие на платформе Android и IOS. Несколько часов помучив гугл, я так ни чего и не нашел на эту тему. Странно, но почему-то еще ни кто не описывал данную проблему. Пришлось разбираться самому.
Оказывается, что при создании фотки мобильные устройства записывают в EXIF-заголовки картинки очень много полезной информации, такой как гео-положение телефона во время съемки, время снимка, положения аппарата относительно горизонта, ширину и высоту кадра, информацию об устройстве и еще много чего полезного. Из всего этого мне понадобилось только три параметра — ширина и высота фотографии, и ориентация телефона во время съемки. На сколько я понял, телефон может иметь 8 положений, но независимо от расположения ширина и высота имеют одно и тоже значение. То есть при альбомной и книжной ориентации значения высоты и ширины не меняются. Из-за этого и возникали конфликты в при изменении размера. В php я получал ширину, а по факту это были размеры высоты или наоборот. Переварив всю эту информацию я написал две функции, которые позволяют правильно обрабатывать фотографии сделанные с мобильных устройств. Первая функция определяет высоту, ширину и угол, на который нужно повернуть фотографию. А вторая функция, осуществляет поворот картинки, приводя ее к виду, который php понимает и прекрасно обрабатывает.
Обработка фотографий сделанных с мобильных устройств. Код
Теперь приведу сам код функций.
// проверка фоток на то, что они сделаны с мобильного устройства // проверяем ориентацию фотки и если нужно вернем градус, на который нужно повернуть фото function getSizePhotoMobile($file_name){ // получаем EXIF-заголовки $exif_read_data = @exif_read_data($file_name); $size = @getimagesize($file_name); $width = $size[0]; $height = $size[1]; $degree = 0; // если заголовки получили, и среди них нашлось упоминание об ориентации if($exif_read_data){ if(isset($exif_read_data["Orientation"]) AND $exif_read_data["Orientation"] > 4){ $size = getimagesize($file_name, $info); $width = $size[1]; $height = $size[0]; switch ($exif_read_data["Orientation"]){ case 5: $degree = 270; break; case 6: $degree = 270; break; case 7: $degree = 90; break; case 8: $degree = 90; break; } } } return array( 0 => $width, 1 => $height, 'degree' => $degree ); }
function rotatePhotoMobile($img, $degree){ // получаем данные о картинке $size = getimagesize($img); //определяем тип (расширение) картинки $format = strtolower(substr($size['mime'], strpos($size['mime'], '/')+1)); $icfunc = "imagecreatefrom" . $format; //определение функции для расширения файла //если нет такой функции, то прекращаем работу скрипта if (!function_exists($icfunc)) return false; // Загрузка изображения $source = $icfunc($img); // Поворот. Пустые углы заливаем цветом 0xffffff $rotate = imagerotate($source, $degree, '0xd72630'); return $rotate; }
И простой пример использования:
$size = getSizePhotoMobile($source);//узнаем размеры исходной картинки // если это фото сделано с мобильного телефона if($size['degree'] > 0){ $photo = rotatePhotoMobile($source, $size['degree']); }else{ // код для обычных фоток }