EL_EL
EL_EL

Reputation: 133

php support for WEBP image metadata

Does php support webp image metadata?

Specifically, I want to be able to read and write XMP and EXIF metadata for webp images natively in php code.

I have been experimenting with the below code and it is giving me a "File not supported in" warning.

<?php

$photoSourceThumbnail = "publicAssets/images/att_galleryWebP/A0001_LSF-PHOTOS-WM-TM-WEBP/A0001-EWF-LSF-01.webp";
$photoSourceFull = "assets/images/att_galleryWebP/A0001_LSF-PHOTOS-WM-FULL-WEBP/A0001-EWF-LSF-01.webp";

echo "$photoSourceFull:<br />\n";
$exif = exif_read_data($photoSourceFull, 'IFD0');
echo $exif===false ? "No header data found.<br />\n" : "Image contains headers<br />\n";

$exif = exif_read_data($photoSourceFull, 0, true);
echo "test2.jpg:<br />\n";
foreach ($exif as $key => $section) {
    foreach ($section as $name => $val) {
        echo "$key.$name: $val<br />\n";
    }
} 

Upvotes: 2

Views: 3099

Answers (3)

Solonl
Solonl

Reputation: 2512

It is better to use ExifTool for this.

Install ExifTool

https://exiftool.org/

PHP example

class ExifToolException extends RuntimeException{}

function getInfo(string $file) : object 
{
    $info = shell_exec('exiftool -json ' . escapeshellarg($file) . ' 2>&1');
    if(strpos($info, 'Error:') > -1) {
        throw new ExifToolException(rtrim($info, PHP_EOL));
    }
    return json_decode($info)[0];
}

try {
    var_dump(getInfo('abc.webp')->Megapixels);
} catch(ExifToolException $e) {
    var_dump($e->getMessage());
}

Update: Exiftool added WebP support as of version 12.46, Oct. 1, 2022

Upvotes: 0

EL_EL
EL_EL

Reputation: 133

Google have recently changed the image requirements for web sites saying that they should include IPTC image rights metadata.

https://developers.google.com/search/docs/advanced/appearance/image-rights-metadata

I have successfully been able to update image XMP,EXIF and IPTC metadata for a jpg image from my SQL table using EXIFTOOL to meet these new google requirements. I have checked the test image on the IPTC tool and it does contain the desired XMP,EXIF and IPTC metadata.

https://getpmd.iptc.org/getiptcpmd.html

However.........

Extensive reading into the WEBP format and tools such as exiv2, dwebp and webpmux, can only write XMP and EXIF metadata to a webp image.

https://www.exiv2.org/manpage.html
https://developers.google.com/speed/webp/docs/cwebp
https://developers.google.com/speed/webp/docs/webpmux
https://image.online-convert.com/convert-to-webp (drag and drop web tool that converts Jpg to webp with XMP & Exif metadata)

It would seem that webp DOES NOT SUPPORT IPTC metadata therefore does not fulfil these requirements:

https://developers.google.com/search/docs/advanced/appearance/image-rights-metadata

Conclusions:

  1. Webp as an image format for images that I want google indexed, is a dead duck unless/until google modify the RIFF header to include IPTC.
  2. Next steps are to revert images on my website back to jpg.

For anyone interested in how I modified the image XMP,EXIF and IPTC metadata from php.

a) These are the metadata fields that I finally decided upon with the exiftool commands to update them.

exiftool -iptc:by-line="image creator" A0000-01.jpg
exiftool -xmp:creator="image creator" A0000-01.jpg
exiftool -exif:Artist="image creator" A0000-01.jpg

exiftool -iptc:CopyrightNotice="Copywrite 2022 websiteName.com" A0000-01.jpg
exiftool -xmp:rights="Copywrite 2022 websiteName.com" A0000-01.jpg
exiftool -exif:Copyright="Copywrite 2022 websiteName.com" A0000-01.jpg

exiftool -iptc:keywords="keyword1,keyword2,keyword3" A0000-01.jpg
exiftool -xmp:Subject="keyword1,keyword2,keyword3" A0000-01.jpg
exiftool -exif:UserComment="keyword1,keyword2,keyword3" A0000-01.jpg

exiftool -iptc:credit="image reproduced with permission from" A0000-01.jpg
exiftool -xmp:credit="image reproduced with permission from" A0000-01.jpg

exiftool -iptc:ObjectName="Image title" A0000-01.jpg
exiftool -xmp:Title="Image title" A0000-01.jpg

exiftool -iptc:Caption-Abstract="Image description" A0000-01.jpg
exiftool -xmp:description="Image description" A0000-01.jpg
exiftool -exif:ImageDescription="Image description" A0000-01.jpg

exiftool -iptc:Source="Url where image can be found" A0000-01.jpg
exiftool -xmp:Source="Url where image can be found" A0000-01.jpg

exiftool -exif:gpslatitude="44.081102" -exif:gpslatituderef=N A0000-01.jpg
exiftool -exif:gpslongitude="-35.489600" -exif:gpslongituderef=W A0000-01.jpg
exiftool -xmp:gpslatitude="44.081102 N" A0000-01.jpg
exiftool -gpslongitude="-35.489600 E" A0000-01.jpg

exiftool -xmp:AuthorsPosition="website owner & coder" A0000-01.jpg
exiftool -iptc:By-lineTitle="website owner & coder" A0000-01.jpg

exiftool -xmp:CaptionWriter="websiteName.com.com" A0000-01.jpg
exiftool -iptc:Writer-Editor="websiteName.com.com" A0000-01.jpg

b) In php I am using the below code to generate a string of text that contains the exiftoolcommand:

$F_XmpDescriptionSt = 'exiftool -xmp:description="'.$iptcDescription.'" "'.$absoluteImgJpgFullSizePath.'"';

where $iptcDescription and $absoluteImgJpgFullSizePath are the desired metadata values from mySQL table

c) I am then launching the command via command prompt terminal with below code:

$FullsizeExiftoolXmpDescriptionExecute = exec("$F_XmpDescriptionSt");

I repeat the above for all of the metadata fields I want to update, adjusting the php code to the exiftool command.

I am sure there is a more elegant way of doing this such as a batch script?? but I prefer to launch each exiftool command as a single line of code one by one so that I get the response message "1 files updated" for each metadata field that I update. It takes about 15 seconds to complete the code for all metadata fields so not a big issue.

This line of code outputs the exiftool response contained in variable FullsizeExiftoolXmpDescriptionExecute.

<h4>Fullsize XMP Description $FullsizeExiftoolXmpDescriptionExecute to $iptcDescription</h4>

This video tutorial explains how to install exiftool on windows 10. https://www.youtube.com/watch?v=Ku1Nx-kl7RM

Upvotes: -1

AmigoJack
AmigoJack

Reputation: 6174

WebP supports both Exif and XMP for years already. The format is based on RIFF and acknowledges at least the chunks EXIF, XMP and ICCP. Good software will also read an IPTC chunk.

Just because some random software does not consider carrying over metadata doesn't mean the target format doesn't support it - most software is rather sloppy than ambitious. Since the RIFFormat is rather trivial it should be easy to modify existing files to include more chunks:

  • Each chunk consists of 4 bytes identifier/FourCC (i.e. the ASCII characters EXIF), then 4 bytes of its size in little Endian, then the payload.
  • The file's first chunk is similar: it starts with the 4 bytes RIFF, then 4 bytes of its entire filesize minus 8, then 4 bytes of content identification, here WEBP (to distinguish this from other formats also using RIFF, such as WAV, AVI, Maya, AIF, MIDI...).
  • This means you append your new chunk at the end of the file and then patch bytes 5 through 8 of the file with the new filesize. Example:
$sExif= '...the binary data...';  // You read that off the other file, of course
$iLenExif= strlen( $sExif );  // Payload length in bytes
if( $iLenExif% 2== 1 ) $sExif.= "\0";  // RIFF needs 16bit alignment

$hFile= fopen( 'TARGET.WEBP', 'r+' );   // Read and write access
fseek( $hFile, 0, SEEK_END );  // Go to end of file

fwrite( $hFile, 'EXIF' );  // 4 bytes chunk ID
fwrite( $hFile, pack( 'V', $iLenExif ) );  // 4 bytes of payload length
fwrite( $hFile, $sExif );  // Actual data

$iFilesize= ftell( $hFile );  // Should be bigger
fseek( $hFile, 4, SEEK_SET );  // Go to 5th byte of file
fwrite( $hFile, pack( 'V', $iFilesize- 8 ) );  // Write 4 bytes, patching old filesize

fclose( $hFile );  // Store everything.

Upvotes: 3

Related Questions