powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PEL битый EXIF
5 сообщений из 5, страница 1 из 1
PEL битый EXIF
    #40054849
Zhenek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день..
Необходимо в изображении очистить exif и прописать нужные данные.
Как делаю:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
$fname = 'photo_2021-03-18_15-43-40.jpg';

$e = exif_read_data(PATH_TO."/$fname", 0, true); 
print_r($e);    //Читаю EXIF оригинала. Это для отладки


///Тут отпиливаем все что есть в exif с сохранением icc профиля
$img = new Imagick(PATH_TO."/$fname");
$profiles = $img->getImageProfiles("icc", true);
  $img->stripImage();
    if(!empty($profiles)) {
       $img->profileImage("icc", $profiles['icc']);
    }  
 $img->setImageCompressionQuality(100);
 $img->writeImage(PATH_TO."/$fname");
$e = exif_read_data(PATH_TO."/$fname", 0, true); 
print_r($e);  // результат для отладки


$data = new PelDataWindow(file_get_contents(PATH_TO."/$fname"));
$tiff = null;
$file = null;
if (PelJpeg::isValid($data)) {
    $jpeg = $file = new PelJpeg(); 
    $jpeg->load($data);
    $exif = $jpeg->getExif();

    // If no EXIF in image, create it
    if($exif == null) {
        $exif = new PelExif();
        $jpeg->setExif($exif);

        $tiff = new PelTiff();
        $exif->setTiff($tiff);
    }
    else {
        $tiff = $exif->getTiff();
    }
}
// If it is a TIFF EXIF-headers will always be set
elseif (PelTiff::isValid($data)) { 
    $tiff = $file = new PelTiff();
    $tiff->load($data);
}
else {
    throw new \Exception('Invalid image format');
}


$exif_ifd = new PelIfd(PelIfd::EXIF);
 $ifd0->addSubIfd($exif_ifd);
 $date2 = $exif_ifd->getEntry(PelTag::DATE_TIME_ORIGINAL);
if($date2 == null) {
  $time2 =  new PelEntryTime(PelTag::DATE_TIME_ORIGINAL, strtotime($Odate));
  $exif_ifd->addEntry($time2);
} 
 
 $date2 = $exif_ifd->getEntry(PelTag::DATE_TIME_DIGITIZED);
if($date2 == null) {
   $time2 =  new PelEntryTime(PelTag::DATE_TIME_DIGITIZED, strtotime($Odate));
   $exif_ifd->addEntry($time2);
} 


$file->saveFile(PATH_TO."/$fname");
$e = exif_read_data(PATH_TO."/$fname", 0, true); 
print_r($e); //Вывод результата для отладки




В общем Все записывает и читается. exif_read_data выводит результат:
п.с. Я убрал часть кода которая редактирует другие данные т.к. проблема только в дате


[FILE] => Array
(
[FileName] => photo_2021-03-18_15-43-40.jpg
[FileDateTime] => 1616051748
[FileSize] => 354099
[FileType] => 2
[MimeType] => image/jpeg
[SectionsFound] => ANY_TAG, IFD0, EXIF, GPS
)

[COMPUTED] => Array
(
[html] => width="960" height="1280"
[Height] => 1280
[Width] => 960
[IsColor] => 1
[ByteOrderMotorola] => 0
)

[IFD0] => Array
(
[Make] => CANON
[Model] => PowerShot SX430 IS
[DateTime] => 2021:03:18 13:20:16
[Exif_IFD_Pointer] => 119
[GPS_IFD_Pointer] => 189
)

[EXIF] => Array
(
[DateTimeOriginal] => 2021:03:18 13:20:16
[DateTimeDigitized] => 2021:03:18 13:20:16
)


)


Но при этом при чтении записанных параметров exif_read_data паралельно ругается. Ругается, но результат выводит.

<br />
<b>Warning</b>: exif_read_data(photo_2021-03-18_15-43-40.jpg): Process tag(x0132=DateTime ): Illegal format code 0x0000, suppose BYTE in <b>PATH/test.php</b> on line <b>47</b><br />
<br />
<b>Warning</b>: exif_read_data(photo_2021-03-18_15-43-40.jpg): Process tag(x9003=DateTimeOri): Illegal format code 0x0000, suppose BYTE in <b>PATH/test.php</b> on line <b>47</b><br />
<br />
<b>Warning</b>: exif_read_data(photo_2021-03-18_15-43-40.jpg): Process tag(x9004=DateTimeDig): Illegal format code 0x0000, suppose BYTE in <b>PATH/test.php</b> on line <b>47</b><br />

Возможно это баг exif_read_data, (много багрепортов с подобными ошибками), но ресурс куда нужно загрузить это фото, ругается и не может прочитать параметры. (скорее всего читаем им-же)
Если же открыть изображение в ExifPilot, все данные есть. Жму сохранить (ничего не меняя) и оп, все ошибки пропадают.exif валидный.

Сравнивал вывод exif_read_data для файлов с ошибками и без, разницы нет.лишних пробелов нет.

Прошу помощи т.к. уже 2 ночи сижу, и даже не знаю в какую сторону идти. менять PEL не хотелось бы, вроде как достойной замены нет
...
Рейтинг: 0 / 0
PEL битый EXIF
    #40054937
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zhenek
Если же открыть изображение в ExifPilot, все данные есть. Жму сохранить (ничего не меняя) и оп, все ошибки пропадают.exif валидный.

Сравнивал вывод exif_read_data для файлов с ошибками и без, разницы нет.лишних пробелов нет.
Получается, что при записи что-то не то пишется. Такое, что для exif_read_data не является фатальной ошибкой и, видимо, не оказывает влияния на конечный результат. Возможно, для даты нужен какой-то особый подход или формат исходных данных, с датами часто всякие заморочки бывают. Если есть желание, можно чуток изучить структуру хранения метаданных и посмотреть результат записи в файле какой-нибудь HEX-смотрелкой, сравнить с тем, что после пересохранения. Возможно, натолкнет на какие-то мысли.

PS: Лет несколько назад для записи или перезаписи метаданных в изображение пытался использовать пхпшние библиотеки. Перебрал несколько - ни одной стопроцентно рабочей не попалось в разумное время. В итоге ушел на системный вызов утилиты exiv2, благо, ситуация позволяла это сделать.
...
Рейтинг: 0 / 0
PEL битый EXIF
    #40054990
Zhenek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle, Спасибо за ответ

Методом проб и ошибок, удалось записать дату вот таким способом

Код: php
1.
$time2=  new PelEntryAscii(PelTag::DATE_TIME_ORIGINAL, date('Y:m:d H:i:s'));



Записать как текст, вот в таком формате.
Т.к. посмотрел, что делает встроенная в pel функция работы с датами:

Код: sql
1.
2.
3.
4.
    public function convertUnixToJd($timestamp)
    {
        return floor($timestamp / 86400) + 2440588;
    }



И хранит его в 3 варианте (там вроде как 3 варианта хранения даты в exif, 1.строкой, 2. юлианский и григорианский стиль.
Может кому будет полезно.
При этом нормальные программы читаю все варианты и сами приводят в удобный для человека вид.
...
Рейтинг: 0 / 0
PEL битый EXIF
    #40055008
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дата не в UTC, случаем, в метаданных хранится? Если так, то надо учесть влияние таймзоны на функцию date().
...
Рейтинг: 0 / 0
PEL битый EXIF
    #40055047
Zhenek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторДата не в UTC, случаем, в метаданных хранится? Если так, то надо учесть влияние таймзоны на функцию date().
Вроде нет. Я сильно глубоко не стал копать,офф дока 148 страниц( и я думал отделаться сторонним класом)
Судя по доке хранится дата в ASCII, просто я изначально думал, что это не просто строка и поэтому пытался записать ее через функционал класса.

Но все-же не понятно, почему были ошибки т.к. дата все-же формировалась и была записана, читалась как exif_read_data (но с ошибками) так и остальным софтом. Скорее всего узнать как так вышло можно только сравнив HEX двух файлов и найти различия..
Но пока не буду) не настолько интересно, учитывая что это такой формат, где каждый пляшет как хочет
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / PEL битый EXIF
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]