From 337aef87ef141c767c106cbe2cec0a7c6914eeab Mon Sep 17 00:00:00 2001 From: rabuzarus Date: Wed, 30 Sep 2015 00:19:54 +0200 Subject: [PATCH 1/2] port of reds geotag feature --- include/Photo.php | 51 +++++++++++++++++++++++-------------------- include/features.php | 1 + include/photos.php | 27 +++++++++++++++++++++++ mod/photos.php | 52 ++++++++++++++++++++++++++++++++++++-------- 4 files changed, 98 insertions(+), 33 deletions(-) create mode 100644 include/photos.php diff --git a/include/Photo.php b/include/Photo.php index 785601c7e..9732801c9 100644 --- a/include/Photo.php +++ b/include/Photo.php @@ -345,38 +345,37 @@ class Photo { } public function orient($filename) { - if ($this->is_imagick()) { - // based off comment on http://php.net/manual/en/imagick.getimageorientation.php - $orientation = $this->image->getImageOrientation(); - switch ($orientation) { - case imagick::ORIENTATION_BOTTOMRIGHT: - $this->image->rotateimage("#000", 180); - break; - case imagick::ORIENTATION_RIGHTTOP: - $this->image->rotateimage("#000", 90); - break; - case imagick::ORIENTATION_LEFTBOTTOM: - $this->image->rotateimage("#000", -90); - break; - } + if ($this->is_imagick()) { + // based off comment on http://php.net/manual/en/imagick.getimageorientation.php + $orientation = $this->image->getImageOrientation(); + switch ($orientation) { + case imagick::ORIENTATION_BOTTOMRIGHT: + $this->image->rotateimage("#000", 180); + break; + case imagick::ORIENTATION_RIGHTTOP: + $this->image->rotateimage("#000", 90); + break; + case imagick::ORIENTATION_LEFTBOTTOM: + $this->image->rotateimage("#000", -90); + break; + } - $this->image->setImageOrientation(imagick::ORIENTATION_TOPLEFT); - return TRUE; - } + $this->image->setImageOrientation(imagick::ORIENTATION_TOPLEFT); + return TRUE; + } // based off comment on http://php.net/manual/en/function.imagerotate.php if(!$this->is_valid()) - return FALSE; + return FALSE; if( (! function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg') ) - return; + return; - $exif = @exif_read_data($filename); + $exif = @exif_read_data($filename,null,true); + if(! $exif) + return; - if(! $exif) - return; - - $ort = $exif['Orientation']; + $ort = $exif['IFD0']['Orientation']; switch($ort) { @@ -413,6 +412,10 @@ class Photo { $this->rotate(90); break; } + + // logger('exif: ' . print_r($exif,true)); + return $exif; + } diff --git a/include/features.php b/include/features.php index 091dfc6e9..5450c7fab 100644 --- a/include/features.php +++ b/include/features.php @@ -23,6 +23,7 @@ function get_features() { t('General Features'), //array('expire', t('Content Expiration'), t('Remove old posts/comments after a period of time')), array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles')), + array('photo_location', t('Photo Location'), t('Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map.'),false), ), // Post composition diff --git a/include/photos.php b/include/photos.php new file mode 100644 index 000000000..93a565b51 --- /dev/null +++ b/include/photos.php @@ -0,0 +1,27 @@ + 0 ? gps2Num($exifCoord[0]) : 0; + $minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0; + $seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0; + + $flip = ($hemi == 'W' or $hemi == 'S') ? -1 : 1; + + return floatval($flip * ($degrees + ($minutes / 60) + ($seconds / 3600))); +} + +function gps2Num($coordPart) { + $parts = explode('/', $coordPart); + + if (count($parts) <= 0) + return 0; + + if (count($parts) == 1) + return $parts[0]; + + return floatval($parts[0]) / floatval($parts[1]); +} diff --git a/mod/photos.php b/mod/photos.php index 3d3b92a46..e911c6505 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -1,5 +1,6 @@ get_baseurl() . '/' . $_SESSION['photo_return']); } + /* + * RENAME photo album + */ + $newalbum = notags(trim($_POST['albumname'])); if($newalbum != $album) { q("UPDATE `photo` SET `album` = '%s' WHERE `album` = '%s' AND `uid` = %d", @@ -206,6 +211,9 @@ function photos_post(&$a) { return; // NOTREACHED } + /* + * DELETE photo album and all its photos + */ if($_POST['dropalbum'] == t('Delete Album')) { @@ -534,12 +542,12 @@ function photos_post(&$a) { if(count($links)) { foreach($links as $link) { if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') - $profile = $link['@attributes']['href']; + $profile = $link['@attributes']['href']; if($link['@attributes']['rel'] === 'salmon') { $salmon = '$url:' . str_replace(',','%sc',$link['@attributes']['href']); if(strlen($inform)) $inform .= ','; - $inform .= $salmon; + $inform .= $salmon; } } } @@ -833,7 +841,7 @@ function photos_post(&$a) { killme(); } - $ph->orient($src); + $exif = $ph->orient($src); @unlink($src); $max_length = get_config('system','max_image_length'); @@ -874,8 +882,20 @@ function photos_post(&$a) { // Create item container + $lat = $lon = null; + + if($exif && $exif['GPS']) { + if(feature_enabled($channel_id,'photo_location')) { + $lat = getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']); + $lon = getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']); + } + } + $arr = array(); + if($lat && $lon) + $arr['coord'] = $lat . ' ' . $lon; + $arr['uid'] = $page_owner_uid; $arr['uri'] = $uri; $arr['parent-uri'] = $uri; @@ -1062,10 +1082,9 @@ function photos_content(&$a) { $_is_owner = (local_user() && (local_user() == $owner_uid)); $o .= profile_tabs($a,$_is_owner, $a->data['user']['nickname']); - // - // dispatch request - // - + /** + * Display upload form + */ if($datatype === 'upload') { if(! ($can_post)) { @@ -1176,6 +1195,10 @@ function photos_content(&$a) { return $o; } + /* + * Display a single photo album + */ + if($datatype === 'album') { $album = hex2bin($datum); @@ -1203,6 +1226,7 @@ function photos_content(&$a) { intval($a->pager['itemspage']) ); + //edit album name if($cmd === 'edit') { if(($album !== t('Profile Photos')) && ($album !== 'Contact Photos') && ($album !== t('Contact Photos'))) { if($can_post) { @@ -1290,11 +1314,12 @@ function photos_content(&$a) { } + /** + * Display one photo + */ if($datatype === 'image') { - - //$o = ''; // fetch image, item containing image, then comments @@ -1418,6 +1443,9 @@ function photos_content(&$a) { $linked_items = q("SELECT * FROM `item` WHERE `resource-id` = '%s' $sql_extra LIMIT 1", dbesc($datum) ); + + $map = null; + if(count($linked_items)) { $link_item = $linked_items[0]; $r = q("SELECT COUNT(*) AS `total` @@ -1461,6 +1489,10 @@ function photos_content(&$a) { ); update_thread($link_item['parent']); } + + if($link_item['coord']) { + $map = generate_map($link_item['coord']); + } } $tags=Null; @@ -1753,6 +1785,8 @@ function photos_content(&$a) { '$desc' => $ph[0]['desc'], '$tags' => $tags_e, '$edit' => $edit, + '$map' => $map, + '$map_text' => t('Map'), '$likebuttons' => $likebuttons, '$like' => $like_e, '$dislike' => $dikslike_e, From 8e1564965df15d707547e2c3749df28143a1429b Mon Sep 17 00:00:00 2001 From: rabuzarus <> Date: Wed, 30 Sep 2015 12:33:57 +0200 Subject: [PATCH 2/2] port of reds geotag feature --- include/Photo.php | 51 +++++++++++++++++++++++--------------------- include/features.php | 1 + include/photos.php | 27 +++++++++++++++++++++++ mod/photos.php | 48 +++++++++++++++++++++++++++++++++++------ 4 files changed, 96 insertions(+), 31 deletions(-) create mode 100644 include/photos.php diff --git a/include/Photo.php b/include/Photo.php index 785601c7e..9732801c9 100644 --- a/include/Photo.php +++ b/include/Photo.php @@ -345,38 +345,37 @@ class Photo { } public function orient($filename) { - if ($this->is_imagick()) { - // based off comment on http://php.net/manual/en/imagick.getimageorientation.php - $orientation = $this->image->getImageOrientation(); - switch ($orientation) { - case imagick::ORIENTATION_BOTTOMRIGHT: - $this->image->rotateimage("#000", 180); - break; - case imagick::ORIENTATION_RIGHTTOP: - $this->image->rotateimage("#000", 90); - break; - case imagick::ORIENTATION_LEFTBOTTOM: - $this->image->rotateimage("#000", -90); - break; - } + if ($this->is_imagick()) { + // based off comment on http://php.net/manual/en/imagick.getimageorientation.php + $orientation = $this->image->getImageOrientation(); + switch ($orientation) { + case imagick::ORIENTATION_BOTTOMRIGHT: + $this->image->rotateimage("#000", 180); + break; + case imagick::ORIENTATION_RIGHTTOP: + $this->image->rotateimage("#000", 90); + break; + case imagick::ORIENTATION_LEFTBOTTOM: + $this->image->rotateimage("#000", -90); + break; + } - $this->image->setImageOrientation(imagick::ORIENTATION_TOPLEFT); - return TRUE; - } + $this->image->setImageOrientation(imagick::ORIENTATION_TOPLEFT); + return TRUE; + } // based off comment on http://php.net/manual/en/function.imagerotate.php if(!$this->is_valid()) - return FALSE; + return FALSE; if( (! function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg') ) - return; + return; - $exif = @exif_read_data($filename); + $exif = @exif_read_data($filename,null,true); + if(! $exif) + return; - if(! $exif) - return; - - $ort = $exif['Orientation']; + $ort = $exif['IFD0']['Orientation']; switch($ort) { @@ -413,6 +412,10 @@ class Photo { $this->rotate(90); break; } + + // logger('exif: ' . print_r($exif,true)); + return $exif; + } diff --git a/include/features.php b/include/features.php index 091dfc6e9..5450c7fab 100644 --- a/include/features.php +++ b/include/features.php @@ -23,6 +23,7 @@ function get_features() { t('General Features'), //array('expire', t('Content Expiration'), t('Remove old posts/comments after a period of time')), array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles')), + array('photo_location', t('Photo Location'), t('Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map.'),false), ), // Post composition diff --git a/include/photos.php b/include/photos.php new file mode 100644 index 000000000..93a565b51 --- /dev/null +++ b/include/photos.php @@ -0,0 +1,27 @@ + 0 ? gps2Num($exifCoord[0]) : 0; + $minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0; + $seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0; + + $flip = ($hemi == 'W' or $hemi == 'S') ? -1 : 1; + + return floatval($flip * ($degrees + ($minutes / 60) + ($seconds / 3600))); +} + +function gps2Num($coordPart) { + $parts = explode('/', $coordPart); + + if (count($parts) <= 0) + return 0; + + if (count($parts) == 1) + return $parts[0]; + + return floatval($parts[0]) / floatval($parts[1]); +} diff --git a/mod/photos.php b/mod/photos.php index a19cfaaa7..834fab33f 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -1,5 +1,6 @@ get_baseurl() . '/' . $_SESSION['photo_return']); } + /* + * RENAME photo album + */ + $newalbum = notags(trim($_POST['albumname'])); if($newalbum != $album) { q("UPDATE `photo` SET `album` = '%s' WHERE `album` = '%s' AND `uid` = %d", @@ -210,6 +215,9 @@ function photos_post(&$a) { return; // NOTREACHED } + /* + * DELETE photo album and all its photos + */ if($_POST['dropalbum'] == t('Delete Album')) { @@ -837,7 +845,7 @@ function photos_post(&$a) { killme(); } - $ph->orient($src); + $exif = $ph->orient($src); @unlink($src); $max_length = get_config('system','max_image_length'); @@ -878,8 +886,20 @@ function photos_post(&$a) { // Create item container + $lat = $lon = null; + + if($exif && $exif['GPS']) { + if(feature_enabled($channel_id,'photo_location')) { + $lat = getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']); + $lon = getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']); + } + } + $arr = array(); + if($lat && $lon) + $arr['coord'] = $lat . ' ' . $lon; + $arr['uid'] = $page_owner_uid; $arr['uri'] = $uri; $arr['parent-uri'] = $uri; @@ -1066,10 +1086,9 @@ function photos_content(&$a) { $is_owner = (local_user() && (local_user() == $owner_uid)); $o .= profile_tabs($a,$is_owner, $a->data['user']['nickname']); - // - // dispatch request - // - + /** + * Display upload form + */ if($datatype === 'upload') { if(! ($can_post)) { @@ -1180,6 +1199,10 @@ function photos_content(&$a) { return $o; } + /* + * Display a single photo album + */ + if($datatype === 'album') { $album = hex2bin($datum); @@ -1207,6 +1230,7 @@ function photos_content(&$a) { intval($a->pager['itemspage']) ); + //edit album name if($cmd === 'edit') { if(($album !== t('Profile Photos')) && ($album !== 'Contact Photos') && ($album !== t('Contact Photos'))) { if($can_post) { @@ -1294,11 +1318,12 @@ function photos_content(&$a) { } + /** + * Display one photo + */ if($datatype === 'image') { - - //$o = ''; // fetch image, item containing image, then comments @@ -1422,6 +1447,9 @@ function photos_content(&$a) { $linked_items = q("SELECT * FROM `item` WHERE `resource-id` = '%s' $sql_extra LIMIT 1", dbesc($datum) ); + + $map = null; + if(count($linked_items)) { $link_item = $linked_items[0]; $r = q("SELECT COUNT(*) AS `total` @@ -1465,6 +1493,10 @@ function photos_content(&$a) { ); update_thread($link_item['parent']); } + + if($link_item['coord']) { + $map = generate_map($link_item['coord']); + } } $tags=Null; @@ -1757,6 +1789,8 @@ function photos_content(&$a) { '$desc' => $ph[0]['desc'], '$tags' => $tags_e, '$edit' => $edit, + '$map' => $map, + '$map_text' => t('Map'), '$likebuttons' => $likebuttons, '$like' => $like_e, '$dislike' => $dikslike_e,