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'); }
/** * Load data into a JPEG object. * * The data supplied will be parsed and turned into an object * structure representing the image. This structure can then be * manipulated and later turned back into an string of bytes. * * This methods can be called at any time after a JPEG object has * been constructed, also after the {@link appendSection()} has been * called to append custom sections. Loading several JPEG images * into one object will accumulate the sections, but there will only * be one {@link PelJpegMarker::SOS} section at any given time. * * @param PelDataWindow the data that will be turned into JPEG * sections. */ function load(PelDataWindow $d) { Pel::debug('Parsing %d bytes...', $d->getSize()); /* JPEG data is stored in big-endian format. */ $d->setByteOrder(PelConvert::BIG_ENDIAN); /* Run through the data to read the sections in the image. After * each section is read, the start of the data window will be * moved forward, and after the last section we'll terminate with * no data left in the window. */ while ($d->getSize() > 0) { /* JPEG sections start with 0xFF. The first byte that is not * 0xFF is a marker (hopefully). */ for ($i = 0; $i < 7; $i++) { if ($d->getByte($i) != 0xff) { break; } } $marker = $d->getByte($i); if (!PelJpegMarker::isValid($marker)) { throw new PelJpegInvalidMarkerException($marker, $i); } /* Move window so first byte becomes first byte in this * section. */ $d->setWindowStart($i + 1); if ($marker == PelJpegMarker::SOI || $marker == PelJpegMarker::EOI) { $content = new PelJpegContent(new PelDataWindow()); $this->appendSection($marker, $content); } else { /* Read the length of the section. The length includes the * two bytes used to store the length. */ $len = $d->getShort(0) - 2; Pel::debug('Found %s section of length %d', PelJpegMarker::getName($marker), $len); /* Skip past the length. */ $d->setWindowStart(2); if ($marker == PelJpegMarker::APP1) { try { $content = new PelExif(); $content->load($d->getClone(0, $len)); } catch (PelInvalidDataException $e) { /* We store the data as normal JPEG content if it could * not be parsed as Exif data. */ $content = new PelJpegContent($d->getClone(0, $len)); } $this->appendSection($marker, $content); /* Skip past the data. */ $d->setWindowStart($len); } elseif ($marker == PelJpegMarker::COM) { $content = new PelJpegComment(); $content->load($d->getClone(0, $len)); $this->appendSection($marker, $content); $d->setWindowStart($len); } else { $content = new PelJpegContent($d->getClone(0, $len)); $this->appendSection($marker, $content); /* Skip past the data. */ $d->setWindowStart($len); /* In case of SOS, image data will follow. */ if ($marker == PelJpegMarker::SOS) { /* Some images have some trailing (garbage?) following the * EOI marker. To handle this we seek backwards until we * find the EOI marker. Any trailing content is stored as * a PelJpegContent object. */ $length = $d->getSize(); while ($d->getByte($length - 2) != 0xff || $d->getByte($length - 1) != PelJpegMarker::EOI) { $length--; } $this->jpeg_data = $d->getClone(0, $length - 2); Pel::debug('JPEG data: ' . $this->jpeg_data->__toString()); /* Append the EOI. */ $this->appendSection(PelJpegMarker::EOI, new PelJpegContent(new PelDataWindow())); /* Now check to see if there are any trailing data. */ if ($length != $d->getSize()) { Pel::maybeThrow(new PelException('Found trailing content ' . 'after EOI: %d bytes', $d->getSize() - $length)); $content = new PelJpegContent($d->getClone($length)); /* We don't have a proper JPEG marker for trailing * garbage, so we just use 0x00... */ $this->appendSection(0x0, $content); } /* Done with the loop. */ break; } } } } /* while ($d->getSize() > 0) */ }
/** * Generuje miniaturę i zapisuje do exifa * @param <type> $fullpath */ public function generujMiniature($fullpath) { // include_once('C:\xampp\php\PEAR\PelJpeg.php'); // include_once('C:\xampp\php\PEAR\PelExif.php'); // include_once('C:\xampp\php\PEAR\PelIfd.php'); $jpeg = new PelJpeg($fullpath); $exif = $jpeg->getExif(); //Jeżeli zdjęcie nie posiada exifa if (!$exif) { //Utworzenie kontera exif $pelexif = new PelExif(); //Dodanie obiektu PelTiff i PelIfd $tiff = new PelTiff(); $ifd0 = new PelIfd(PelIfd::IFD0); $tiff->setIfd($ifd0); $pelexif->setTiff($tiff); //Dodanie obiektów do zdjęcia $jpeg->setExif($pelexif); } $exif = $jpeg->getExif(); $tiff = $exif->getTiff(); $ifd0 = $tiff->getIfd(); $ifd1 = $ifd0->getNextIfd(); //tworzenie miniatury jeżli nie istnieje (nie ma IFD1) if (!$ifd1) { $ifd1 = new PelIfd(1); //point ifd0 to the new ifd1 (or else ifd1 will not be read) $ifd0->setNextIfd($ifd1); //create image resource of original $original = ImageCreateFromString($jpeg->getBytes()); $orig_w = imagesx($original); $orig_h = imagesy($original); $wmax = 160; $hmax = 120; if ($orig_w > $wmax || $orig_h > $hmax) { $thumb_w = $wmax; $thumb_h = $hmax; if ($thumb_w / $orig_w * $orig_h > $thumb_h) { $thumb_w = round($thumb_h * $orig_w / $orig_h); } else { $thumb_h = round($thumb_w * $orig_h / $orig_w); } } else { # only set the thumb's size if the original is larger than 'wmax'x'hmax' $thumb_w = $orig_w; $thumb_h = $orig_h; } # create image resource with thumbnail sizing $thumb = imagecreatetruecolor($thumb_w, $thumb_h); ## Resize original and copy to the blank thumb resource imagecopyresampled($thumb, $original, 0, 0, 0, 0, $thumb_w, $thumb_h, $orig_w, $orig_h); # start writing output to buffer ob_start(); # outputs thumb resource contents to buffer ImageJpeg($thumb); # create PelDataWindow from buffer thumb contents (and end output to buffer) $window = new PelDataWindow(ob_get_clean()); if ($window) { $ifd1->setThumbnail($window); # set window data as thumbnail in ifd1 $outpath = $fullpath; # overwrite original jpg file file_put_contents($outpath, $jpeg->getBytes()); # write everything to output filename } } }