PHP Exif Library - library for reading and writing Exif headers in JPEG and TIFF files using PHP.

Last update: Jun 28, 2022

PEL: PHP Exif Library

Build Status Code Coverage Scrutinizer Code Quality Latest Stable Version Total Downloads License

README file for PEL: PHP Exif Library. A library with support for reading and writing Exif headers in JPEG and TIFF images using PHP.

Copyright (C) 2004, 2005, 2006 Martin Geisler. Licensed under the GNU GPL, see COPYING for details.


The PHP Exif Library (PEL) makes it easy to develop programs that will read and write the Exif metadata headers found in JPEG and TIFF images. See the file INSTALL for an introduction to how PEL can be used by your application.

PEL is a library written entirely in PHP 5, which means that it does not have any dependencies outside the core of PHP, it does not even use the Exif module available for PHP.

Please note that the API for PEL is not yet frozen, and it will remain changeable until version 1.0 is reached. Read the NEWS file for important information about API changes.

Also, please go to the PEL development mailing list (look below) and share your ideas about how the API should look like.


composer require lsolesen/pel

Documentation Overview

  • README.markdown: gives you a short introduction to PEL (this file).
  • explain how to install and get going with PEL.
  • contains important information about changes in PEL.
  • examples/: small self-contained examples of how to use PEL.
  • AUTHORS: list of people who have helped.
  • run to generate API-documention or see it online at

Features of PEL

  • Reads and writes Exif metadata from both JPEG and TIFF images.
  • Supports reading and writing all Exif tags.
  • Supports internationalization.
  • Extensible object-oriented design.
  • PhpUnit tested
  • Documented with PhpDocumentor (

Helping out

Help will be very much appreciated. You can report issues, run the test suite, add patches. The best way to help out is applying patches and helping out with the tests. See instructions in the test/ directory.

All changes to code should be issued through a pull request, and other maintainers should review the code and merge it.


To work with the translations, you need the gettext package installed.

Getting Support

The first place you should consult for support is the documentation supplied with PEL, found at There you will find a complete API documentation with descriptions of all classes and files in PEL.

The scripts found in the examples/ directory are also a good source of information, especially the edit-description.php file which has tons of comments.

PEL is hosted on Github and uses the tools found there for support. This means that all questions, bug reports, etc. should be directed there (and not directly to the developers).

Please try the latest version before reporting bugs -- it might have been fixed already. The latest code can be found in the git repository at

It is very helpful if you try out the latest code from the git repository before submitting a bug report. The code found there is generally very stable.

Contributing Test Images

To make PEL as stable as possible, it is tested with images from a number of different camera models.

New test images are very much appreciated -- please download the existing test images and read the README file found there for instructions.


Please see the AUTHORS file for a list of people who have contributed to PEL. See the full list of code contributors.

  • 1. Non-latin characters in PelEntryWindowsString

    Why does PelEntryWindowsString support only Latin-1 character set? Windows surely supports other ASCII character sets in file properties dialog (particularly, russian: Windows-1251).

    Reviewed by dmitry-fedyuk at 2011-01-02 04:40
  • 2. Fixes for [pel-Bugs-2979466 ] endless loop in PelIfd->load

    A long time standing bug

    This case seems due to wrong data setup in the test image: the INTEROPERABILITY IFD has inside it a pointer to another INTEROPERABILITY IFD. But this is incorrect - we expect only one INTEROPERABILITY IFD in an image file. This leads to an infinite loop.

    This PR addresses this by passing the parent IFD type to the load method, so that it can check it's not duplicating IFDs of the same type.

    Reviewed by mondrake at 2017-11-15 12:02
  • 3. PROPOSAL: Move tags metadata to a YAML file

    I was thinking for a while about this, then also found this in the TODO:

    • Restructure information about tags. Currently information about the tags are stored in several places around the code, making updates difficult. All information about a tag should be stored at one place, maybe by having a class per tag (how well does PHP handle 142 small classes?).

      The information in question is:

      • hex code,
      • title,
      • name,
      • description
      • format,
      • components,
      • valid IFD types,
      • how to load data,
      • how to display (the getText() method)

    ua-parser/uap-php manages something like this - it has a big list of regex patterns that are stored in a YAML file; to reduce I/O and processing, the YAML file is compiled into a PHP equivalent and then included in code as needed.

    This would mean a BC change, so I this is a for a new major version of PEL.

    Just wanted to test the waters if any feedback. Next steps if there is interest could be to start defining a YAML model to store the info needed.

    Reviewed by mondrake at 2017-11-19 17:22
  • 4. Parsing canon maker notes

    This PR is my first attempt of parsing canon's maker notes. The results look good so far. Beside FocalLength, which is overwritten by the maker notes and has an other format. Only first level elements are taken into account. E.g. tag 0x0001 (Exif.Canon.CameraSettings) is not parsed yet.

    Would be great if anyone else could test and have a look at my code if it is ok :) As soon as this one gets (hopefully) merged, I'd have a look at nikon's maker notes.

    Reviewed by v1r0x at 2017-10-01 10:56
  • 5. Added reverse lookup methods, fixed PHPDOC for PelTag enumerations

    Added new reverse lookup methods: getExifTagByName() and getGpsTagByName(). There is no way to tell what type of tag was returned by the getTagByName, making it unusable. I suggest deprecating getTagByName() as soon as possible, will delete it from branch if you confirm this. Fixed inconsistent PHPDOC parameter types for PelTag enumerations, which were erroneously referring to PelTag type. Every method that use tag wants int as an argument, not a PelTag instance. Also, PelEntry and PelEntryException use int as their $tag property, not PelEntry instance.

    Reviewed by artemShelest at 2017-04-13 15:24
  • 6. Reworked the way tag lookup is done and added reverse lookup

    Needed a reverse lookup of the tag short name to the tag value, so had to rework how it is handled. Stored tags into arrays, tag as a key, value as a string.

    Reviewed by artemShelest at 2016-10-29 14:31
  • 7. PEL is up for adoption

    I am not using PEL in any of my own projects, and haven't been for a while. Therefore, the project needs a new maintainer, which actually maintains the code. Are you up for it?

    Reviewed by lsolesen at 2012-10-11 21:47
  • 8. Handle non-numeric values from PelFormat::getSize

    PelFormat::getSize can also return non-numeric values (string, in case of an error). We should handle those cases correctly.

    In my case, this is the warning I see (only the relevant backtrace is shown here).

    Warning: A non-numeric value encountered in lsolesen\pel\PelIfd->loadSingleValue() (line 447 of /var/www/.../vendor/lsolesen/pel/src/PelIfd.php) #0 /var/www/.../web/core/includes/ _drupal_error_handler_real(2, 'A non-numeric v...', '/var/www/...', 447, Array)
    #1 /var/www/.../vendor/lsolesen/pel/src/PelIfd.php(447): _drupal_error_handler(2, 'A non-numeric v...', '/var/www/...', 447, Array)
    #2 /var/www/.../vendor/lsolesen/pel/src/PelCanonMakerNotes.php(215): lsolesen\pel\PelIfd->loadSingleValue(Object(lsolesen\pel\PelDataWindow), 4908, 71, 19200)
    #3 /var/www/.../vendor/lsolesen/pel/src/PelIfd.php(406): lsolesen\pel\PelCanonMakerNotes->load()
    #4 /var/www/.../vendor/lsolesen/pel/src/PelTiff.php(159): lsolesen\pel\PelIfd->load(Object(lsolesen\pel\PelDataWindow), 10)
    #5 /var/www/.../vendor/lsolesen/pel/src/PelExif.php(108): lsolesen\pel\PelTiff->load(Object(lsolesen\pel\PelDataWindow))
    #6 /var/www/.../vendor/lsolesen/pel/src/PelJpeg.php(216): lsolesen\pel\PelExif->load(Object(lsolesen\pel\PelDataWindow))
    #7 /var/www/.../vendor/lsolesen/pel/src/PelJpeg.php(286): lsolesen\pel\PelJpeg->load(Object(lsolesen\pel\PelDataWindow))
    #8 /var/www/.../vendor/lsolesen/pel/src/PelJpeg.php(123): lsolesen\pel\PelJpeg->loadFile('public://photos...')
    Reviewed by hussainweb at 2020-04-05 17:14
  • 9. Convert to new array syntax (PHP 5.4)

    Since PHP 5.4, the array syntax changed from array() to [].

    This PR is changing the old syntax to the new syntax. Used the script @

    Reviewed by mondrake at 2017-12-15 14:13
  • 10. Links to Scrutinizer and to Packagist are wrong

    The pel/pel package on Packagist refers to another project, and the badge on the readme is wrong. So it looks like in composer you still need to require lsolesel/pel.

    Also, the badge linking to Scrutinizer leads to a 404 page.

    Reviewed by mondrake at 2017-11-04 17:09
  • 11. Exception thrown on picture

    Bug created from sourceforge

    $jpeg = new PelJpeg($tmpfile); 
    $exif = $jpeg->getExif(); 
    if ( $exif != null ) { 
        $jpeg1 = new PelJpeg($bigfile); 
        $jpeg1->setExif( $exif); 
        file_put_contents($bigfile, $jpeg1->getBytes()); 

    A test case has been created

    Reviewed by lsolesen at 2010-12-06 12:21
  • 12. Invalid marker found at offset 0: 0x89

    Another issue that surfaced from drupal file_mdm module (

    Error is caused by:

    Slightly offtopic: I'm also wondering since we're seeing a few of pel issues - does anyone know a way of how to fix image exif metadata on filesystem directly? other error: Message: Unknown format: 0x300

    Reviewed by ivangrozni at 2022-04-13 10:52
  • 13. webp support ?

    Hi, are there plans to add webp image type support ? It doesn't look too complicated if you consider this answer on StackOverflow : Thank you for the good work so far, I've been using PEL for years ;)

    Reviewed by AbsurdePhoton at 2022-04-12 23:13
  • 14. Cannot find a way to get the document name

    I cannot for the life of me find a way to extract the document name:

    use lsolesen\pel\PelJpeg;
    use lsolesen\pel\PelTag;
    $jpeg=new PelJpeg('samplepic-doctitle.jpg');
    print_r($ifd->getEntry( PelTag::DOCUMENT_NAME));


    I see the name, though, if I check with GNOME's file manager or other apps:


    Reviewed by rgpublic at 2022-03-10 15:20
  • 15. Convert three variable assignments to the usage of combined operators

    :eyes: Some source code analysis tools can help to find opportunities for improving software components. :thought_balloon: I propose to increase the usage of combined operators accordingly.

    diff --git a/src/PelEntrySShort.php b/src/PelEntrySShort.php
    index 94f0f3d..b65fa44 100644
    --- a/src/PelEntrySShort.php
    +++ b/src/PelEntrySShort.php
    @@ -793,7 +793,7 @@ class PelEntrySShort extends PelEntryNumber
                 $val = $this->value[0];
                 if ($this->ifd_type === PelIfd::CANON_CAMERA_SETTINGS && $this->tag === PelTag::CANON_CS_LENS_TYPE) {
                     // special handling: lens types must be multtiplied by 100 because digits canÄt be used in arrays
    -                $val = $val * 100;
    +                $val *= 100;
                 if (array_key_exists($val, self::TRANSLATIONS[$this->ifd_type][$this->tag])) {
                     return Pel::tra(self::TRANSLATIONS[$this->ifd_type][$this->tag][$val]);
    diff --git a/src/PelEntryTime.php b/src/PelEntryTime.php
    index 5275d68..ae3116e 100644
    --- a/src/PelEntryTime.php
    +++ b/src/PelEntryTime.php
    @@ -270,9 +270,9 @@ class PelEntryTime extends PelEntryAscii
             $l = $jd + 68569;
             $n = floor((4 * $l) / 146097);
    -        $l = $l - floor((146097 * $n + 3) / 4);
    +        $l -= floor((146097 * $n + 3) / 4);
             $i = floor((4000 * ($l + 1)) / 1461001);
    -        $l = $l - floor((1461 * $i) / 4) + 31;
    +        $l -= floor((1461 * $i) / 4) - 31;
             $j = floor((80 * $l) / 2447);
             $d = $l - floor((2447 * $j) / 80);
             $l = floor($j / 11);
    Reviewed by elfring at 2021-11-26 17:40
  • 16. [0.9.10] PelIllegalFormatException: Unknown format: 0x0

    We recenty upgraded to PHP 7.4 with PEL 0.9.10. Since then, we have the following error after the first EXIF write:

                    lsolesen\pel\PelIllegalFormatException: Unknown format: 0x0 in /var/www/
    Stack trace:
    #0 /var/www/ lsolesen\pel\PelFormat::getSize()
    #1 /var/www/ lsolesen\pel\PelIfd->loadSingleValue()
    #2 /var/www/ lsolesen\pel\PelIfd->load()
    #3 /var/www/ lsolesen\pel\PelTiff->load()
    #4 /var/www/ lsolesen\pel\PelExif->load()
    #5 /var/www/ lsolesen\pel\PelJpeg->load()

    The first write of exif is successful. The second (open already edited file) does not load anymore.

    Downgrading to 0.9.9 works.

    Reviewed by Commifreak at 2021-02-11 13:55
PEL: PHP Exif Library

PHP Exif Library - library for reading and writing Exif headers in JPEG and TIFF files using PHP.

Jun 28, 2022
PHPExif is a library which gives you easy access to the EXIF meta-data of an image

PHPExif v0.6.4 PHPExif is a library which gives you easy access to the EXIF meta-data of an image. PHPExif serves as a wrapper around some native or C

Aug 4, 2022
PHPExif - A PHP Exif reader

PHPExif is a library which gives you easy access to the EXIF meta-data of an image.

Apr 10, 2022
Image optimization / compression library. This library is able to optimize png, jpg and gif files in very easy and handy way. It uses optipng, pngquant, pngcrush, pngout, gifsicle, jpegoptim and jpegtran tools.

Image Optimizer This library is handy and very easy to use optimizer for image files. It uses optipng, pngquant, jpegoptim, svgo and few more librarie

Jul 30, 2022
This package provides an integration with FFmpeg for Laravel. Laravel's Filesystem handles the storage of the files.

Laravel FFMpeg This package provides an integration with FFmpeg for Laravel 6.0 and higher. Laravel's Filesystem handles the storage of the files. Fea

Aug 11, 2022
A library using PHP to generate QRCode from free

PHP Class Generate Free QRCode ?? A library using PHP to generate QRCode from free ✋ NOTE: Do not generate too many QRCo

Jul 28, 2022
Symfony Bundle to assist in imagine manipulation using the imagine library

LiipImagineBundle PHPUnit PHP-CS-Fixer Coverage Downloads Release This bundle provides an image manipulation abstraction toolkit for Symfony-based pro

Aug 11, 2022
Auto Image & file upload, resize and crop for Laravel eloquent model using Intervention image

Laravel ImageUp The qcod/laravel-imageup is a trait which gives you auto upload, resize and crop for image feature with tons of customization. Install

Jul 26, 2022
Create images with embedded text using advanced typography

Image with Text This class makes it super easy to render images with multiple, independently styled text blocks. You can control each text block's ali

May 3, 2022
Alternative image provider for fakerphp using

Fakerphp Picsum Images Introduction Alternative image provider for fakerphp using This package has been forked from mmo/faker-images for

Jul 27, 2022
Generate Avatars using Initials, Bears or Kittens

Avatary Simple avatar generator Explore the docs » View Demo · Report Bug · Request Feature Table of Contents About The Project Built With Getting Sta

Jun 17, 2022
Laravel Optical Character Reader(OCR) package using ocr engines like Tesseract
Laravel Optical Character Reader(OCR) package using ocr engines like Tesseract

LaraOCR Laravel Optical Character Reader(OCR) package using ocr engines like Tesseract under the hood. Features Read text from image using WebUI/Progr

Jun 15, 2022
ImageWorkshop is a PHP5.3+ library that helps you to manage images based on GD library

================================ ImageWorkshop class ================================ Summary and features Really flexible and easy-to-use PHP class t

Aug 10, 2022
PHP library to resize, scale and crop images.
PHP library to resize, scale and crop images.

PHP library to resize, scale and crop images.

Aug 12, 2022
PHP library to easily edit image with GD extension. Resize, crop, merge, draw, and many more options !
PHP library to easily edit image with GD extension. Resize, crop, merge, draw, and many more options !

PHP Image Editor PHP library to easily edit image with GD extension. Resize, crop, merge, draw, and many more options ! ✨ Supporting ⭐ Star this repos

Aug 11, 2022
PHP 5.3 Object Oriented image manipulation library

Imagine Tweet about it using the #php_imagine hashtag. Image manipulation library for PHP 5.3 inspired by Python's PIL and other image libraries. Requ

Aug 12, 2022
PHP Captcha library
PHP Captcha library

Captcha Installation With composer : { ... "require": { "gregwar/captcha": "1.*" } } Usage You can create a captcha with the Captc

Aug 10, 2022
This is a class of php QR Code, This library helps you generate QR codes in a jiffy.

This is a class of php QR Code, This library helps you generate QR codes in a jiffy.

Jun 30, 2022
Goldbach Algorithms Mask is a PHP library developed for Symfony for apply a mask to strings.

Goldbach Algorithms Mask (fondly nicknamed GoldMask) is a PHP library developed for Symfony for apply a mask to strings.

Oct 30, 2021