:racehorse: find the size of an image without downloading the whole file. Supports batch requests.

Overview

FasterImage CircleCI Coveralls Minimum PHP Version Packagist Version Packagist Downloads License

FasterImage finds the dimensions or filetype of a remote image file given its uri by fetching as little as needed, based on the excellent Ruby implementation by Stephen Sykes and PHP implementation by Tom Moor.

FasterImage uses the curl_muli* suite to run requests in parallel. Currently supports JPG, GIF, PNG, WEBP, BMP, PSD, TIFF, SVG, and ICO files.

Usage

        $client = new \FasterImage\FasterImage();
        
        $images = $client->batch([
            'http://wwww.example.com/image1.jpg',
            'http://wwww.example.com/image2.gif',
            'http://wwww.example.com/image3.png',
            'http://wwww.example.com/image4.bmp',
            'http://wwww.example.com/image5.tiff',
            'http://wwww.example.com/image6.psd',
            'http://wwww.example.com/image7.webp',
            'http://wwww.example.com/image8.ico',
            'http://wwww.example.com/image9.cur',
            'http://wwww.example.com/image10.svg'
        ]);
        
        foreach ($images as $image) {
            list($width,$height) = $image['size'];
        }

Install

composer require fasterimage/fasterimage

Alternatively, add "fasterimage/fasterimage": "~1.5" to your composer.json

Changelog

  • v1.5.0 - Fallback support when curl_multi_init() is not available
  • v1.4.0 - Add support for parsing dimensions from SVG images
  • v1.3.0 - Add ability for user agent, buffer size, and SSL host/peer verification to be overridden
  • v1.2.1 - Limit isRotated to only check for valid orientation values
  • v1.2.0 - Add option to include content-length in result set
  • v1.1.2 - Update Accept header to accept images
  • v1.1.1 - Properly handle jpeg's with corrupted Exif tags
  • v1.1.0 - Return message in return array when curl fails
  • v1.0.3 - Use external stream package
  • v1.0.2 - Fail invalid image exceptions gracefully when using batch requests
  • v1.0.1 - Support PHP v5.4+
  • v1.0.0 - Stable Release - Support for .PSD, .ICO + .CUR
  • v0.0.7 - Remove support for PHP v5.4
  • v0.0.6 - Add option to set timeout of requests, support for EXIF in .jpgs, better support for .bmp (including negative height bitmaps) and normalized response indexes for all file types
  • v0.0.5 - Support for .webp
  • v0.0.4 - Support for .tiff and exceptions for unknown file types
  • v0.0.3 - Force curl to follow redirects so you get less bad responses
  • v0.0.2 - Update curl headers to mimic browser so you get less bad responses
  • v0.0.1 - Support for .jpg, .bmp, .gif, .png and parallel requests

References

Comments
  • Images that fail

    Images that fail

    From time to time I've come across images that fail -- creating a list here to see if we can't fix them eventually

    • https://www.staysafe.org/files/2018/01/unplugged.jpg
    bug 
    opened by willwashburn 15
  • Add fallback support for when cURL multi is not available

    Add fallback support for when cURL multi is not available

    Fixes #16.

    It turns out that even when cURL is installed, the curl_multi_init() function may be disabled on some hosts who are seeking to guard against DDoS attacks. See https://github.com/ampproject/amp-wp/pull/2183#issuecomment-491506514.

    This PR modifies FasterImage::batch() to check if cURL multi is available, and if not, it falls back to doing plain curl_init() calls to obtain the images sequentially.

    opened by westonruter 9
  • Upper bound for orientation check for bogus images

    Upper bound for orientation check for bogus images

    I have a image that is EXIF orientation 49. That is obviously an invalid value, and the image itself has the correct dimensions otherwise. It should report it as not rotated, but is reporting it as rotated. I think https://github.com/willwashburn/fasterimage/blob/master/src/FasterImage/ExifParser.php#L74 should be changed from return (! empty($this->orientation) && $this->orientation >= 5); to return (! empty($this->orientation) && $this->orientation >= 5 && $this->orientation <= 8); to better handle all of the bogus images out there.

    opened by daneren2005 5
  • Add support for parsing dimensions from SVG images

    Add support for parsing dimensions from SVG images

    The AMP plugin for WordPress patches FasterImage to add support for extracting dimension information from SVG images:

    https://github.com/ampproject/amp-wp/blob/4228eee8332c109eff62df5dba0ae4d7c4137ef2/patches/fasterimage-fixes.diff#L51-L115

    It is admittedly somewhat non-sensical to obtain dimensions from SVGs since they are vector images. Nevertheless, when there is an SVG image like:

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" width="36" height="36"><circle fill="#FFCC4D" cx="18" cy="18" r="18"/><path fill="#664500" d="M10.515 23.621C10.56 23.8 11.683 28 18 28c6.318 0 7.44-4.2 7.485-4.379.055-.217-.043-.442-.237-.554-.195-.111-.439-.078-.6.077C24.629 23.163 22.694 25 18 25s-6.63-1.837-6.648-1.855C11.256 23.05 11.128 23 11 23c-.084 0-.169.021-.246.064-.196.112-.294.339-.239.557z"/><ellipse fill="#664500" cx="12" cy="13.5" rx="2.5" ry="3.5"/><ellipse fill="#664500" cx="24" cy="13.5" rx="2.5" ry="3.5"/></svg>
    

    And it is added to a page without width or height attributes:

    <img src="http://wordpressdev.lndo.site/content/uploads/smiley.svg">
    

    It will get rendered with those dimensions defined in the SVG file:

    image

    The FasterImage library is used in the AMP plugin to supply width and height attributes for any img that lacks it in the HTML document. By supplying the dimensions, a better user experience results by avoiding content shifting as images are loaded into the page. (This is why AMP requires the dimensions.) Including support for SVG helps to this end.

    Note that this PR not only extracts the width and height attributes from the SVG image, but it also falls back to inferring (i.e. guessing) a width/height from the SVG viewBox.

    ~⚠️ There are two outstanding issues with this PR, however, and that has to do with SVG images that are extremely small. It turns out that the Stream library doesn't like handling SVG images that are smaller than 1024 bytes. I took a shot at working on a patch in https://github.com/ampproject/amp-wp/pull/1807/files but you probably have a better approach in mind. Notes from that PR:~

    The problem turns out to be an issue with FasterImage and how it was modified in https://github.com/ampproject/amp-wp/pull/1150 to allow extracting pixel dimensions from SVG images. The problem is that it is attempting to read 1024 bytes of data from the image, but the above SVG is only 525 bytes long. This results in a WillWashburn\Stream\StreamBufferTooSmallException exception being thrown, and the image size failing to be obtained, and thus the fallback image size is being used (which is obviously too big).

    Todo

    • [x] Add tests.
    • [x] Address issue with reading tiny SVG images.
    opened by westonruter 4
  • Retry: Add fallback support for when cURL multi is not available

    Retry: Add fallback support for when cURL multi is not available

    Starting a new PR from branch on origin repo. See #17.

    Fixes #16.

    It turns out that even when cURL is installed, the curl_multi_init() function may be disabled on some hosts who are seeking to guard against DDoS attacks. See https://github.com/ampproject/amp-wp/pull/2183#issuecomment-491506514.

    This PR modifies FasterImage::batch() to check if cURL multi is available, and if not, it falls back to doing plain curl_init() calls to obtain the images sequentially.

    opened by westonruter 2
  • Fallback support when curl_multi_init() is not available

    Fallback support when curl_multi_init() is not available

    It turns out that even when cURL is installed, the curl_multi_init() function may be disabled on some hosts who are seeking to guard against DDoS attacks. See https://github.com/ampproject/amp-wp/pull/2183#issuecomment-491506514.

    Would it be feasible to check if this function exists in FasterImage::batch(), and if not, fallback to doing plain curl_init() calls to obtain the images sequentially?

    opened by westonruter 2
  • Exif parsing fails for image

    Exif parsing fails for image

    http://gluesticksgumdrops.com/wp-content/uploads/2015/03/how-to-find-more-time-to-read-to-your-kids.jpg

    Could not be parsed for some reason. Something isn't right in the exif parsing. The byte order is showing up as * here: https://github.com/willwashburn/FasterImage/blob/master/src/FasterImage/ExifParser.php#L80

    bug 
    opened by willwashburn 2
  • Add ability for user agent, buffer size, and SSL host/peer verification to be overridden

    Add ability for user agent, buffer size, and SSL host/peer verification to be overridden

    In the AMP plugin for WordPress, the user agent, buffer size, and SSL host/peer verification are overridden.

    The user agent is overridden to indicate the actual source as opposed to emulating Chrome:

    https://github.com/ampproject/amp-wp/blob/158855dc3349e1e18099dba959ab49dedf806ff6/includes/utils/class-amp-image-dimension-extractor.php#L216-L217

    (Disregard the @todo comment as we have implemented in a patch we apply.)

    This PR applies the patch to fasterimage itself so that it can be passed via a new setUserAgent() setter method.

    Similarly, the AMP plugin is patching the buffer size, SSL peer verification, and SSL host verification:

    https://github.com/ampproject/amp-wp/blob/4228eee8332c109eff62df5dba0ae4d7c4137ef2/patches/fasterimage-fixes.diff#L35-L40

    By class member variables and setter methods, patching in this way will no longer be required.

    opened by westonruter 1
  • Limit isRotated to only check for valid orientation values

    Limit isRotated to only check for valid orientation values

    We have an image that has an orientation of 49 which isn't even a valid value. I am not able to give the image because it is a customer's image and I do not have permission to share it.

    opened by daneren2005 0
  • “Too many open files” warning causes autoloader fatal error when processing an excessive number of images

    “Too many open files” warning causes autoloader fatal error when processing an excessive number of images

    An issue has come up a couple times in the AMP plugin:

    • https://wordpress.org/support/topic/server-error-5xx-from-google-search-console/
    • https://wordpress.org/support/topic/fatal-error-require-failed-opening-required-file/

    The issue is that when someone has a large number of images in their content, FasterImage ends up triggering a “Too many open files” warning. This then eventually tries to throw an StreamBufferTooSmallException exception, but at this point there are too many files open and the autoloader is not able to load the class. The result is then a fatal error due to the the StreamBufferTooSmallException class not being found, as seen in these notices:

    1. Warning: include(/home/meaganpu/public_html/wp-content/plugins/amp/vendor/willwashburn/stream/src/Stream/Exception/StreamBufferTooSmallException.php): failed to open stream: Too many open files in /home/meaganpu/public_html/wp-content/plugins/amp/vendor/composer/ClassLoader.php on line 444
    2. Warning: include(): Failed opening ‘/home/meaganpu/public_html/wp-content/plugins/amp/vendor/composer/../willwashburn/stream/src/Stream/Exception/StreamBufferTooSmallException.php’ for inclusion (include_path=’.:/usr/local/php71/pear’) in /home/meaganpu/public_html/wp-content/plugins/amp/vendor/composer/ClassLoader.php on line 444
    3. Warning: curl_multi_exec(): Could not call the CURLOPT_WRITEFUNCTION in /home/meaganpu/public_html/wp-content/plugins/amp/vendor/fasterimage/fasterimage/src/FasterImage/FasterImage.php on line 119
    4. Fatal error: Uncaught Error: Class ‘WillWashburn\Stream\Exception\StreamBufferTooSmallException’ not found

    A mitigation of this issue would seem to be ensure that the exception class is loaded up-front to prevent triggering that fatal error. This would be a bit better, but since the max files are open at this point another error could happen further in the process.

    It seems the best thing would be to prevent opening too many files in the first place, perhaps batching them in chunks of 32, or else attempt to find some way of detecting how many more files can be opened and open one less than that for a batch. The batches of images would then need to be processed synchronously one after the other until all images are processed.

    opened by westonruter 0
Releases(v1.5.0)
Owner
Will Washburn
Someone probably thought I was a really good dancer at a wedding I went to one time. I also build products with software.
Will Washburn
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

QCode.in 708 Dec 22, 2022
The image server plugin allows you to add responsive images via config without extra elements

Grav image server plugin adds picture tag with loading, responsive, high density images

catchIT 7 Dec 30, 2022
A Laravel Gravatar package for retrieving gravatar image URLs or checking the existance of an image.

Gravatar for Laravel 5.x, 6, 7 and 8 Installation First, pull in the package through Composer via the command line: composer require creativeorange/gr

Creativeorange 477 Dec 1, 2022
This plugin adds a new image style for the Core Image block.

This plugin adds a new image style for the Core Image block. Introduction How to use? Go to Gutenberg Editor and add a image block. e.g. Add new image

Mahesh Waghmare 3 Feb 17, 2022
Fetch instagram photos without the need for app aproval

Fetch instagram photos without the need for app aproval. This plugin will download the photos and/or video thumbnails to local storage. All media will be stored in a json file.

GeNx 39 Dec 7, 2022
PHP Image Manipulation

Intervention Image Intervention Image is a PHP image handling and manipulation library providing an easier and expressive way to create, edit, and com

null 13k Jan 3, 2023
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

Bulat Shakirzyanov 4.3k Jan 6, 2023
Wonderfully easy on-demand image manipulation library with an HTTP based API.

Glide Glide is a wonderfully easy on-demand image manipulation library written in PHP. Its straightforward API is exposed via HTTP, similar to cloud i

The League of Extraordinary Packages 2.4k Dec 19, 2022
🌄 Perceptual image hashing for PHP

ImageHash A perceptual hash is a fingerprint of a multimedia file derived from various features from its content. Unlike cryptographic hash functions

Jens Segers 1.9k Dec 28, 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

Piotr Śliwa 879 Dec 30, 2022
Extract colors from an image like a human would do.

ColorExtractor Extract colors from an image like a human would do. Install Via Composer $ composer require league/color-extractor:0.3.* Usage require

The League of Extraordinary Packages 1.2k Jan 1, 2023
php-gd based image templates

gdaisy A highly experimental image templating system based on PHP-GD to dynamically generate image banners and covers. Installation 1. Require erikahe

Erika Heidi 67 Nov 22, 2022
An open source image hosting service powered by Laravel

Limg An open source image hosting service powered by Laravel Features Upload your image via file, url or ShareX ! Manage your image (custom title, pub

Thomas 56 Dec 16, 2022
A simple page view counter that store data as text and shows data as a PNG image

Image Counter A simple page view counter that store data as text and shows the counter as a PNG image.

Victor Ribeiro 10 Apr 19, 2022
Grabs the dominant color or a representative color palette from an image. Uses PHP and GD, Imagick or Gmagick.

Color Thief PHP A PHP class for grabbing the color palette from an image. Uses PHP and GD or Imagick libraries to make it happen. It's a PHP port of t

Kevin Subileau 610 Dec 28, 2022
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

Franck Alary 17 Nov 13, 2022
image sharing site made in PHP just for fun and freetime

2bart image sharing site made in PHP just for fun and freetime To-do list: upload system [DONE] ✔️ views system [DONE] ✔️ image list system [DONE] ✔️

goom 1 Oct 22, 2021
Convert image types. Take samples of pdfs or psd, do some filters as SEPIA, resizes. Save to WEBP

img2img. PHP Converter, sampler of pdfs & psd, do resizes & some filters in images as SEPIA. Save to WEBP V.1.0.3 This class in pure PHP try to manage

Rafael Martin Soto 9 Oct 23, 2022
Alternative image provider for fakerphp using picsum.photos

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

Arnaud Becher 16 Dec 9, 2022