PHP code example of belisoful / php-image

1. Go to this page and download the library: Download belisoful/php-image library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

belisoful / php-image example snippets


$jpeg = JPEGImage::fromStream($psr7Stream);             // any PSR-7 implementation
$jpeg = JPEGImage::fromStream(fopen('in.jpg', 'rb'));   // or a raw resource
$jpeg->getEXIF()?->setValueByName('Artist', 'A. Photographer');
$jpeg->writeTo(fopen('out.jpg', 'wb'));                 // resource out
$jpeg->writeTo($psr7Stream);                            // or a stream out

$handle = $jpeg->toStream();                            // a rewound PHP stream resource

$exif = EXIF::scanFile('500MB-scan.tif');   // seeks; never loads the pixels
$exif->getMake();
$exif->getThumbnail();

use Belisoful\Image\JPEGImage;
use Belisoful\Image\PNGImage;
use Belisoful\Image\WebPImage;

$jpeg = JPEGImage::fromFile('photo.jpg');           // or fromString() / fromStream()
[$w, $h] = [$jpeg->getWidth(), $jpeg->getHeight()];

$png  = PNGImage::fromFile('image.png');
$icc  = $png->getICCProfile();                  // null when absent

$webp = WebPImage::fromFile('image.webp');          // VP8 / VP8L / VP8X all supported

use Belisoful\Image\JPEGImage;
use Belisoful\Image\Meta\IPTC;
use Belisoful\Image\Meta\IPTCTags;

$jpeg = JPEGImage::fromFile('photo.jpg');

$iptc = $jpeg->getIPTC() ?? new IPTC();
$iptc[IPTCTags::CaptionAbstract] = 'Edited caption';
$iptc['Keywords'] = ['php', 'image', 'metadata'];     // repeatable dataset
$jpeg->setIPTC($iptc);

$jpeg->save('photo-out.jpg');    // image data unchanged, metadata rewritten

$jfif = $jpeg->getJFIF();
[$jfif->getXDensity(), $jfif->getYDensity(), $jfif->getUnits()];
$jfif->setImage($gdThumbnail);   // embed an RGB thumbnail (<= 255x255)

// JFXX is the APP0 thumbnail extension, with JPEG, palette, or RGB encodings.
$jfxx = $jpeg->getJFXX() ?? new JFXX();
$jfxx->setImage($gdThumbnail, JFXX::JPEG_THUMB);   // or PALETTE_THUMB / COLOR_THUMB / EFFICIENCY_THUMB
$thumb = $jfxx->getImage();                          // back to a \GdImage or \Imagick
$jpeg->setJFXX($jfxx);

use Belisoful\Image\JPEGImage;

$jpeg = JPEGImage::fromFile('photo.jpg');
$exif = $jpeg->getEXIF();

$exif->getMake();                          // 'Canon'
$exif->getValueByName('FNumber');          // [[71, 10]]
$exif->getTextByName('FNumber');           // '7.1'
$exif->getTextByName('ExposureTime');      // '1/125 seconds'
$exif->getTextByName('GPSLatitude');       // '34° 3' 30"'
$thumb = $exif->getThumbnail();            // IFD1 JPEG bytes

$note = $exif->getMakernote();             // detected via the maker registry
$note?->getValues();                       // name => interpreted text
$note?->getThumbnail();                    // Casio/Olympus/Minolta embedded thumbnail

$exif->setValueByName('Artist', 'A. Photographer');
$jpeg->save('photo-out.jpg');              // rewritten; makernote pinned at its offset

$exif->getLatitude();                      // -33.86882  (S negative, W negative)
$exif->setLatitude(60.392990);
$exif->setLongitude(5.324383);
$exif->setAltitude(-42.25);                // below sea level
$exif->setGpsTimestamp(new DateTimeImmutable('now'));   // stored as UTC

use Belisoful\Image\PrivacyCategory;

// One call on the container reaches every metadata block it holds.
$jpeg = JPEGImage::fromFile('photo.jpg');
$removed = $jpeg->clearPrivateData();                                // everything: the safe default
$jpeg->save('photo-shareable.jpg');

$png->clearPrivateData(PrivacyCategory::Location);                  // GPS in EXIF and XMP, IPTC place names
$tiff->clearPrivateData(PrivacyCategory::All & ~PrivacyCategory::CameraModel);   // keep make/model
$webp->clearPrivateData(PrivacyCategory::Identity | PrivacyCategory::Location);  // people + place
$gif->clearPrivateData(PrivacyCategory::Provenance);                // where, when, and with what software

// Or scrub a single carrier when that is what you hold.
$exif = $jpeg->getEXIF();
$exif->clearPrivateData(PrivacyCategory::MakerNote | PrivacyCategory::Thumbnail);
$jpeg->setEXIF($exif);

$exif = $jpeg->getEXIF();
$bytes = $exif->toBinary();

$exif->getReservedSpaces();   // [[offset, length], …] — the pinned maker notes / private IFDs
$exif->getFreeSpaces();       // the complement: every editable range, in offset order

// Rewrite only the free regions; the reserved bytes are never addressed.
foreach ($exif->getFreeSpaces() as [$offset, $length]) {
    $bytes = substr_replace($bytes, $patchFor($offset, $length), $offset, $length);
}

use Belisoful\Image\Meta\XMP;

$xmp = $jpeg->getXMP() ?? XMP::blank();
$xmp->getTitle();                                          // x-default
$xmp->getTitle('de');                                      // language alternative
$xmp->setLangAlt(XMP::NS_DC, 'title', ['x-default' => 'Sunset', 'de' => 'Sonnenuntergang']);
$xmp->setKeywords(['sunset', 'norway']);
$xmp->getByPath('xmpMM:History[1]/stEvt:action');          // 'created'
$xmp->addArrayItem(XMP::NS_MM, 'History', ['stEvt:action' => 'edited'], 'Seq');
$xmp->getProperties();                                     // every property, by prefix:name
$jpeg->setXMP($xmp);                                       // extended XMP when > 64 KB

$png->setXMP($xmp);                                        // PNG iTXt
$webp->setXMP($xmp);                                       // WebP XMP chunk (adds VP8X)

use Belisoful\Image\Meta\PhotoshopFileInfo;

$info = PhotoshopFileInfo::fromJpeg($jpeg);        // merged view: XMP, then IPTC, then EXIF
$info['title'] = 'Sunset over Bergen';
$info['copyrightstatus'] = PhotoshopFileInfo::Copyrighted;
$info->applyTo($jpeg);                     // EXIF + XMP + IRB/IPTC updated together
$jpeg->save('photo-out.jpg');

use Belisoful\Image\GIFImage;
use Belisoful\Image\GIF\GIFFrame;

$gif = GIFImage::fromFile('animation.gif');
$gif->getFrameCount();                       // 12
$gif->getLoopCount();                        // 0 = forever, null = play once
$gif->getComments();                         // ['made with php-image']

$frame = $gif->getFrame(0);
[$frame->getLeft(), $frame->getTop()];       // the sub-rectangle, not the canvas
$frame->getDelayTime();                      // hundredths of a second
$frame->getDisposalMethod();                 // GIFFrame::DisposalRestoreBackground
$frame->getTransparentIndex();               // palette index, or null
$frame->getPixels();                         // one index byte per pixel, de-interlaced

$frame->setDelayTime(8);                     // retime the animation
$gif->setLoopCount(0);                       // loop forever
$gif->save('animation-out.gif');             // every other byte identical

$image = $gif->getFrameImage(0);             // \GdImage or \Imagick

$frame = new GIFFrame();
$frame->setDelayTime(10);
$frame->setImage($photo);                    // quantized to a local color table
$gif->addFrame($frame);

$still = GIFImage::fromImage($photo);            // a single-frame GIF from any image

use Belisoful\Image\PNGImage;
use Belisoful\Image\ImageChunk;
use Belisoful\Image\PNG\PNGChunkType;

$png = PNGImage::fromFile('image.png');

$png->setICCProfile($iccBytes);              // deflated iCCP chunk
$png->setEXIF($exif);                        // eXIf chunk (bare TIFF)
$png->setXMP($xmp);                          // iTXt XMP packet
$png->setIPTC($iptc);                        // stored in the 8BIM text chunk

$png->getICCProfile();                       // and each reads straight back
$png->getPhotoshopIRB();                     // the resource block the IPTC rides in

// Raw chunk access keeps the spec's normative order and recomputes each CRC.
$png->setChunk(new ImageChunk(PNGChunkType::Gamma, 4, 0, pack('N', 45455)));
$png->removeChunk(PNGChunkType::Text);

$image = $png->getImage();                   // decode the raster
$png->setImage($resized);                    // re-encode, carrying the metadata chunks across
$png->save('image-out.png');

use Belisoful\Image\PNG\APNGFrame;

$apng = PNGImage::fromApngImages([$frame0, $frame1, $frame2], 0.15, 0);   // 0.15s each, loop forever
$apng->getIsAnimated();                      // true
$apng->getFrameCount();                      // 3
$apng->getPlayCount();                       // 0 = forever

$frames = $apng->getApngFrames();            // APNGFrame[] with fcTL geometry + delay
$frames[1]->setDelaySeconds(0.5);
$frames[1]->setDisposeOp(APNGFrame::DisposeBackground);
$apng->setApngFrames($frames);               // rebuilds acTL/fcTL/fdAT, renumbering sequences

$image = $apng->getApngFrameImage(0);        // decode one frame to a \GdImage or \Imagick
$apng->addApngFrame($extra, 0.2);            // append a frame from an image
$apng->save('animation.png');                // a still viewer shows the default image

use Belisoful\Image\WebPImage;

$webp = WebPImage::fromFile('image.webp');

$webp->setICCProfile($iccBytes);             // adds VP8X + the ICC flag if absent
$webp->setEXIF($exif);
$webp->setXMP($xmp);
$webp->getEXIF()?->getValueByName('Model');

try {
    $webp->setIPTC($iptc);                    // throws: WebP has no IPTC carrier
} catch (\RuntimeException $e) {
    // put the equivalent properties in XMP instead
}

$webp->setImage($resized, 80);               // re-encode the bitstream, metadata carried across
$webp->save('image-out.webp');

use Belisoful\Image\ImageGraphicsLibraryInterface;
use Belisoful\Image\ImageGraphics;
use Belisoful\Image\ImageGraphicsMode;

$jfif->setImage($imagickThumbnail);                          // an \Imagick source works anywhere
$gd  = $jfif->getImage(ImageGraphicsMode::GD);              // ... and either library comes back out
$im  = $jfif->getImage(ImageGraphicsMode::Imagick);

ImageGraphics::setDefaultMode(ImageGraphicsMode::Imagick); // prefer ImageMagick for this app
$image = $jpeg->getIPTC()->getRasterizedCaptionImage();      // now an \Imagick by default

ImageGraphics::supports(ImageGraphicsLibraryInterface::CapabilityCmyk);          // the default library
ImageGraphics::supports(ImageGraphicsLibraryInterface::CapabilityWebP, ImageGraphicsMode::GD);
ImageGraphics::getLibrary(ImageGraphicsMode::Imagick)->supports(ImageGraphicsLibraryInterface::CapabilityHighBitDepth);

$webp = ImageGraphics::encode($image, ImageGraphicsLibraryInterface::FormatWebP, 80);   // false when unsupported
$png  = ImageGraphics::encode($image, ImageGraphicsLibraryInterface::FormatPng);        // lossless: quality ignored

$cmyk = ImageGraphics::cmykPixels($image);                                      // 4 bytes/pixel
$image = ImageGraphics::fromCmykPixels($cmyk, $w, $h);

$profile = ImageGraphics::getICCProfile($image);        // ImageMagick only; null under GD
ImageGraphics::setICCProfile($image, $profile);         // over an existing profile: a transform
ImageGraphics::transformICCProfile($image, $sRgb, $adobeRgb);   // works in either backend

$library = ImageGraphics::getCapableLibrary(ImageGraphicsLibraryInterface::CapabilityICCEmbed);
$image = $library?->fromRgbPixels($rgb, $w, $h);         // built where the profile can ride along

use Belisoful\Image\Compression\GIFLZWCompressor;
use Belisoful\Image\Compression\PackBitsCompressor;

$lzw   = new GIFLZWCompressor();
$bytes = $lzw->compress($indexStream, 8);      // GIF image data sub-blocks
$data  = $lzw->decompress($bytes, 8);

$packed = (new PackBitsCompressor())->compress($scanline);

use Belisoful\Image\RIFFContainer;

$riff = RIFFContainer::fromFile('audio.wav');
$riff->getFormType();            // 'WAVE'
foreach ($riff->getChunks() as $chunk) {
    [$chunk->getType(), $chunk->getSize(), $chunk->getOffset()];
}
sh
composer install
composer unittest                                    # tests
vendor/bin/php-cs-fixer fix src                      # code style (tabs)
vendor/bin/php-cs-fixer fix tests                    # (the finder excludes tests/, so name it)
vendor/bin/phpstan analyse --memory-limit=1G         # static analysis (level 4)
sh
XDEBUG_MODE=coverage vendor/bin/phpunit --testsuite unit --coverage-clover build/logs/clover.xml
php tests/test_tools/coverage-gate.php build/logs/clover.xml
sh
XDEBUG_MODE=coverage php -d memory_limit=10G vendor/bin/phpunit --testsuite unit \
    --path-coverage --coverage-php build/logs/coverage.php
php -d memory_limit=8G tests/test_tools/branch-gate.php build/logs/coverage.php