Patch for loading EXIF data on image upload
"Heath S. Hendrickson" <[email protected]>
| Newsgroups | gmane.comp.horde.ansel |
|---|---|
| Message-ID | <[email protected]> |
Attached is a super patch that patches the following files: image.php (NOTE: patch for watermark mods is also included in here...) lib/Exif.php templates/view/exif_image.inc templates/image/exif.inc Also included is a new file: templates/image/exifFields.inc The patches add the requested TODO capability of writing the EXIF data to the datatree backend on image upload... I set an additional flag of "Exif" to signal that the images Exif data had already been processed and written... this way the system can automatically determine if the data is in datatree or if it needs to try and read it from the image. At some point it may be worthwhile to write a CLI script to process all images in all galleries and write the EXIF data to the datatree, but it's not critical as I left in the ability to continue reading it from the file. What may be more important is to have it write the data (if not already there) before committing any edits to the image file. That would keep from losing the data before it's too late. As an FYI, the EXIF fields that are written to the datatree are all maintained in the new template file (I stripped it out of lib/Exif.php to make it one file to maintain so it can be reused elsewhere if desired). I tried to make it have scope over the entire Ansel_ImageData class, but you can't have assignments outside of a function (the getText stuff) and putting it in a constructor wasn't working. h -- ansel mailing list - Join the hunt: http://horde.org/bounties/#ansel Frequently Asked Questions: http://horde.org/faq/ To unsubscribe, mail: [email protected]
exif_to_datatree_on_upload.patch
(text/plain, 12.2 KB)
Index: lib/Exif.php
===================================================================
RCS file: /usr/local/horde/cvs/ansel/lib/Exif.php,v
retrieving revision 1.7
diff -u -r1.7 Exif.php
--- lib/Exif.php 25 Jan 2004 04:32:33 -0000 1.7
+++ lib/Exif.php 23 Mar 2004 03:14:04 -0000
@@ -5,45 +5,18 @@
* $Horde: ansel/lib/Exif.php,v 1.6 2004/01/19 22:37:54 chuck Exp $
*/
class Ansel_ImageData {
-
+
function readAttributes(&$image)
{
+ require ANSEL_TEMPLATES . '/image/exifFields.inc';
+
$imageFile = $image->toFile();
$result = get_exif_data($imageFile);
+ $output = array();
if ($result) {
- // Array of EXIF fields to populate.
- // The key is the Exif field name, the value is the display name.
- $ExifFields = array('Make' => _('Camera Make'),
- 'Model' => _('Camera Model'),
- 'ImageType' => _('Image Type'),
- 'FileSize' => _('File Size'),
- 'DateTime' => _('Image Taken'),
- 'ExifImageWidth' => _('Width'),
- 'ExifImageLength' => _('Height'),
- 'XResolution' => _('X Resolution'),
- 'YResolution' => _('Y Resolution'),
- 'ShutterSpeedValue' => _('Shutter Speed'),
- 'ExposureTime' => _('Exposure'),
- 'FocalLength' => _('Focal Length'),
- 'ApertureValue' => _('Aperture'),
- 'FNumber' => _('F-Number'),
- 'ISOSpeedRatings' => _('ISO Setting'),
- 'ExposureBiasValue' => _('Exposure Bias'),
- 'ExposureMode' => _('Exposure Mode'),
- 'MeteringMode' => _('Metering Mode'),
- 'Flash' => _('Flash Setting'),
- 'UserComment' => _('User Comment'),
- 'ColorSpace' => _('Color Space'),
- 'SensingMethod' => _('Sensing Method'),
- 'WhiteBalance' => _('White Balance'),
- 'Orientation' => _('Camera Orientation'),
- 'Copyright' => _('Copyright')
- );
- $output = array();
- $keys = array();
foreach ($ExifFields as $field => $desc) {
- array_key_exists($field, $result) ? $data = $result[$field] : $data = '';
+ $data = array_key_exists($field, $result) ? $result[$field] : '';
if (trim($data) == '') {
continue;
}
@@ -56,6 +29,72 @@
return $output;
}
+ /**
+ * Get the image attributes from the datatree backend.
+ *
+ * @param object DataTreeObject_Image &$image a reference to the image
+ *
+ * @return array $output the formated output of the EXIF data
+ */
+ function getAttributes(&$image)
+ {
+ // get the EXIF fields to handle
+ require ANSEL_TEMPLATES . '/image/exifFields.inc';
+ $output = array();
+
+ foreach ($ExifFields as $field => $desc) {
+ $data = $image->get($field);
+ // make sure it's not an empty field, as this does happen
+ if (trim($data) == '') {
+ continue;
+ }
+ $output[] = "<td class='item'><b>$desc</b>:</td<td class='item'>$data</td>";
+ }
+ return $output;
+ }
+
+ /**
+ * Write the image EXIF data to the datatree backend as a series
+ * of attributes. The EXIF data being handled is driven by the
+ * multi-dimensional array set up in templates/image/exifFields.inc.
+ *
+ * @param object DataTreeObject_Image &$image a reference to the image
+ *
+ */
+ function setExifData(&$image)
+ {
+ // get the EXIF fields to handle
+ require ANSEL_TEMPLATES . '/image/exifFields.inc';
+
+ // Unfortunately, the PHP function requires a file, not a stream
+ $imageFile = $image->toFile();
+ $result = get_exif_data($imageFile);
+
+ // see if we got anything from the image file
+ if ($result) {
+
+ // it's easier and faster to work from the fields we know
+ // about instead of all the possible fields stored in the
+ // image file
+ foreach ($ExifFields as $field => $desc) {
+ $data = array_key_exists($field, $result) ? $result[$field] : '';
+ // make sure it's not an empty field, as this does happen
+ if (trim($data) == '') {
+ continue;
+ }
+ // convert the data to something meaningful
+ if (function_exists('exif_read_data')) {
+ $data = convert_exif_data($field, $data);
+ }
+ // write it to the datatree backend, forcing the update
+ $image->set($field, $data, true);
+ }
+ // set a marker that we have the EXIF data available in the
+ // datatree backend so we don't have to read it from the file
+ // again.
+ $image->set('Exif', 1, true);
+ }
+ }
}
//================================================================================================
Index: templates/view/exif-image.inc
===================================================================
RCS file: /usr/local/horde/cvs/ansel/templates/view/exif-image.inc,v
retrieving revision 1.3
diff -u -r1.3 exif-image.inc
--- templates/view/exif-image.inc 25 Jan 2004 19:11:32 -0000 1.3
+++ templates/view/exif-image.inc 23 Mar 2004 03:15:22 -0000
@@ -1,5 +1,11 @@
<?php
-$output = @Ansel_ImageData::readAttributes($image);
+// see of the EXIF data is in the datatree backend, otherwise
+// we have to read it from the file itself.
+if ($image->get('Exif')) {
+ $output = @Ansel_ImageData::getAttributes($image);
+} else {
+ $output = @Ansel_ImageData::readAttributes($image);
+}
if (count($output)) {
$newout = array_chunk($output, 3);
echo '<br /><div align="center"><table border="0" cellpadding="2" cellspacing="0" class="item">';
Index: templates/image/exif.inc
===================================================================
RCS file: /usr/local/horde/cvs/ansel/templates/image/exif.inc,v
retrieving revision 1.6
diff -u -r1.6 exif.inc
--- templates/image/exif.inc 25 Jan 2004 19:11:31 -0000 1.6
+++ templates/image/exif.inc 23 Mar 2004 03:15:34 -0000
@@ -6,7 +6,13 @@
</table>
<?php
-$output = @Ansel_ImageData::readAttributes($image);
+// see of the EXIF data is in the datatree backend, otherwise
+// we have to read it from the file itself.
+if ($image->get('Exif')) {
+ $output = @Ansel_ImageData::getAttributes($image);
+} else {
+ $output = @Ansel_ImageData::readAttributes($image);
+}
if (!count($output)) {
$out = '<td colspan="2" class="text"><i>' . _("No embedded information found.") . '</i></td>';
} else {
Index: image.php
===================================================================
RCS file: /usr/local/horde/cvs/ansel/image.php,v
retrieving revision 1.68
diff -u -r1.68 image.php
--- image.php 16 Mar 2004 02:51:17 -0000 1.68
+++ image.php 22 Mar 2004 22:10:05 -0000
@@ -10,6 +10,7 @@
define('ANSEL_BASE', dirname(__FILE__));
require_once ANSEL_BASE . '/lib/base.php';
+require_once ANSEL_BASE . '/lib/Exif.php';
require_once HORDE_LIBS . 'Horde/Form.php';
require_once HORDE_LIBS . 'Horde/Form/Renderer.php';
require_once HORDE_LIBS . 'Horde/Text.php';
@@ -100,6 +101,23 @@
$w = &$this->addVariable(_("Custom Watermark"), 'watermark', 'text', false, false, null);
$w->setDefault($prefs->getValue('watermark'));
+
+ $fonts = array('tiny' => _("Tiny"),'small' => _("Small"),'medium' => _("Medium"),'large' => _("Large"),'giant' => _("Giant"));
+ $f = &$this->addVariable(_("Watermark Font"), 'font', 'enum', false, false, null, array($fonts));
+ if ($prefs->getValue('font')) {
+ $default_font = $prefs->getValue('font');
+ } else {
+ $default_font = 'small';
+ }
+ $f->setDefault($default_font);
+
+ $ha = array( 'left' => _('Left'), 'center' => _("Center"), 'right' => _("Right") );
+ $wha = &$this->addVariable(_("Horizontal Alignment"), 'whalign', 'enum', false, false, null, array($ha));
+ $wha->setDefault('right');
+
+ $va = array( 'top' => _('Top'), 'middle' => _("Middle"), 'bottom' => _("Bottom") );
+ $wva = &$this->addVariable(_("Vertical Alignment"), 'wvalign', 'enum', false, false, null, array($va));
+ $wva->setDefault('bottom');
}
}
@@ -108,7 +126,24 @@
$gallery_id = Util::getFormData('gallery');
$image_id = Util::getFormData('image');
$watermark = Util::getFormData('watermark', $prefs->getValue('watermark'));
+$watermark_halign = Util::getFormData('whalign');
+$watermark_valign = Util::getFormData('wvalign');
+//$watermark_transp = Util::getFormData('wtransp');
+if (isset($watermark)) {
+ require_once HORDE_LIBS . 'Horde/Identity.php';
+ $identity = &Identity::singleton();
+ $name = $identity->getValue('fullname');
+ if (empty($name)) {
+ $name = Auth::getAuth();
+ }
+ // set up array of possible substitutions
+ $watermark_array = array('%N' => $name, // Users fullname
+ '%L' => Auth::getAuth()); // user login
+ $watermark = strftime( $watermark );
+ $watermark = str_replace(array_keys($watermark_array), array_values($watermark_array), $watermark);
+}
$page = Util::getFormData('page', 0);
+$watermark_font = Util::getFormData('font');
/* Redirect to the image list if no action has been requested. */
if (is_null($actionID)) {
@@ -240,6 +275,8 @@
);
$image_id = $gallery->addImage($image);
if (!is_a($image_id, 'PEAR_Error')) {
+ $tmp = &$ansel_shares->getImage($image_id);
+ @Ansel_ImageData::setExifData($tmp);
$success++;
} else {
$notification->push(sprintf(_("There was a problem saving the image: %s"), $image_id), 'horde.error');
@@ -269,6 +306,8 @@
$image_id = $gallery->addImage($image);
if (!is_a($image_id, 'PEAR_Error')) {
+ $tmp = &$ansel_shares->getImage($image_id);
+ @Ansel_ImageData::setExifData($tmp);
$notification->push(_("The image was saved."), 'horde.success');
if ($vars->get('image_default')) {
$gallery->set('default', $image_id, true);
@@ -369,7 +408,7 @@
break;
case 'watermark':
- $image->watermark($watermark);
+ $image->watermark($watermark, $watermark_halign, $watermark_valign, $watermark_font);
break;
}
@@ -405,6 +444,9 @@
$imageurl = Util::addParameter($imageurl, 'image', $image_id);
$imageurl = Util::addParameter($imageurl, 'page', $page);
$imageurl = Util::addParameter($imageurl, 'watermark', $watermark);
+ $imageurl = Util::addParameter($imageurl, 'font', $watermark_font);
+ $imageurl = Util::addParameter($imageurl, 'whalign', $watermark_halign);
+ $imageurl = Util::addParameter($imageurl, 'wvalign', $watermark_valign);
$url = Horde::applicationUrl(Util::addParameter($imageurl, 'actionID', 'previewwatermark'));
$url = str_replace( '&', '&', $url);
Util::closeWindowJS('window.opener.location.href = "' . $url . '";');
@@ -468,7 +510,7 @@
case 'imagewatermark':
$image = &$ansel_shares->getImageById($image_id);
- $image->watermark($watermark);
+ $image->watermark($watermark, $watermark_halign, $watermark_valign, $watermark_font);
$image->display();
exit;
exifFields.inc
(text/plain, 1.4 KB)
<?php
$ExifFields = array('Make' => _('Camera Make'),
'Model' => _('Camera Model'),
'ImageType' => _('Image Type'),
'FileSize' => _('File Size'),
'DateTime' => _('Image Taken'),
'ExifImageWidth' => _('Width'),
'ExifImageLength' => _('Height'),
'XResolution' => _('X Resolution'),
'YResolution' => _('Y Resolution'),
'ShutterSpeedValue' => _('Shutter Speed'),
'ExposureTime' => _('Exposure'),
'FocalLength' => _('Focal Length'),
'ApertureValue' => _('Aperture'),
'FNumber' => _('F-Number'),
'ISOSpeedRatings' => _('ISO Setting'),
'ExposureBiasValue' => _('Exposure Bias'),
'ExposureMode' => _('Exposure Mode'),
'MeteringMode' => _('Metering Mode'),
'Flash' => _('Flash Setting'),
'UserComment' => _('User Comment'),
'ColorSpace' => _('Color Space'),
'SensingMethod' => _('Sensing Method'),
'WhiteBalance' => _('White Balance'),
'Orientation' => _('Camera Orientation'),
'Copyright' => _('Copyright')
);
?>