hbarcelos/gd-wrapper

PHP GD2 库的对象封装

v1.0.0 2016-01-05 22:42 UTC

This package is not auto-updated.

Last update: 2024-09-24 19:06:30 UTC


README

GdWrapper 是 PHP GD2 库的对象封装。

安装

使用 composer

将以下代码添加到您的 composer.json

// ...
"require": {
    // ...
    "hbarcelos/gd-wrapper": "dev-master"
}
// ...

然后在您的项目根目录下运行以下命令

$ composer update

要自动加载此库中的类,只需调用默认的 composer 自动加载器

require_once 'vendor/autoload.php';

手动

GdWrapper 兼容 PSR-4,您可以在这里找到示例自动加载器。

组件

资源

表示内存中的图像资源。这些实际上是 GD 的原生资源类型的封装对象。此库支持的所有操作都是在 Resource 对象上完成的。

IO

此包负责图像 IO(从磁盘读取并写回/显示在屏幕上)。每种支持的图像类型都有自己的 IO 类。

几何

简化图像尺寸操作的帮助组件,例如定位、方向、填充等。

操作

可以应用于图像的操作。目前有 3 种受支持的操作

  • 调整大小
  • 裁剪
  • 合并

使用

从磁盘加载图像

如果您只需要加载特定扩展名的文件,可以直接实例化一个针对该扩展名的图像 Reader

use Hbarcelos\GdWrapper\Io\Reader;

$jpegReader = new JpegReader();
$imageResource = $jpegReader->read('/path/to/file.jpg');

对于 gif 和 png 图像,代码类似,只需将 JpegReader 更改为 GifReaderPngReader

当您有更动态的图像输入时,可以考虑使用工厂来简化操作

use Hbarcelos\GdWrapper\Io\ReaderFactory;

$file = '/path/to/file.png';

$readerFactory = new ReaderFactory();
$reader = $readerFactory->create($file); // Will create a factory based on the type of the image

$imageResource = $reader->read($file);

上述代码示例用于创建原始 GD 资源,这些资源用于 GD 库的几乎所有功能。但是,它们很难处理,因为它们不是对象,并且在不再需要时需要手动释放。

使用资源封装

一旦创建了原始资源,就应该将其封装到 Resource 对象中。对于从磁盘读取的图像,有 ImageResource

use Hbarcelos\GdWrapper\Io\Reader;
use Hbarcelos\GdWrapper\Resource\ImageResource;

$jpegReader = new JpegReader();
$imageResource = $jpegReader->read('/path/to/file.jpg');

$objResource = new ImageResource($imageResource);

基于磁盘中的图像创建资源可以通过以下方式委托给 ImageResourceFactory

use Hbarcelos\GdWrapper\Resource\ResourceFactory;

$resourceFactory = new ImageResourceFactory('/path/to/file.jpg');
$objResource = $resourceFactory->create(); // Will create a ImageResource object

您可以通过再次调用 create 方法创建多个基于同一图像的资源

$resourceFactory = new ImageResourceFactory('/path/to/file.jpg');

$objResource = $resourceFactory->create(); // Will create a ImageResource object
$objResource = $resourceFactory->create(); // Will create another ImageResource object for the same image

也可以通过设置新的图像路径(使用 setPathName 方法)来重用相同的工厂为其他图像创建资源对象

$resourceFactory = new ImageResourceFactory('/path/to/file.jpg');

$objResource = $resourceFactory->create(); // Will create a ImageResource object for /path/to/file.jpg

$resourceFactory->setPathName('/path/to/another_file.png');
$objResource = $resourceFactory->create(); // Will create another ImageResource object for /path/to/another_file.png

请注意,您甚至可以更改图像类型。 ImageResourceFactory 足够智能,可以识别这一点并切换到适当的读取器。

生成图像输出

要生成图像输出,必须使用 IO 包中的 Writer 组件。

与读取图像不同,在尝试写入图像时,您应该已经知道您想要的图像格式。

这样可以将 JPEG 图像转换为 PNG

use Hbarcelos\GdWrapper\Resource\ImageResource;
use Hbarcelos\GdWrapper\Io\PngWriter;

$resourceFactory = new ImageResourceFactory('/path/to/file.jpg');
$objResource = $resourceFactory->create(); // Will create a ImageResource object for /path/to/file.jpg

$writer = new PngWriter($objResource->getRaw()); // Writers just need the raw GD resource to work
$writer->write('/path/to/new_file.png'); // will save a PNG image on /path/to/new_file.png

有时,您需要在动态中生成图像而不是输出到文件。在这种情况下,您可以写入 Writer::STDOUT 以使输出发送到标准输出(通常是一个浏览器)

header('Content: image/png'); // This is important to make the image be properly rendered by the browser
$writer->write(PngWritter::STDOUT); // will generate a PNG image binary and send it to the browser

在图像上应用操作

操作以级联方式应用于图像,即执行的操作是累积的:如果您裁剪一个图像然后调整大小,您将调整裁剪后的图像的大小。

调整大小

调整大小可以通过以下三种方式进行

  • 按比例
  • 调整为精确的固定大小
  • 保持纵横比
use Hbarcelos\GdWrapper\Resource\ResourceFactory;
use Hbarcelos\GdWrapper\Action\Resize;
use Hbarcelos\GdWrapper\Action\ResizeMode\Proportional as ResizeProportional;
use Hbarcelos\GdWrapper\Action\ResizeMode\KeepRatio as ResizeKeepRatio;
use Hbarcelos\GdWrapper\Action\ResizeMode\Exact as ResizeExact;

$resourceFactory = new ImageResourceFactory('/path/to/file.jpg');
$objResource1 = $resourceFactory->create();
$objResource2 = $resourceFactory->create();
$objResource3 = $resourceFactory->create(); 

/* Will resize the image to 80% of its original size (both width and height).
 * You can also scale up an image, by passing a value > 1 to ResizeProportional constructor, 
 * but that is inadivisable, since it will deteriorate the image quality.
 */
$resizeMode = new ResizeProportional(0.8); 
$resizeAction = new Resize($resizeMode);

$resizeAction->execute($objResource1); // $objResource1 now refers to the 80%-resized image resource

/* This will resize the image to the exact dimensions passed to ResizeExact construtor (width, height).
 * Needless to say that this can cause distortions (stretching or shrinking) on the image.
 */
$resizeMode = new ResizeExact(400, 300);

$resizeAction->execute($objResource2); // $objResource1 now refers to the 400x300 px resized image resource

/* This is a hybrid resizing mode: you pass both width and length that will be considered the maximum
 * allowed dimensions for the image. 
 *
 * If the image dimensions have the same ratio as the dimensions passed to ResizeKeepRatio constructor, 
 * this action will perform the same way ResizeExact would do.
 * If not, then one of the dimensions will be set to the maximum allowed and the other will be proportionally
 * scaled in order to stay within the predefined limits.
 */

$resizeMode = new ResizeKeepRatio(400, 300); // This is a 4:3 ratio

// Now imagine that $objResource3 refers to an image with 16:9 ratio (1920x1080 px, AKA full HD)
$resizeAction->execute($objResource3); // $objResource1 now refers to a 400x225 px image (keeping the 16:9 ratio)

裁剪

裁剪可以以以下四种方式进行

  • 使用固定尺寸(宽度和高度),基于参考位置
  • 基于固定点,一个作为参考点,另一个用于计算宽度和高度
  • 使用其边缘作为参考,创建“填充”
  • 按比例,基于参考位置
use Hbarcelos\GdWrapper\Resource\ResourceFactory;
use Hbarcelos\GdWrapper\Action\Crop;
use Hbarcelos\GdWrapper\Action\CropMode\Proportional as CropProportional;
use Hbarcelos\GdWrapper\Action\CropMode\FixedDimensions as CropFixedDimensions;
use Hbarcelos\GdWrapper\Action\CropMode\FromEdges as CropFromEdges;
use Hbarcelos\GdWrapper\Action\CropMode\FixedPoints as CropFixedPoints;

use Hbarcelos\GdWrapper\Geometry\Point;

use Hbarcelos\GdWrapper\Geometry\Padding\Fixed as FixedPadding;
use Hbarcelos\GdWrapper\Geometry\Padding\Proportional as ProportionalPadding;

use Hbarcelos\GdWrapper\Geometry\Position\FixedPoint as FixedPointPosition;
use Hbarcelos\GdWrapper\Geometry\Position\Aligned as AlignedPosition;

use Hbarcelos\GdWrapper\Geometry\Alignment\Center;
use Hbarcelos\GdWrapper\Geometry\Alignment\Start;
use Hbarcelos\GdWrapper\Geometry\Alignment\End;

$resourceFactory = new ImageResourceFactory('/path/to/file.jpg');
$objResource1 = $resourceFactory->create();
$objResource2 = $resourceFactory->create();
$objResource3 = $resourceFactory->create(); 
$objResource4 = $resourceFactory->create(); 

/* Point(x,y) represents the (x,y) point of the inverted y-axis cartesian plan.
 * Inverted because the way GD referential point is the top left corner of the image.
 *     The x coordinates increase from left to right.
 *     The y coordinates increase from top to down.
 */


/* Fixed points cropping will be done using the rectangle defined by the $start and $end points.
 *
 * Will generate a 800x500 px image, from the point (0,0) to the point (800,500) of the original image.
 *
 * Imagine this: 
 *
 * .----------------------------------------------------------> 1920 px
 * |(0,0)                     + > 800 px                     |
 * |                          +                              |
 * |                          +                              |
 * |                          +                              |
 * |                          +                              |
 * |                          +                              |
 * |                          +                              |
 * |                          +                              |
 * |++++++++++++++++++++++++++.(500,300)                     |
 * |                          v                              |
 * |                        500 px                           |
 * |                                                         |
 * |                                                         |
 * |                                                         |
 * |                                                         |
 * |                                                         |
 * -----------------------------------------------------------
 *                                                           v
 *                                                         1080 px
 */
$cropMode = new CropFixedPoints(new Point(0,0), new Point(800,500));

$cropAction = new Crop($cropMode);
$crop->execute($objResource1);


/* Padding cropping can be done using fixed paddings...
 *
 * Will Generate a 1720x880 image, cropping out 100 px from each side of the original image.
 *
 * Imagine this:
 *
 * -----------------------------------------------------------> 1920 px
 * |     A 100px                                             |
 * |     V                                             100 px|
 * |     +++++++++++++++++++++++++++++++++++++++++++++++<--->|
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |<--->+++++++++++++++++++++++++++++++++++++++++++++++     |
 * | 100 px                                     100 px A     |
 * |                                                   V     |
 * -----------------------------------------------------------
 *                                                           v
 *                                                         1080 px
 */
$padding = new FixedPadding(100); // --> same padding for both sides
// To use different vertical and horizontal paddings: new FixedPadding(100, 200) --> 100 px on vert. and 200 horiz.
// To use 4 different paddings: new FixedPadding(100, 200, 50, 80) --> top, right, bottom, left
$cropMode = new CropFromEdges($padding);
$crop->execute($objResource2);

/* ... or it can be done with proportional paddings.
 * The proportion will be relative to the original image dimensions.
 *
 * Imagine this:
 *
 * -----------------------------------------------------------> 2000 px
 * |     A 120px                                             |
 * |     V                                             200 px|
 * |     +++++++++++++++++++++++++++++++++++++++++++++++<--->|
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |     +                                             +     |
 * |<--->+++++++++++++++++++++++++++++++++++++++++++++++     |
 * | 200 px                                     120 px A     |
 * |                                                   V     |
 * -----------------------------------------------------------
 *                                                           v
 *                                                         1200 px
 */
$padding = new ProportionalPadding(0.1); // 10%
// Different paddings can be used just like the example above
$cropMode = new CropFromEdges($padding);
$crop->execute($objResource3);

/* FixedDimensionsCrop is a Positioned cropping mode.
 * This means you have to determine a reference position for it.
 * Reference positions can be either a fixed point or anchored to some image notable point (aligned).
 *
 * For fixed point references, the cropping will behave almost like FixedPointsCrop, but you should pass
 * the desired width and height of the cropped image instead of the end point.
 *
 * Imagine this:
 *
 * -----------------------------------------------------------> 1920 px
 * |                                                         |
 * |                                                         |
 * |                                                         |
 * |(200,200).++++++++++++++++++++++++++++++++  A            |
 * |         +                               +  |            |
 * |         +                               +  |            |
 * |         +                               +  |            |
 * |         +                               +  |            |
 * |         +                               +  | 900 px     |
 * |         +                               +  |            |
 * |         +                               +  |            |
 * |         +                               +  |            |
 * |         +                               +  |            |
 * |         +++++++++++++++++++++++++++++++++  V            |
 * |         <----------- 1200 px ----------->               |
 * |                                                         |
 * -----------------------------------------------------------
 *                                                           v
 *                                                         1080 px
 */

$pos = new FixedPosition(new Point(200, 200));
$cropMode = new CropFixedDimensions($pos, 1200, 900);

/* An alignment is either start, center or end, for both vertical and horizontal directions.
 * For the horizontal direction:
 *      start --> left
 *      end   --> right
 *
 * For the vertical direction:
 *      start --> top
 *      end   --> bottom
 */

/* An aligned position consists of a horizontal AND a vertical alignment.
 * The two alignment coordinates will generate a reference point.
 */

/* For aligned reference, the cropping will be aligned to source image anchor points and you should also pass
 * the desired width and height for the cropped image.
 * Imagine this:
 *
 * -----------------------------------------------------------> 1920 px
 * |                                                         |
 * |                                                         |
 * |         +++++++++++++++++++++++++++++++++++++++ A       |
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |         +                                     + | 800 px|
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |         +++++++++++++++++++++++++++++++++++++++ V       |
 * |         <-------------- 1200 px -------------->         |
 * |                                                         |
 * -----------------------------------------------------------
 *                                                           v
 *                                                         1080 px
 */

$pos = new AlignedPosition(new Center());
/* If you want different alingments in horizontal and vertical, you can pass a second argument:
 * $post = new AlignedPosition(new Center(), new Start()); // horizontal, vertical = center, top
 */
$cropMode = new CropFixedDimensions($pos, 1200, 800);
$crop->execute($objResource3);

/* Much like the above example, it's also possible do crop an image proportionally, based on a reference position.
 * The arguments to the CropProportional constructor are the position and the proportio.
 *
 * Imagine this:
 *
 * -----------------------------------------------------------> 2000 px
 * |         A  (10%)                                        |
 * |         V 120 px                                        |
 * |         +++++++++++++++++++++++++++++++++++++++ A       |
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |         +                                     + | 960 px|
 * |         +                                     + |       |
 * |         +                                     + |       |
 * |   (10%) +                                     + |       |
 * |  200 px +                                     + |       |
 * |<------->+++++++++++++++++++++++++++++++++++++++ V       |
 * |         <-------------- 1600 px -------------->         |
 * |                                                         |
 * -----------------------------------------------------------
 *                                                           v
 *                                                         1200 px
 */

合并

@待办