PHPのExif ライブラリ lsolesen Pel を使おうと思ったらはまった話

Exif 情報をJPEGから抜き出してサムネイル作成時にその Exif 情報を部分的にコピーして再生成しようと思ったのですが…

lsolesen/pel @ GitHub
こんなの見つけたんだけど、
サイト探しても資料が無い…

PHPプロ!TIPS+ PHPでExifを操作する
PHP TIPS - 106. PHPでExifを操作する:ITpro

こういう自分用タグ埋め込む方法は書いてるんだけど、もともとあるタグをそのままの形式で埋め込む方法が無いんだわ・ω・;

ってわけで、12時間くらいかけて試行錯誤しながら実現してみました。

 $jpegFile = new PelJpeg($fileName);
 $app = $jpegFile->getExif();

 if ($app == null) {
// Exif 情報なしの場合処理しない
 } else {
     $tiff = $app->getTiff();
     $ifd = $tiff->getIfd();
     $exif = $ifd->getSubIfd(PelIfd::EXIF);
     $gps = $ifd->getSubIfd(PelIfd::GPS);
     $jpeg1 = new PelJpeg($copyFile);
     $app1 = new PelExif();
     $jpeg1->setExif($app1);
     $tiff1 = new PelTiff();
     $app1->setTiff($tiff1);
     $ifd1 = new PelIfd(PelIfd::IFD0);
     $gps1  = new PelIfd(PelIfd::GPS);
     $exif1 = new PelIfd(PelIfd::EXIF);
     $tiff1->setIfd($ifd1);
     $entry = $ifd0->getEntry(PelTag::IMAGE_DESCRIPTION);
     // 詳細
     if($entry) {
  $ifd1->addEntry(new PelEntryAscii(PelTag::IMAGE_DESCRIPTION , $entry->getValue()));
     }
     // メーカー名
     $entry = $ifd0->getEntry(PelTag::MAKE);
     if($entry) {
  $ifd1->addEntry(new PelEntryAscii(PelTag::MAKE , $entry->getValue()));
     }
     // モデル名
     $entry = $ifd0->getEntry(PelTag::MODEL);
     if($entry) {
  $ifd1->addEntry(new PelEntryAscii(PelTag::MODEL , $entry->getValue()));
     }
     // バージョン情報
     $entry = $exif0->getEntry(PelTag::EXIF_VERSION);
     if($entry) {
  $exif1->addEntry(new PelEntryVersion(PelTag::EXIF_VERSION , $entry->getValue()));
     }
     // 日時の取得
     $entry = $exif0->getEntry(PelTag::DATE_TIME_ORIGINAL);
     if($entry) {
  $ifd1->addEntry(new PelEntryTime(PelTag::DATE_TIME , $entry->getValue()));
// なぜか Y:m:d にするとExif情報が破壊されるバグがある
  $exif1->addEntry(new PelEntryAscii(PelTag::DATE_TIME_ORIGINAL , date('Y/m/d H:i:s',$entry->getValue()- date("Z")) ));
  $exif1->addEntry(new PelEntryAscii(PelTag::DATE_TIME_DIGITIZED , date('Y/m/d H:i:s',$entry->getValue()- date("Z")) ));
//タイムゾーンの修正
     }
     // 画像幅
     $entry = $exif0->getEntry(PelTag::PIXEL_X_DIMENSION);
     if($entry) {
  $exif1->addEntry(new PelEntryLong(PelTag::PIXEL_X_DIMENSION , $entry->getValue()));
     }
     // 画像高さ
     $entry = $exif0->getEntry(PelTag::PIXEL_Y_DIMENSION);
     if($entry) {
  $exif1->addEntry(new PelEntryLong(PelTag::PIXEL_Y_DIMENSION , $entry->getValue()));
     }
     // GPS情報
     if ($gps0) {
  $v=$gps0->getEntries();
  $gps1->addEntry(new PelEntryByte(PelTag::GPS_VERSION_ID, $v[0]->getValue()[0], $v[0]->getValue()[1], $v[0]->getValue()[2], $v[0]->getValue()[3]));
  $gps1->addEntry(new PelEntryRational(PelTag::GPS_LATITUDE, $v[2]->getValue()[0], $v[2]->getValue()[1], $v[2]->getValue()[2]));
  $gps1->addEntry(new PelEntryAscii(   PelTag::GPS_LATITUDE_REF, $v[1]->getText()));
  $gps1->addEntry(new PelEntryRational(PelTag::GPS_LONGITUDE, $v[4]->getValue()[0], $v[4]->getValue()[1], $v[4]->getValue()[2]));
  $gps1->addEntry(new PelEntryAscii(   PelTag::GPS_LONGITUDE_REF, $v[3]->getText()));
  //高度情報
  $entry = $gps0->getEntry(PelTag::GPS_ALTITUDE_REF);
  $entry2 = $gps0->getEntry(PelTag::GPS_ALTITUDE);
  if ($entry2 != null) {
      $gps1->addEntry(new PelEntryRational(PelTag::GPS_ALTITUDE, $entry2->getValue()));
      $gps1->addEntry(new PelEntryByte(PelTag::GPS_ALTITUDE_REF, $entry->getValue()));
  }
  $entry = $gps0->getEntry(PelTag::GPS_MAP_DATUM);
  if ($entry != null) {
      $gps1->addEntry(new PelEntryAscii(   PelTag::GPS_MAP_DATUM, $entry));
  }
  $entry = $gps0->getEntry(PelTag::GPS_DATE_STAMP);
  if ($entry) {
      $gps1->addEntry(new PelEntryAscii(PelTag::GPS_DATE_STAMP , $entry->getText() ));
  }
  $entry = $gps0->getEntry(PelTag::GPS_TIME_STAMP);
  if ($entry) {
      $gps1->addEntry(new PelEntryRational(PelTag::GPS_TIME_STAMP, $entry->getValue()[0], $entry->getValue()[1], $entry->getValue()[2]));
  }
  $ifd1->addSubIfd($gps1);
  $ifd1->addSubIfd($exif1);
     }
     file_put_contents($up, $jpeg->getBytes());

     // nullにしないとなぜかこの後の処理でJPEGが開けなくなる
     $tiff1 = null;
     $app1 = null;
     $gps1 = null;
     $jpeg1 = null;
     $ifd1 = null;
     $app = null;
     $tiff = null;
     $ifd = null;
     $exif = null;
     $gps = null;
     return ;

基本こんな感じで複写できるようだ。
なんか、たまにイレギュラーなバグがあってはまったのだけど…。

例えば、PelJpeg.php が Penjpeg.php になってるバグがあってこのままだと linuxで動かないとか

おすすめ

1件の返信

  1. Theresejes より:

    Конференция
    ИТ-аутсорсинг: лучшие практики и новые бизнес-модели
    13 октября 2015 года

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です