loops/gdimage

辅助GD库导入、转换、导出图像。此库提供:GIF支持、JPEG支持、PNG24支持、PNG8支持、动画GIF支持、APNG支持、HTTP支持、数据URI支持、调色板颜色增强(特别是GD透明颜色泄漏),调整大小(裁剪、适应、填充),颜色过滤

2.9.1-RC 2016-04-12 14:02 UTC

This package is auto-updated.

Last update: 2024-09-09 13:27:56 UTC


README

要求

至少PHP 5.3,GD库是必需的。

如何使用它

自动加载

如果您没有composer,请调用bootstrap

:::php
  require $path_to_library.'/bootstrap.inc.php';

此库使用PSR-0与一个命名空间,并可能永远不会转到PSR-4。

图像格式

此库支持GIF、JPEG、PNG24、PNG8、AGIF(动画GIF)和APNG。

导入

基本用法

您可以从许多来源导入图像:文件、二进制、base64、数据URI...

它们都通过 \GDImage\Factory::import() 方法处理。

:::php
  $image = \GDImage\Factory::import( $stuff );

绕过

为了优化性能,您可能想绕过工厂层。在这种情况下,您可以使用任何 \GDImage\Image_Interface 的相应方法绕过文件或二进制导入。

:::php
  // import file as GIF
  $image = new \GDImage\Image_Gif();
  $image->fromFile( $filepath );

  // import binary as PNG
  $image = new \GDImage\Image_Png();
  $image->fromBinary( $filepath );

在导入时绕过工厂层,您必须知道图像的MIME类型。

导出

基本用法

您可以将图像导出到多种格式:文件、二进制数据、base64数据、数据URI方案...

它们都通过 \GDImage\Factory::export() 方法处理。

:::php
  // export to file
  // on file export, if no extension is specified on the filepath, it will be 
  // automatically added
  $final_filepath = \GDImage\Factory::export( $image , $filepath );

  // export to data URI
  $data_uri = \GDImage\Factory::export( $image , 'data' );

  // export to base 64
  $data_uri = \GDImage\Factory::export( $image , 'base64' );

  // export to binary
  $data_uri = \GDImage\Factory::export( $image , 'binary' );

  // export to output
  \GDImage\Factory::export( $image , 'output' );

强制MIME类型

如果您希望将图像强制导出到预期的MIME类型,可以这样做。

:::php
  // export to file with PNG MIME Type
  $final_filepath = \GDImage\Factory::export( $image , $filepath , 'image/png' );

导出参数

如果您需要额外的导出参数,第二个参数可以是一个数组。

:::php
  // export to data URI without base 64 encoding and MIME Type
  $data_uri = \GDImage\Factory::export( $image , array(
    'driver' => 'DataUri' ,
    'base64' => false ,
    'mimetype' => false ,
  ) );

未命名的参数将传递到最终的GD函数(如 imagejpeg()、imagepng()...),但您必须知道将使用哪个函数。

:::php
  // export to file with JPEG MIME Type and 75 quality
  $final_filepath = \GDImage\Factory::export( $image , array(
    'driver' => 'File' ,
    'file' => $filepath ,
    95 ,
  ) , 'image/jpeg' );

  // export to file with PNG MIME Type, 8 compression level and all PNG filters
  $final_filepath = \GDImage\Factory::export( $image , array(
    'driver' => 'File' ,
    'file' => $filepath ,
    8 ,
    PNG_ALL_FILTERS ,
  ) , 'image/png' );

绕过

为了优化性能,您可能想绕过工厂层。在这种情况下,您可以使用任何 \GDImage\Image_Interface 的相应方法绕过文件或二进制导出。

:::php
  // export to file
  $success = $image->toFile( $filepath );

  // export to binary
  $binary = $image->toBinary();

转换

理念

转换是在图像实例上应用以修改其资源或动画图像的资源。

通过分离图像操作和图像资源,相同的转换可以安全地应用于任何图像。

:::php
  $image = \GDImage\Factory::import( $import_filepath );
  $transform = new \GDImage\Transform_GaussianBlur();
  $image->apply( $transform );
  $final_filepath = \GDImage\Factory::export( $image , $export_filepath );

主要转换

以下是主要转换列表

\GDImage\Transform_Resize_Fit:将图像缩放到最大尺寸,使其宽度和高度都适合区域。最终的宽度和高度可能小于预期,但不一定都小于预期。

:::php
  $image = \GDImage\Factory::import( $import_filepath );
  $transform = new \GDImage\Transform_Resize_Fit( 300 , 300 );
  $image->apply( $transform );
  $final_filepath = \GDImage\Factory::export( $image , $export_filepath );

如果您只想使图像适应预期的宽度,可以这样操作

:::php
  $image = \GDImage\Factory::import( $import_filepath );
  $transform = new \GDImage\Transform_Resize_Fit( 300 , \PHP_INT_MAX );
  $image->apply( $transform );
  $final_filepath = \GDImage\Factory::export( $image , $export_filepath );

\GDImage\Transform_Resize_Crop:将图像缩放到最大尺寸,使其完全覆盖区域。图像的一些部分将被裁剪,最终的宽度和高度将与预期完全一致。

:::php
  $image = \GDImage\Factory::import( $import_filepath );
  $transform = new \GDImage\Transform_Resize_Crop( 300 , 300 );
  $image->apply( $transform );
  $final_filepath = \GDImage\Factory::export( $image , $export_filepath );

\GDImage\Transform_Resize_FitNFill:将图像缩放到最大尺寸,使其宽度和高度都适合区域。空白区域将被透明颜色填充,以确保最终的宽度和高度与预期完全一致。

:::php
  $image = \GDImage\Factory::import( $import_filepath );
  $transform = new \GDImage\Transform_Resize_FitNFill( 300 , 300 );
  $image->apply( $transform );
  $final_filepath = \GDImage\Factory::export( $image , $export_filepath );

您可以指定填充的颜色

:::php
  $image = \GDImage\Factory::import( $import_filepath );
  // fill with white
  $transform = new \GDImage\Transform_Resize_FitNFill( 300 , 300 , 'FFFFFF' );
  $image->apply( $transform );
  $final_filepath = \GDImage\Factory::export( $image , $export_filepath );

还有很多其他的转换,所以请不要犹豫去查看测试案例或 Transform 文件夹。

多个转换

您可以将多个转换组合成一个。

:::php
  $image = \GDImage\Factory::import( $import_filepath );
  $transform = new \GDImage\Transform_Multiple(
    new \GDImage\Transform_Grayscale() ,
    new \GDImage\Transform_Negate()
  );
  $image->apply( $transform );
  $final_filepath = \GDImage\Factory::export( $image , $export_filepath );

注册转换

您可以注册一个转换,甚至是多个转换,以便以后使用。通过这种方式,所有您的转换都可以放在一个地方,无论您在哪里使用它们。

:::php
  $resize = new \GDImage\Transform_Resize_Fit( 300 , 300 );
  \GDImage\Transform_Collection::set( 'a_key_for_the_transformation' , clone $resize );
    (...)
  $image = \GDImage\Factory::import( $import_filepath );
  $image->apply( \GDImage\Transform_Collection::get( 'a_key_for_the_transformation' ) );
  $final_filepath = \GDImage\Factory::export( $image , $export_filepath );

自定义转换

每个转换都必须实现 \GDImage\Transform_Interface

请注意,转换应用于资源实例,而不是图像。

:::php
  class MyTransform implements \GDImage\Transform_Interface
  {
    /**
     * Apply transformation to a resource.
     * Return false if the transformation fails.
     *
     * @param \GDImage\Resource_Abstract &$rsc
     * @return boolean Success flag
     * @access public
     */
    public function __invoke( \GDImage\Resource_Abstract &$rsc )
    {
      // your stuff here

      return true || false;
    }
  }

gd_image() 辅助函数

为了简化所有图像导入、转换和导出过程,一个单独的函数可以为你处理所有这些麻烦: gd_image()

在您的代码中的任何位置调用方法 \GDImage\Config::helper()gd_image() 函数将在全局命名空间中可用。

此函数接受三个参数

  1. $import:要导入的内容,必填;
  2. $export:导出参数,必填但可以是 null
  3. $transform:要应用的转换,可选;
  4. $failure:在失败时执行或返回的值,可选。

$import

如预期的那样,$import 参数可以是 \GDImage\Factory 可以导入的任何内容:文件路径、数据 URI、Base64 数据、二进制数据等...

\GDImage\Factory::import() 方法相比,唯一的区别是没有 MIME 类型转换。

$export

如预期的那样,$export 参数可以是 \GDImage\Factory 可以使用的任何导出内容:文件路径、驱动程序名称、导出参数、驱动程序类名称、驱动程序实例等...

\GDImage\Factory::export() 方法相比,第一个区别是没有 MIME 类型转换。

$export 参数还有额外的行为

  • 一个 null 导出将导致 文件导出

  • 如果 $export 是以 "-" 或 "_" 开头的字符串,则该字符串将被视为 文件导出的后缀

  • 如果 $import 是文件路径并且文件导出未指定文件名,文件导出将使用相同的文件名

  • 如果 $import 不是一个文件路径并且文件导出未指定文件名,文件导出将使用 $import 的 MD5 哈希作为文件名

  • 如果 $transform 不为 null 并且文件导出未指定文件名或后缀,则转换键 — 或以下划线 "_" 前缀的类名 — 将用作 文件名的后缀

  • 如果 $import 是文件路径并且文件导出未指定目录,文件导出将使用相同的目录

  • 如果 $import 不是一个文件路径并且文件导出未指定目录,文件导出将使用系统临时目录

  • 如果 $import 是具有创建日期的文件路径 — 或 HTTP 中的 Last-modified 标头 — 并且如果文件导出导致已存在的文件,如果其创建日期高于 $import,则不会生成新文件。

这些行为可以相互交互,因此请参阅下面的使用部分以获取更多信息。

$transform

$transform 可以是已注册转换的键、转换类名称(完全限定或位于 \GDImage 命名空间中)、\GDImage 转换类后缀(\GDImage\Transform_*)或转换实例。

请注意,不以 "\" 开头的转换类名称可能对应于 \GDImage 转换而不是全局转换。请小心。

$failure

如果出现问题,将触发 E_USER_WARNING 错误,并返回 false。此行为可以通过 $failure 参数进行自定义

  • 如果 $failure 是可调用的,它将被执行,并通过 gd_image() 辅助函数返回其结果 — 此回调的参数是:抛出的 \GDImage\Exception 实例、$stuff 参数、$export 参数和 $transform 参数;

  • 如果 $failure 不可调用且不为 null,则它将在失败时用作返回值 — 仍然会触发错误。

使用方法

将文件路径与后缀导出相同

:::php
  $final_filepath = gd_image( $import_filepath , '_suffix' [, $transform] );

从转换中导出到相同的文件路径后缀

:::php
  $final_filepath = gd_image( $import_filepath , null , 'transform_key' );
  $final_filepath = gd_image( $import_filepath , null , $transform );
  $final_filepath = gd_image( $import_filepath , null , 'Sepia' );
  $final_filepath = gd_image( $import_filepath , null , 'Transform_Negate' );
  $final_filepath = gd_image( $import_filepath , null , '\\GDImage\\Transform_Grayscale' );

将文件导出到另一个目录中的转换后缀

:::php
  $final_filepath = gd_image( $import , $directory , $transform );

导出到 Base64

:::php
  $final_filepath = gd_image( $import , 'base64' [, $transform] );

导出到没有 MIME 类型的数据 URI

:::php
  $final_filepath = gd_image( $import , array(
    'driver' => 'data' ,
    'mimetype' => false ,
  ) [, $transform] );

AGIF 和 APNG

本库支持动画GIF(AGIF)和动画PNG(APNG)。

“可见”状态

大多数具体的动画图像都是一些优化的结果:移除了多余的像素信息,并将帧减小到最小尺寸。

在这些优化后的动画图像中,实际状态的帧只是噪点像素,无法正确利用。

这就是为什么这个库总是提供“可见”状态的帧:每个分解帧适合图片大小,如果另一个帧应该在后面完成透明像素,它就会这样做。

对于具有混合选项为1(覆盖混合)的APNG帧也是如此:在这种情况下,分解帧是两个帧合并的结果,并且关闭混合选项以避免重新组合错误。

注意,在AGIF中,具有不同调色板的两个帧的合并可能产生256种以上颜色的真彩色帧。

命名

为了方便起见,帧属性从规范中获取其名称。AGIF使用延迟时间(get/setDelayTime())和丢弃方法(get/setDisposalMethod()),而APNG使用延迟分子(get/setDelayNumerator())、延迟分母(get/setDelayDenominator())和丢弃选项(get/setDisposeOption())。

目前没有统一化,也没有计划。

优化

动画图片优化是可行的,但过程非常漫长:每个帧都必须进行分析,与前一帧进行比较,然后减小到其最小尺寸。

默认情况下,优化是禁用的,但可以通过使用\GDImage\Config::setAGifComposerOptimization()\GDImage\Config::setAPngComposerOptimization()设置来启用。

这些设置是位运算的这些位

  • 1:在帧边缘移除透明像素;
  • 2:在帧上移除多余的像素——从丢弃帧到当前帧;
     borders;
    
  • 4:替换多余的像素——从丢弃帧到当前帧的
     frame by transparent color.
    

我们强烈建议在动画图片在后台任务生成时启用动画图片优化,在按需生成时禁用它。

示例

将所有包放到您本地服务器上的gdimage文件夹中,然后您将能够在https:///gdimage/demo/index.php中看到GDImage的实际操作。

如果您想测试特定的图像,只需将其放入demo/samples文件夹中并运行演示。

此外,此项目没有单元测试,但主要测试用例可以从该演示中获得。

接下来是什么?

色度变换

在图片上应用色度变换(双色到N色)应该很酷。
具有X种颜色的图片将转换为具有N种用户定义颜色的图片(没有自动颜色确定,这很烦人)。

为什么不选择Imagick?

托管历史

这个库是为具有Imagick扩展的托管而创建的——是的,有一些。

由于许多库实现了它,因此对于提供Imagick的托管解决方案,这个库可能没有意义。

分而治之

我也不欣赏Imagick的设计方式:将所有东西都放在一个巨大的类中听起来像:“这个类可以调整大小、颜色过滤、文件导出、咖啡、脚部按摩……”

在GDImage库中,有四个基本层:资源句柄GD资源、转换操作资源、图像处理资源和工厂管理图像。这可能不是实现图像操作的最佳方式,但它相对容易维护和扩展。

POOP实现

这是什么POOP?

POOP(许可面向对象编程)是一些建议,主张自愿省略protectedprivate可见性,仅使用public

  • POOP并不脏
  • POOP不是无用的
  • POOP不是危险的
  • POOP不是困难的

POOP不是废物。

伪受保护属性/方法

该库遵循POOP模式,这意味着每个属性和方法都是public的,即使它们应该被视为protected

为了区分真正是public的属性/方法和应该被视为protected的属性/方法,需要考虑以下约定:

  • 如果属性/方法以单个下划线 "_" 开头,应视为pseudo-protected如果你不清楚自己在做什么,不要使用它

  • 如果属性以两个下划线 "__" 开头,应视为需要特别小心的pseudo-protected如果你不确定自己在做什么,不要操作它,因为它可能引起重大问题

  • 如果方法以两个下划线 "__" 开头,它是一个“魔法”PHP方法,可以视为public

POOP on \GDImage\Transform_*

你可能注意到,所有的\GDImage\Transform_*类都只有设置器。

实际上,在变换上有获取器似乎没有意义,因为变换只需要参数,当你分配参数时,你已经知道了它们,不是吗?

当然,这些参数中的一些可能在分配之前被操作,所以为了帮助POOP,如果你出错,你仍然可以直接获取它们。

贡献者

想贡献吗?

请访问这里: https://bitbucket.org/lxxps/gdimage/src