How to Read Png Metadata from PHP

Fastest way to read PNG metadata in PHP

I'm not familiar with any ready-made libraries or classes to do it in PHP without a subprocess call, but if you can't find one, writing your own would definitely be the way to go.

PNG's a fairly simple block stream format, so seeking to a specific block and extracting some header fields is trivial.

All you'd need is something which reads and checks the 8-byte 89 50 4E 47 0D 0A 1A 0A PNG header and then alternates between reading 8 bytes (chunk length plus type) and seeking past the block using the length until you hit the chunk type you want.

For the geometry, assuming the PNG follows the spec, here's how it'd go:

  1. Read and verify PNG header (8 bytes)
  2. Read and check header of first block (8 bytes)
    1. Success. type = IHDR
    2. Read additional 8 bytes for geometry (width, height. 4 bytes each)
  3. If the other field you wanted isn't in IHDR, use the chunk size from step 2 to seek to the next block in search of the other field you wanted.

It'd probably take me 5 to 15 minutes to whip something like that up in Python. (I've done similar things with RAR and GIF) Maybe 15 to 25 in PHP since I've got less experience doing low-level file I/O in it.

Creating an image of PNG-format in php with GD with exif

u can go through the following link
exif is not used in png.

https://stackoverflow.com/questions/9542359/does-png-contain-exif-data-like-jpg

but now a days some png image preserve exif tag.u can try bellow link it might help
http://php.net/manual/en/function.exif-read-data.php

Following is the sample code

<?php
//path of the image
$image_name = "1.PNG";

//read all the image attributes
$exif = exif_read_data($image_name, 0, true);
echo $exif===false ? "No header data found.<br />\n" : "Image contains headers\n";

//print the name of the image
echo "Image Name:".$image_name."\n\n";

//iterate trough the image to list all the attributes
foreach ($exif as $key => $section) {
echo "############### Section Name :".$key." #############\n";
foreach ($section as $name => $val) {
echo "$key.$name: $val\n";
}
echo "\n";
}

?>

This will gives bellow output

Image contains headers
Image Name:1.PNG

############### Section Name :FILE #############
FILE.FileName: 1.PNG
FILE.FileDateTime: 1511089868
FILE.FileSize: 6251146
FILE.FileType: 2
FILE.MimeType: image/jpeg
FILE.SectionsFound: ANY_TAG, IFD0, EXIF, MAKERNOTE

############### Section Name :COMPUTED #############
COMPUTED.html: width="5184" height="3456"
COMPUTED.Height: 3456
COMPUTED.Width: 5184
COMPUTED.IsColor: 1
COMPUTED.ByteOrderMotorola: 0
COMPUTED.ApertureFNumber: f/5.0

############### Section Name :IFD0 #############
IFD0.Make: Canon
IFD0.Model: Canon EOS 1300D
IFD0.Orientation: 1
IFD0.XResolution: 72/1
IFD0.YResolution: 72/1
IFD0.ResolutionUnit: 2
IFD0.DateTime: 2017:11:19 16:41:08
IFD0.Artist:
IFD0.YCbCrPositioning: 2
IFD0.Copyright:

############### Section Name :EXIF #############
EXIF.ExposureTime: 1/60
EXIF.FNumber: 5/1
EXIF.ExposureProgram: 2
EXIF.ISOSpeedRatings: 800
EXIF.UndefinedTag:0x8830: 2
EXIF.UndefinedTag:0x8832: 800
EXIF.ExifVersion: 0230
EXIF.DateTimeOriginal: 2017:11:19 16:41:08
EXIF.DateTimeDigitized: 2017:11:19 16:41:08
EXIF.ComponentsConfiguration:

I hope this might help

Metadata extraction from PNG images

PNG files are made up of blocks, most of which are IDAT blocks which contain compressed pixel data in an average PNG. All PNG's start with a IHDR block and end with an IEND block. Since PNG is a very flexible standard in this way, it can be extended by making up new types of blocks--this is how animated Animated PNG works. All browsers can see the first frame, but browsers which understand the types of blocks used in APNG can see the animation.

There are many places that text data can live in a PNG image, and even more places metadata can live. Here is a very convenient summary. You mentioned the "Description tag", which can only live in text blocks, so that it was I'll be focusing on.

The PNG standard contains three different types of text blocks: tEXt (Latin-1 encoded, uncompressed), zTXt (compressed, also Latin-1), and finally iTXt, which is the most useful of all three as it can contain UTF-8 encoded text and can either be compressed or decompressed.

So, your question becomes, "what is a convenient way to extract the text blocks?"

At first, I thought pypng could do this, but it cannot:

tEXt/zTXt/iTXt

Ignored when reading. Not generated.

Luckily, Pillow has support for this - humorously it was added only one day before you asked your original question!

So, without further ado, let's find an image containing an iTXt chunk: this example ought to do.

>>> from PIL import Image
>>> im = Image.open('/tmp/itxt.png')
>>> im.info
{'interlace': 1, 'gamma': 0.45455, 'dpi': (72, 72), 'Title': 'PNG', 'Author': 'La plume de ma tante'}

According to the source code, tEXt and zTXt are also covered.

For the more general case, looking over the other readers, the JPEG and GIF ones also seem to have good coverage of those formats as well - so I would recommend PIL for this. That's not to say that the maintainers of hacoir-metadata wouldn't appreciate a pull request adding text block support though! :-)

Reading a File's Metadata

While I have not used this myself the XMP PHP Toolkit on sourceforge sounds like just what you might be looking for: http://xmpphptoolkit.sourceforge.net/ That being said - it's in alpha and hasn't been updated in over a year it appears.

XMP Toolkit PHP Extension is a PHP module which includes the Adobe XMP
Toolkit SDK. This PHP5 extension will provide classes and methods to
manipulate XMP Metadatas from files like jpegs, tiff, png, but also
wav, mp3, avi, mpeg4, pdf, ai, eps… It’s based from the Adobe XMP
Toolkit SDK 4.4.2. The goal of this extension is to have php classes
which can open files, extract metadatas, manipulate them, and put them
back within few lines of php code. This project is under GPL v3
License.

You are also be able to write arbitrary metadata to an image file with iptcembed. As you mention in your comment this only works for JPEG files.

http://php.net/manual/en/function.iptcembed.php

Here is a script from the comments of a class that will get and set IPTC data:

<?

/************************************************************\

IPTC EASY 1.0 - IPTC data manipulator for JPEG images

All reserved www.image-host-script.com

Sep 15, 2008

\************************************************************/

DEFINE('IPTC_OBJECT_NAME', '005');
DEFINE('IPTC_EDIT_STATUS', '007');
DEFINE('IPTC_PRIORITY', '010');
DEFINE('IPTC_CATEGORY', '015');
DEFINE('IPTC_SUPPLEMENTAL_CATEGORY', '020');
DEFINE('IPTC_FIXTURE_IDENTIFIER', '022');
DEFINE('IPTC_KEYWORDS', '025');
DEFINE('IPTC_RELEASE_DATE', '030');
DEFINE('IPTC_RELEASE_TIME', '035');
DEFINE('IPTC_SPECIAL_INSTRUCTIONS', '040');
DEFINE('IPTC_REFERENCE_SERVICE', '045');
DEFINE('IPTC_REFERENCE_DATE', '047');
DEFINE('IPTC_REFERENCE_NUMBER', '050');
DEFINE('IPTC_CREATED_DATE', '055');
DEFINE('IPTC_CREATED_TIME', '060');
DEFINE('IPTC_ORIGINATING_PROGRAM', '065');
DEFINE('IPTC_PROGRAM_VERSION', '070');
DEFINE('IPTC_OBJECT_CYCLE', '075');
DEFINE('IPTC_BYLINE', '080');
DEFINE('IPTC_BYLINE_TITLE', '085');
DEFINE('IPTC_CITY', '090');
DEFINE('IPTC_PROVINCE_STATE', '095');
DEFINE('IPTC_COUNTRY_CODE', '100');
DEFINE('IPTC_COUNTRY', '101');
DEFINE('IPTC_ORIGINAL_TRANSMISSION_REFERENCE', '103');
DEFINE('IPTC_HEADLINE', '105');
DEFINE('IPTC_CREDIT', '110');
DEFINE('IPTC_SOURCE', '115');
DEFINE('IPTC_COPYRIGHT_STRING', '116');
DEFINE('IPTC_CAPTION', '120');
DEFINE('IPTC_LOCAL_CAPTION', '121');

class iptc {
var $meta=Array();
var $hasmeta=false;
var $file=false;

function iptc($filename) {
$size = getimagesize($filename,$info);
$this->hasmeta = isset($info["APP13"]);
if($this->hasmeta)
$this->meta = iptcparse ($info["APP13"]);
$this->file = $filename;
}
function set($tag, $data) {
$this->meta ["2#$tag"]= Array( $data );
$this->hasmeta=true;
}
function get($tag) {
return isset($this->meta["2#$tag"]) ? $this->meta["2#$tag"][0] : false;
}

function dump() {
print_r($this->meta);
}
function binary() {
$iptc_new = '';
foreach (array_keys($this->meta) as $s) {
$tag = str_replace("2#", "", $s);
$iptc_new .= $this->iptc_maketag(2, $tag, $this->meta[$s][0]);
}
return $iptc_new;
}
function iptc_maketag($rec,$dat,$val) {
$len = strlen($val);
if ($len < 0x8000) {
return chr(0x1c).chr($rec).chr($dat).
chr($len >> 8).
chr($len & 0xff).
$val;
} else {
return chr(0x1c).chr($rec).chr($dat).
chr(0x80).chr(0x04).
chr(($len >> 24) & 0xff).
chr(($len >> 16) & 0xff).
chr(($len >> 8 ) & 0xff).
chr(($len ) & 0xff).
$val;

}
}
function write() {
if(!function_exists('iptcembed')) return false;
$mode = 0;
$content = iptcembed($this->binary(), $this->file, $mode);
$filename = $this->file;

@unlink($filename); #delete if exists

$fp = fopen($filename, "w");
fwrite($fp, $content);
fclose($fp);
}

#requires GD library installed
function removeAllTags() {
$this->hasmeta=false;
$this->meta=Array();
$img = imagecreatefromstring(implode(file($this->file)));
@unlink($this->file); #delete if exists
imagejpeg($img,$this->file,100);
}
};

?>

Example read copyright string:

$i = new iptc("test.jpg");
echo $i->get(IPTC_COPYRIGHT_STRING);

Update copyright statement:

$i = new iptc("test.jpg");
echo $i->set(IPTC_COPYRIGHT_STRING,"Here goes the new data");
$i->write();

Imagick doesn't add metadata PHP

The problem is that you're writing EXIF data to a PNG file. PNG metadata support is poor in most software and until a few years ago (2016/17?) EXIF data wasn't part of the PNG specs.

ImageMagick (and ExifTool and Exiv2) had a non-standard way of embedding EXIF data in a PNG file but almost no software outside of those programs supported it. Exiftool supports the new standard, but I'm not sure if the other two do or not.

I did a quick test on that website you linked to and it simply doesn't read most metadata in a PNG file. My test file has over 1,400 embedded metadata tags and the only one the metapicz.com website picked up was the IPTC:CopyrightNotice.

You might try http://exif.regex.info to check for metadata. It uses ExifTool on the backend and will give better results.



Related Topics



Leave a reply



Submit