/** * Add GPS information to an image basic metadata. Any old Exif data * is discarded. * * @param string the input filename. * * @param string the output filename. An updated copy of the input * image is saved here. * * @param string image description. * * @param string user comment. * * @param string camera model. * * @param float longitude expressed as a fractional number of degrees, * e.g. 12.345°. Negative values denotes degrees west of Greenwich. * * @param float latitude expressed as for longitude. Negative values * denote degrees south of equator. * * @param float the altitude, negative values express an altitude * below sea level. * * @param string the date and time. */ function addGpsInfo($input, $output, $description, $comment, $model, $longitude, $latitude, $altitude, $date_time) { /* Load the given image into a PelJpeg object */ $jpeg = new PelJpeg($input); /* Create and add empty Exif data to the image (this throws away any * old Exif data in the image). */ $exif = new PelExif(); $jpeg->setExif($exif); /* Create and add TIFF data to the Exif data (Exif data is actually * stored in a TIFF format). */ $tiff = new PelTiff(); $exif->setTiff($tiff); /* Create first Image File Directory and associate it with the TIFF * data. */ $ifd0 = new PelIfd(PelIfd::IFD0); $tiff->setIfd($ifd0); /* Create a sub-IFD for holding GPS information. GPS data must be * below the first IFD. */ $gps_ifd = new PelIfd(PelIfd::GPS); $ifd0->addSubIfd($gps_ifd); /* The USER_COMMENT tag must be put in a Exif sub-IFD under the * first IFD. */ $exif_ifd = new PelIfd(PelIfd::EXIF); $exif_ifd->addEntry(new PelEntryUserComment($comment)); $ifd0->addSubIfd($exif_ifd); $inter_ifd = new PelIfd(PelIfd::INTEROPERABILITY); $ifd0->addSubIfd($inter_ifd); $ifd0->addEntry(new PelEntryAscii(PelTag::MODEL, $model)); $ifd0->addEntry(new PelEntryAscii(PelTag::DATE_TIME, $date_time)); $ifd0->addEntry(new PelEntryAscii(PelTag::IMAGE_DESCRIPTION, $description)); $gps_ifd->addEntry(new PelEntryByte(PelTag::GPS_VERSION_ID, 2, 2, 0, 0)); /* Use the convertDecimalToDMS function to convert the latitude from * something like 12.34° to 12° 20' 42" */ list($hours, $minutes, $seconds) = convertDecimalToDMS($latitude); /* We interpret a negative latitude as being south. */ $latitude_ref = $latitude < 0 ? 'S' : 'N'; $gps_ifd->addEntry(new PelEntryAscii(PelTag::GPS_LATITUDE_REF, $latitude_ref)); $gps_ifd->addEntry(new PelEntryRational(PelTag::GPS_LATITUDE, $hours, $minutes, $seconds)); /* The longitude works like the latitude. */ list($hours, $minutes, $seconds) = convertDecimalToDMS($longitude); $longitude_ref = $longitude < 0 ? 'W' : 'E'; $gps_ifd->addEntry(new PelEntryAscii(PelTag::GPS_LONGITUDE_REF, $longitude_ref)); $gps_ifd->addEntry(new PelEntryRational(PelTag::GPS_LONGITUDE, $hours, $minutes, $seconds)); /* Add the altitude. The absolute value is stored here, the sign is * stored in the GPS_ALTITUDE_REF tag below. */ $gps_ifd->addEntry(new PelEntryRational(PelTag::GPS_ALTITUDE, array(abs($altitude), 1))); /* The reference is set to 1 (true) if the altitude is below sea * level, or 0 (false) otherwise. */ $gps_ifd->addEntry(new PelEntryByte(PelTag::GPS_ALTITUDE_REF, (int) ($altitude < 0))); /* Finally we store the data in the output file. */ file_put_contents($output, $jpeg->getBytes()); }
function testIteratorAggretate() { $ifd = new PelIfd(PelIfd::IFD0); $this->assertEqual(sizeof($ifd->getIterator()), 0); $desc = new PelEntryAscii(PelTag::IMAGE_DESCRIPTION, 'Hello?'); $date = new PelEntryTime(PelTag::DATE_TIME, 12345678); $ifd->addEntry($desc); $ifd->addEntry($date); $this->assertEqual(sizeof($ifd->getIterator()), 2); $entries = array(); foreach ($ifd as $tag => $entry) { $entries[$tag] = $entry; } $this->assertIdentical($entries[PelTag::IMAGE_DESCRIPTION], $desc); $this->assertIdentical($entries[PelTag::DATE_TIME], $date); }
function addGPSdata($infile, $outfile, $GPS_lat, $GPS_lon, $GPS_alt) { try { $image = new PelJpeg($infile); } catch (Exception $exc) { return -1; } if ($image instanceof PelJpeg) { if ($image->isValid(new PelDataWindow($image->getBytes()))) { $exif = $image->getExif(); if ($exif == null) { $exif = new PelExif(); $image->setExif($exif); $exif->setTiff(new PelTiff()); } $tiff = $exif->getTiff(); $ifd0 = $tiff->getIfd(); if ($ifd0 == null) { $ifd0 = new PelIFD(PelIfd::IFD0); $tiff->setIfd($ifd0); } /* Tags erzeugen */ $subifd = new PelIfd(PelIfd::GPS); $GPS_latref = $GPS_lat < 0 ? "S" : "N"; $GPS_lonref = $GPS_lon < 0 ? "W" : "E"; $GPS_altref = $GPS_alt < 0 ? 1 : 0; list($degrees, $minutes, $milliseconds) = dec2dms(abs($GPS_lat)); $gpslat = new PelEntryRational(PelTag::GPS_LATITUDE, array($degrees, 1), array($minutes, 1), array($milliseconds, 1000)); list($degrees, $minutes, $milliseconds) = dec2dms(abs($GPS_lon)); $gpslon = new PelEntryRational(PelTag::GPS_LONGITUDE, array($degrees, 1), array($minutes, 1), array($milliseconds, 1000)); echo $GPS_alt * 1000; $gpsalt = new PelEntryRational(PelTag::GPS_ALTITUDE, array(abs($GPS_alt * 1000), 1000)); $gpslatref = new PelEntryAscii(PelTag::GPS_LATITUDE_REF, $GPS_latref); $gpslonref = new PelEntryAscii(PelTag::GPS_LONGITUDE_REF, $GPS_lonref); $gpsaltref = new PelEntryByte(PelTag::GPS_ALTITUDE_REF, $GPS_altref); $gpsversion = new PelEntryByte(PelTag::GPS_VERSION_ID, 2, 2, 0, 0); /* Daten eintragen.*/ $subifd->addEntry($gpsversion); $subifd->addEntry($gpslat); $subifd->addEntry($gpslon); $subifd->addEntry($gpsalt); $subifd->addEntry($gpslatref); $subifd->addEntry($gpslonref); $subifd->addEntry($gpsaltref); $ifd0->addSubIfd($subifd); file_put_contents($outfile, $image->getBytes()); return 0; } } return -1; }
function testWriteRead() { Pel::setStrictParsing(true); $ifd = new PelIfd(PelIfd::IFD0); $this->assertTrue($ifd->isLastIfd()); foreach ($this->entries as $entry) { $ifd->addEntry($entry); } $tiff = new PelTiff(); $this->assertNull($tiff->getIfd()); $tiff->setIfd($ifd); $this->assertNotNull($tiff->getIfd()); $exif = new PelExif(); $this->assertNull($exif->getTiff()); $exif->setTiff($tiff); $this->assertNotNull($exif->getTiff()); $jpeg = new PelJpeg(dirname(__FILE__) . '/no-exif.jpg'); $this->assertNull($jpeg->getExif()); $jpeg->setExif($exif); $this->assertNotNull($jpeg->getExif()); $jpeg->saveFile('test-output.jpg'); $this->assertTrue(file_exists('test-output.jpg')); $this->assertTrue(filesize('test-output.jpg') > 0); /* Now read the file and see if the entries are still there. */ $jpeg = new PelJpeg('test-output.jpg'); $exif = $jpeg->getExif(); $this->assertIsA($exif, 'PelExif'); $tiff = $exif->getTiff(); $this->assertIsA($tiff, 'PelTiff'); $ifd = $tiff->getIfd(); $this->assertIsA($ifd, 'PelIfd'); $this->assertEqual($ifd->getType(), PelIfd::IFD0); $this->assertTrue($ifd->isLastIfd()); foreach ($this->entries as $entry) { $this->assertEqual($ifd->getEntry($entry->getTag())->getValue(), $entry->getValue()); } unlink('test-output.jpg'); }
/** * Add GPS information to an image basic metadata. Any old Exif data * is discarded. * * @param string the input filename. * * @param string the output filename. An updated copy of the input * image is saved here. * * @param string image description. * * @param string user comment. * * @param string camera model. * * @param float longitude expressed as a fractional number of degrees, * e.g. 12.345°. Negative values denotes degrees west of Greenwich. * * @param float latitude expressed as for longitude. Negative values * denote degrees south of equator. * * @param float the altitude, negative values express an altitude * below sea level. * * @param string the date and time. */ function addGpsInfo($input, $description, $comment, $artist, $make, $model, $longitude, $latitude) { /* Load the given image into a PelJpeg object */ $jpeg = new PelJpeg($input); /* Create and add empty Exif data to the image (this throws away any * old Exif data in the image). */ $exif = new PelExif(); $jpeg->setExif($exif); /* Create and add TIFF data to the Exif data (Exif data is actually * stored in a TIFF format). */ $tiff = new PelTiff(); $exif->setTiff($tiff); /* Create first Image File Directory and associate it with the TIFF * data. */ $ifd0 = new PelIfd(PelIfd::IFD0); $tiff->setIfd($ifd0); /* Create a sub-IFD for holding GPS information. GPS data must be * below the first IFD. */ $gps_ifd = new PelIfd(PelIfd::GPS); $ifd0->addSubIfd($gps_ifd); /* The USER_COMMENT tag must be put in a Exif sub-IFD under the * first IFD. */ $exif_ifd = new PelIfd(PelIfd::EXIF); $exif_ifd->addEntry(new PelEntryUserComment($comment)); $ifd0->addSubIfd($exif_ifd); $inter_ifd = new PelIfd(PelIfd::INTEROPERABILITY); $ifd0->addSubIfd($inter_ifd); $ifd0->addEntry(new PelEntryAscii(PelTag::ARTIST, $artist)); $ifd0->addEntry(new PelEntryAscii(PelTag::MAKE, $make)); $ifd0->addEntry(new PelEntryAscii(PelTag::MODEL, $model)); $ifd0->addEntry(new PelEntryAscii(PelTag::IMAGE_DESCRIPTION, $description)); $gps_ifd->addEntry(new PelEntryByte(PelTag::GPS_VERSION_ID, 2, 2, 0, 0)); // Negative numbers indicate different reference then the usual N/E if ($longitude < 0) { $longitude_ref = 'W'; } else { $longitude_ref = 'E'; } if ($latitude < 0) { $latitude_ref = 'S'; } else { $latitude_ref = 'N'; } list($h, $m, $s) = convertDecimalToDMS($latitude); $gps_ifd->addEntry(new PelEntryAscii(PelTag::GPS_LATITUDE_REF, $latitude_ref)); $gps_ifd->addEntry(new PelEntryRational(PelTag::GPS_LATITUDE, $h, $m, $s)); list($h, $m, $s) = convertDecimalToDMS($longitude); $gps_ifd->addEntry(new PelEntryAscii(PelTag::GPS_LONGITUDE_REF, $longitude_ref)); $gps_ifd->addEntry(new PelEntryRational(PelTag::GPS_LONGITUDE, $h, $m, $s)); $gps_ifd->addEntry(new PelEntryRational(PelTag::GPS_ALTITUDE, array(0, 0))); $gps_ifd->addEntry(new PelEntryByte(PelTag::GPS_ALTITUDE_REF, 0)); //print($gps_ifd); file_put_contents($input, $jpeg->getBytes()); }