GithubHelp home page GithubHelp logo

avalanche123 / imagine Goto Github PK

View Code? Open in Web Editor NEW
4.4K 129.0 532.0 14.8 MB

PHP Object Oriented image manipulation library

Home Page: https://imagine.readthedocs.io

License: Other

PHP 99.64% Shell 0.36%

imagine's Introduction

Imagine

PHPUnit Coding Style

Tweet about it using the #php_imagine hashtag.

Image manipulation library for PHP inspired by Python's PIL and other image libraries.

Requirements

The Imagine library has the following requirements:

  • PHP 5.5+

Depending on the chosen Image implementation, you may need one of the following PHP extensions:

  • GD2
  • Imagick (with ImageMagick version 6.2.9 or later, except version 7.0.7-32)
  • Gmagick

To read EXIF metadata (e.g. for autorotation), activate the PHP exif extension. This is optional: Imagine works without the PHP exif extension, but then it can't read and act on image orientation or other EXIF metadata.

Installation using composer

php composer.phar require imagine/imagine

Basic Principles

The main purpose of Imagine is to provide all the necessary functionality to bring all native low level image processing libraries in PHP to the same simple and intuitive OO API.

Several things are necessary to accomplish that:

  • Image manipulation tools, such as resize, crop, etc.
  • Drawing API - to create basic shapes and advanced charts, write text on the image
  • Masking functionality - ability to apply black&white or grayscale images as masks, leading to semi-transparency or absolute transparency of the image the mask is being applied to

The above tools should be the basic foundation for a more powerful set of tools that are called Filters in Imagine.

Some of the ideas for upcoming filters:

  • Charting and graphing filters - pie and bar charts, linear graphs with annotations
  • Reflection - apple style
  • Rounded corners - web 2.0

Documentation

Presentations

Articles

Contributing

Branches

New pull requests should be based on the develop branch. The master branch is the stable branch: it usually matches the latest a release but in can be a bit ahead.

Test groups

Some PHPUnit test is marked as skipped (for example, tests that require a driver that support multiple layers and executed with the GD driver). In addition, if you don't have installed gmagick, the gmagick tests will be marked as skipped.

If you don't want to run tests that are marked as "always skipped" you can tell PHPUnit to exclude the always-skipped group. The same for the tests that require a specific driver (gd, imagick, imagick).

So, for example, to exclude the always-skipped and the gmagick tests, you can launch phpunit with this command options:

composer run test -- --exclude-group always-skipped,gmagick

Development environment

Setting up an environment with all the required libraries may be very hard. In order to run the tests locally, you can use the same docker images used by Imagine to test the pull requests.

For example, if you have Imagine locally in the /home/me/imagine folder, you can run tests for PHP 8.1 with the GD and Imagick with this very simple approach:

  1. Launch a temporary docker container with:
    docker run --rm -it -v /home/me/imagine:/app -w /app ghcr.io/php-imagine/test:8.1-gd-imagick bash
  2. Inside the docker container, run these commands:
    # Start a local web server: some tests require it
    cd tests
    php -n -S 0.0.0.0:8013 >/dev/null 2>&1 &
    cd ..
    # Tell the tests that the local web server is available at the port 8013
    export IMAGINE_TEST_WEBSERVERURL=http://localhost:8013
    # Install the composer dependencies
    composer update
    # Run the tests
    composer run test -- --exclude-group always-skipped,gmagick

Note: This approach works on Windows too: simply launch the docker container with

docker run --rm -it -v C:\Path\To\Imagine:/app -w /app ghcr.io/php-imagine/test:8.1-gd-imagick bash

Built test files

Many tests create temporary files (in the tests/tmp directory) containing built images. Those temporary files are compared with expected images, and then are deleted. If you want to keep those temporary files (for example, to check what's being built), you can set the IMAGINE_TEST_KEEP_TEMPFILES environment variable. If the IMAGINE_TEST_KEEP_TEMPFILES is configured in the GitHub Action tests, those temporary files are attached to tests as an articact.

imagine's People

Contributors

alexander-schranz avatar andreybolonin avatar anthonysterling avatar armatronic avatar ausi avatar avalanche123 avatar burzum avatar chellem avatar chregu avatar christeredvartsen avatar jmikola avatar lashus avatar lenar avatar localheinz avatar lsmith77 avatar mitsuhiko avatar mlocati avatar nicodmf avatar ninze avatar nokrosis avatar ornicar avatar radekdvorak avatar rejinka avatar richtermeister avatar rjkip avatar romainneutron avatar rouffj avatar seldaek avatar thepanz avatar vlakoff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

imagine's Issues

Error handler, should one be added?

I was working with a Gd adapter in Imagine today and I encountered a problem where an error was triggered because of a bug.
Shouldn't we add a default error handler to catch these errors and throw exceptions?
I've just adapted the error handler from Symfony real quickly. Would you like me to open a pull request?

<?php

  namespace Imagine\Error;

  /*
   * This file is part of the Symfony package.
   *
   * (c) Fabien Potencier <[email protected]>
   *
   * For the full copyright and license information, please view the LICENSE
   * file that was distributed with this source code.
   */

  /**
   * Adapted PHP error handler.
   * Original design by Fabien Potencier
   *
   * @author Fabien Potencier <[email protected]>
   */
  class ErrorHandler
  {

    /**
     * @var array
     */
    protected $_levels;

    /**
     * @var string
     */
    protected $_level;

    /**
     * @var string
     */
    protected $_previousErrorHandler;

    /**
     * Instantiate an error handler and tell it to which level of errors it
     * should listen to.
     *
     * If no error level is given it will default to the PHP ini setting.
     *
     * @param   integer $arg_level
     *
     * @return  void
     */
    public function __construct ($arg_level = NULL)
    {
      $this->_level  = NULL === $arg_level ? error_reporting() : $arg_level;
      $this->_levels = array(E_WARNING           => 'Warning'
                            ,E_NOTICE            => 'Notice'
                            ,E_USER_ERROR        => 'User Error'
                            ,E_USER_WARNING      => 'User Warning'
                            ,E_USER_NOTICE       => 'User Notice'
                            ,E_STRICT            => 'Runtime Notice'
                            ,E_RECOVERABLE_ERROR => 'Catchable Fatal Error'
                            );
    }

    /**
     * Register the error handler.
     *
     * @return  void
     */
    public function register ()
    {
      $this->_previousErrorHandler = set_error_handler(array($this, 'handle'));
    }

    /**
     * Unegister the error handler and re-register the original error handler.
     *
     * @return  void
     */
    public function unregister ()
    {
      set_error_handler($this->_previousErrorHandler);
    }

    /**
     * Handle a specific error
     *
     * @param   string  $arg_level    
     * @param   string  $arg_message  
     * @param   string  $arg_file     
     * @param   string  $arg_line     
     * @param   string  $arg_context  
     *
     * @return  boolean 
     *
     * @throws  ErrorException  
     */
    public function handle ($arg_level, $arg_message, $arg_file, $arg_line, $arg_context)
    {
      if (0 === $this->_level)
      {
        return FALSE;
      }

      if (error_reporting() & $arg_level && $this->_level & $arg_level)
      {
        throw new \ErrorException(sprintf('%s: %s in %s line %d', isset($this->_levels[$arg_level]) ? $this->_levels[$arg_level] : $arg_level, $arg_message, $arg_file, $arg_line));
      }

      return FALSE;
    }

  }

quality parameter not working for png-files

Hi,

using the quality parameter doesn't affect filesize when the output is png. When outputting for example jpg the parameter is working.

->save($file, array('quality'=>'90'))

Resize method creates horrible images in Imagick.

For a number of reasons I can't use your thumbnail method for creating, well, thumbnails, and so I make a new canvas of known size and then paste a resized version of my original into it.

In Imagick, the resize method uses "adaptiveResizeImage" with rather horrible results. Is there a reason for this rather than a "thumbnailImage" call with known dimensions. It provides much nicer looking images for some reason.

I have got round this by using the Imagine thumbnail method for resizing instead of resize but it is quite a limitation, especially as in GD resize has much higher quality results.

Thanks.

Dom

E_NOTICE: Undefined constant 'IMAGETYPE_SWC'

Apparently the 'IMAGETYPE_SWC' constant is not available for all PHP 5.3 builds. I get the following PHP E_NOTICE level error when using Imagine:

Notice: Use of undefined constant IMAGETYPE_SWC - assumed 'IMAGETYPE_SWC'

I commented it out for now in my own copy of the lib, but I know that's not a permanent solution.

Creating a new release

The master branch is currently the 0.1.5 release which is 4 months old. The library changed a lot since then, including changing the namespace of the interface. This makes the old releases incompatible with the current code using Imagine (in the bundle for instance). You should IMO release a new version of the library as it confuse people to have an outdated version of the library when cloning it.

Can't saveOrOutput gif image with more than 256 transparent pixels, Exception is throwed...

lib/Imagine/Gd/Image.php

private function saveOrOutput($format, array $options, $filename = null, Color $background = null)
.... Image type GIF ....
$color = $background ? $background : new Color('ffffff');
.... Iteration through each pixel ....
imagesetpixel($this->resource, $x, $y, $this->getColor($color));

The problem is that gif image only have 256 colors and when you are trying to allocate more imagecolorallocatealpha returns false and Imagine throws exception.

To fix that you just need to change code like below:

.... Image type GIF ....
$color = $background ? $background : new Color('ffffff');
$gdColor = $this->getColor($color);
.... Iteration through each pixel ....
imagesetpixel($this->resource, $x, $y, $gdColor);

Thank you...

Reduce memory usage?

I'm resizing and adding a border to a 1Mb image and the script uses about 80Mb.

Works fine on my local machine with php.ini > memory limit = 128M

But my shared host has it hardcoded to 64M (can't change via .htaccess nor ini_set() )

So I get:

Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 13219521 bytes)

Is there any way to reduce Imagine's memory usage? Thanks!

Further font drawing capabilities

First of all, thumbs up for (finally) building a promising image manipulation library in PHP that's elegant and easy to handle.

And not sure if this is within the scope of Imagine at all but all the inconsistencies and hacks regarding to using non-standard fonts on the web (even now) kind of leave me wishing for a good PHP library that handles some 'advanced' things related to drawing text.

Some things I'd wish Imagine could do beyond basic font drawing are: the already requested word-wrapping (and a way to set the line height), letter spacing (plus maybe word spacing) and probably the most difficult/intense task to implement across all 'drivers': anti-aliasing.

I have been trying to find a suitable library for these things and never found anything that's "good enough" in terms of the output and the usability. (Been a while since I have been looking around, recommendations welcome!)

I think this would be a great step towards making Imagine more complete and as extended charts functions are already targeted, it would be great to have fonts covered as well.

(Also I was hesitant to make this an 'issue' at all but I guess this is the best way to put this up for discussion.)

Premature end of JPEG file

Using Imagine for importing images (with SonataMediaBundle), I've got this error :

Notice: imagecreatefromjpeg() [function.imagecreatefromjpeg]:gd-jpeg, libjpeg: recoverable error: Premature end of JPEG file

Line 157 in Imagine.php

Is it possible to have a try/catch, an exception or else for detecting this problem ?

Thanks !

Gravity support for drawing + Wrapping text

Hi

First off, great idea and great library.

I use gravity (imagemagick) extensively for draw operations, so have hacked it in in a few places. Wondered if there was any reason you've not supported this? My guess is that its because its imagemagick only so makes the api inconsistent - which seems like a good reason!

Anyhow, I digress, should you be interested in this, I can look at working it in properly and submitting a pull request.

I've also cobbled together a way to wrap text within a box as well - any interest in supporting this? I think this should be possible across all three existing supported image tools.

Ben

Color overlay

I can't tell from the docs if this is possible, but I would like to overlay a png with a solid color, while maintaining transparency.

This feature would be useful for changing the color of icons on the fly. Is this currently possible?

doc ticket: meaning of inset / outbound

Hey There

It's nowhere really explained which one is inset and which one is outbound. Adding that to the documentation would be very helpful.

Thank you.

Pascal Helfenstein

Cropping to small number fails

I tried cropping a 700x360 image to 100x10 and got the following exception

OutOfBoundsException: Crop coordinates must start at minimum 0, 0 position from top left corner, crop height and width must be positive integers and must not exceed the current image borders.

at Image->thumbnail(object(Box), 'outbound')

Don't have time to investigate right now so if someone else does..

Feature Request: Getter method for Image->ressource

Hi,
first thing - thanks for that beautiful library. I really appreciate to work with it.
There is one small question left for me:
If i try to make a FilterInterface to manipulate the color of an image like this:

class Color implements FilterInterface
{
    private $color;
    
    public function __construct($value)
    {
        $ratio = max($value, 255);
        
        $this->color = new \Imagine\Image\Color('fff');
        $this->color->darken($value);
    }
    
    public function apply(ImageInterface $image)
    {
        imagefilter($image->resource, IMG_FILTER_COLORIZE, 
            $this->color->getRed(), 
            $this->color->getGreen(), 
            $this->color->getBlue()
        );

        return $image;
    }
}

there is no way to get receive the resource of the image because it's a private property. I also
haven't found a getter method. So might it make sense to create a getter, or do I only have some heavy knots in my thoughts?

Thanks

Imagine\Imagick\Image::supported() is not implemented

I am in the process of adding PDF preview support. I am guessing this feature will not be included as GD doesn't support PDFs. I'm using Imagine together with ImagineBundle.

I did some tests to see whether this is possible at all and it most certainlty seems to be. With a couple of line changes here and there I was able to make Imagine save the filtered preview images without any problems.

I also noticed that Imagine\Imagick\Image::supported() is not implemented. For me this causes issues when displaying the image for the first time. It's called in Imagine\Imagick\Image::getMimeType, which itself is used for defining the Content-type header.

Default background color

Hello.
How i can set the default background color for a new image?
E.g.: i want make a new image on basics of old image, but with wider canvas. In this case, background in new image will be filled with black color, but i need a way to change it.

In gd2 library i'm using imagefill() function for this.
Thanks.

Choose a resolution for loading PDFs in Imagick

Imagick has the fantastic ability to load PDFs (and myriad other formats that GD won't support) but for these there has to be a conversion from real world units into pixels. This is as simple as changing:

$imagick = new \Imagick($path);

to (for 72 dpi)

$imagick = new \Imagick();
$imagick->setResolution(72, 72);
$imagick->readImage($path);

in the open method. It would be really nice if this could be incorporate, maybe using an options array similar to the way the options array works for saving.

Many thanks for all your hard work on this and sorry for posting all these irritating requests. It's a really great tool.

PHP native hexadecimal

I'm mostly posting this here as a feature request and reminder: would it be better to use PHP native way to work with hexadecimal notation?

E.g.

$color = new Imagine\Image\Color(0xFFFFFF);

How can I access an Imagick instance in a filter?

I need this in order to e.g.

  • trim image (Imagick's trimImage function)
  • make progressive JPEG (setInterlaceScheme)
  • choose the most colorful corner to apply watermark (getImageRegion function)

Extending Imagine\Imagick\Image is not possible as this is final class.

Scaling Images to a max height/width and filling the rest with a color

This library is awesome, however I don't know where I can find support, so i hope it's cool if I ask a question here.
Basically I've written this code where i can pass a target width and height and it will scale an image so that it uses the height or the width as ceiling. that is if I have an image of 150_150 and put it in my functio with the params 140_100 it will scale to 100*100.

however now I'd like to place that image centered on a 140*100 white canvas. Is that possible?
Code so far

$imagine = new \Imagine\Gd\Imagine();
        try {
            $image = $imagine->open($source_path);
        } catch (Exception $e) {
            return false; // image not present
        }
        $target_ratio = ($height) ? $width / $height : 0;
        $source_ratio = ($image->getSize()->getHeight()) ? $image->getSize()->getWidth() /
         $image->getSize()->getHeight() : 1;
        //Handle images that have a different aspect ratio than the target ration
        if ($target_ratio !== $source_ratio) {
            $scale = 0;
            if ($source_ratio > $target_ratio) {
                if ($image->getSize()->getWidth() > $width) {
                    $scale = $width / $image->getSize()->getWidth();
                }
            } else {
                if ($image->getSize()->getHeight() > $height) {
                    $scale = $height / $image->getSize()->getHeight();
                }
            }
            if ($scale !== 0) {
                $image->resize(
                $image->getSize()
                    ->scale($scale));
            }
        } else {
           // ratio is equal
            if ($image->getSize()->getWidth() != $width) {
                $image->resize(
                $image->getSize()
                    ->scale(
                $width / $image->getSize()
                    ->getWidth()));
            }
        }
        $options = array('quality' => $quality);
        try {
            $image->save($target, $options);
        } catch (Exception $e) {
            return false;
        }

Can't save files without an extension

We store files in a way like /storage/images/jpg/31/5D/K3/ without an extension. By using Imagine as an image processing engine this becomes an issue for us because you have to pass an extension to the output file.

Please make it possible to override the current behavior of mapping the extension to an output format by maybe passing a "format" option to the options array. If the "format" is set in the options the code could ignore the extension and instead use the passed format.

Let me know if my proposed solution is ok for you and I might fix it in my branch.

crop option to center

When using crop the image is cropped starting from the left side of the image,
it would be nice to center the larger side.

For example if you have 150x100 image, want to crop to 100x100
the start position should be 25px using this option, instead 0.

Get color at position

It's not possible to get a color of point in the image.
It would be nice to have new method:

Image::getColorAt($x, $y);

returning Color object.

Would do you think about this?

Wrong Filesystem class

Hi guys,

Since a recent update of symfony I have this error and Imagine doesnt work anymore:

Catchable Fatal Error: Argument 5 passed to Avalanche\Bundle\ImagineBundle\Controller\ImagineController::__construct() must be an instance of Symfony\Component\Filesystem\Filesystem, instance of Symfony\Component\HttpKernel\Util\Filesystem given, called in /Users/pb/Sites/affilae/www/app/cache/dev/appDevDebugProjectContainer.php on line 911 and defined in /Users/pb/Sites/affilae/www/vendor/bundles/Avalanche/Bundle/ImagineBundle/Controller/ImagineController.php line 60

Thank you for your help,

Regards.

Crop to Mask

Is there a way to crop to a mask? (that is, a binding box that contains all non-transparent pixels from a grayscale mask)

Feature Request: Output Filters

I'm not sure if this can be already done somehow, the doc page says "More filters and advanced transformations is planned in the nearest future.".

I would like to know if you plan on creating output filters that would allow a user for example to have a custom filter to cache versions of the image and store them in the file system or upload them into a cloud. A filter would be interesting here because we have our own storage abstraction for local FS remote services like cloud services. Similar to http://framework.zend.com/manual/de/zend.cloud.storageservice.html

If you plan on something like that let me know and share your ideas you might already have, I might implement it in a branch.

Edit: I've checked the current code and I do not think what I want is possible because the image manipulations are already applied before I can intercept it somehow and check for a cached version of the file. I might be wrong if so please correct me.

GD image copy looses alpha

When using Image->copy() on the gd implementation on a png image with alpha, the alpha information is lost.

[Upstream] upcoming phar-build change, whitespace/comment stripping in phar

Hopefully, when my PR for phar-util is accepted (see koto/phar-util#14), I see Imagine wanting to take advantage of the new feature; in most of my own tests on working phars, the size has dropped by approximately 40-50% in well-commented code.

The phar-build line in the makefile would likely need to be changed to this (the only change is the addition of the --strip-files flag and param):

phar-build -s ./lib/Imagine -S ./.stub --phar ./imagine.phar --ns --strip-files ".php$"

I'd appreciate it if this issue were marked as "research" for the time being until the associated pull-request for phar-util is merged, thanks!

Imagine\Image\ManipulatorInterface::show() does not set headers correctly

Shouldn't Imagine\Image\ManipulatorInterface::show() be setting the content-type header?

I would submit a pull request, but I cant find the image function that is passed to call_user_func_array() that would be responsible for setting the headers (in Gd/Image.php). Maybe you would want to set the header in the show() method its self..

Imagick and IPTC headers

I know it is not possible to preserve IPTC headers while using the GD adapter, bug Imagick supports this (I guess Gmagick does as well).

It would be nice if resize() could also resize images like THUMBNAIL_INSET does, but maintain IPTC information. And thumbnail() could get rid of the IPTC headers since you probably do not want to increase file size of your thumbnails.

accept streams in ImagineInterface

it would be nice to support stream resources in the ImagineInterface. right now there is only open (for filesystem paths) and load (for strings). actually maybe there should be one method that can consume all 3 formats (path, string, resource).

Drivers rotate in different directions

Gd seems to be rotating the images counter-clockwise while Imagick and Gmagick rotates clockwise. The following code will therefore not generate the same image:

$imagine = new Imagine\Gd\Imagine();
print($imagine->open('/path/to/file.png')->rotate(90));

and

$imagine = new Imagine\Imagick\Imagine();
print($imagine->open('/path/to/file.png')->rotate(90));

Is this intentional behaviour in Imagine or should it be expected that the different drivers produce the same output given the same input?

Add method to change saturation

I would like a method to change an image's saturation (using imagick->modulateImage) but have no clue how to achieve comparable results with gd. Converting the image pixel by pixel to HSV seems not a good idea ...

PSR-0 Vendor Name

Are there plans to bring the namespacing inline with PSR-0? There's no vendor name for this library so the product name clashes with another vendor, and because of the ImageInterface and ImagineInterface being only one-level up on the namespace, separation won't work with most autoloaders.

phar file not loading

When i get the phar from master or devel branch and do:

include 'phar://imagine.phar';
var_dump(class_exists('Imagine\Image\ImageInterface'));

var_dump prints false. I'm using php 5.3.3, and Imagick 3.0.0RC1. No errors in the apache log, file is readable.

any idea why this would be happening?

GD breaks behaviour

While using Imagick everything goes fine, and when you attempt to save to a directory without permissions and exception is thrown as expected.

However, while using GD, a warning is thrown along with the return false. Which breaks the flow in developer machines where warnings are errors.

Unfortunately, for you to avoid this the only way to do it is calling the GD function using the '@' operator in order to maintain the proper flow.

I hate using this surpressor, and would much rather see PHP itself fix the GD extension to function as the Imagick does, but what do you think about this?

Gd and Imagick/Gmagick font problems

There are 2 main font problems for these libraries;

  1. Gd library has hard-coded resolution 96, while Imagick/Gmagick have 72 by default (tuneable), so Gd will produce larger symbols for same text, size, font than imagick. Workaround for this is to calculate Gd specific font size like this
    code>$size *= 72 / 96;

    So to handle this correctly Font (or maybe some other) class should respect current resolution.
    See also http://bugs.php.net/bug.php?id=15656
  2. Second problem is bounding box calculation. Gd does it pretty well (assuming it was provided correct font size to its resolution, see p.1) but Imagick gives much larger height than needed (possibly 15% larger than Gd). However it provides more exact width than Gd (about 5%) and some more useful information, such as ascender/descender height. The problem is that both libraries are inperfect in calculating bbox, so while Gd behaves better Imagick only users will suffer from its incorrect bbox calculation.
    Gmagick provides slightly different results from Imagick and it seems it doesn't support font antialiasing (see links in P.P.S. further)
    Ideas on solving this:
  3. Combine results from two libraries.
    Drawbacks: low performance, no library isolation
    Advantages: exact results
  4. Report about bugs to upstream
    Drawbacks: nobody knows when (and if) it will be done
    Advantage: library isolation, exact results
  5. Create own layer in Imagine
    Drawbacks: hard task (both libraries use FreeType as backend), possibly slow performance due to php implementation
    Advantage: library isolation, exact results

More?

P.S. I used imageftbbox for bbox calculation in GD and queryfontmetrics in Imagick.
P.P.S. Comparing results Imagick/Gmagick with Gd:
Imagick with GD: http://pastie.org/1794355 (save code on your computer by clicking download on left upper corner and open it in your browser)
Gmagick with GD: http://pastie.org/1794360 (same instrucations as above)
PHP code that was used for generation: http://pastie.org/1794364. For proper running you need a webserver with enabled gd with imagick either gmagick (but not both) and fix the path to the font in the beginning of the script.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.