ambroisemaupate / intervention-request
一个可定制的干预图像包装器,用于在URL上使用图像简单重采样功能并配置缓存。
Requires
- php: >=8.0
- ext-curl: *
- ext-gd: *
- intervention/image: ^2.5.1
- league/flysystem: ^3.0
- league/flysystem-memory: ^3.0
- monolog/monolog: ^1.22 || ^2.1.1 || ^3.3.1
- symfony/console: ^4.4 || ^5.0.7 || ^6.4
- symfony/event-dispatcher: ^4.4 || ^5.0.7 || ^6.4
- symfony/filesystem: ^4.4 || ^5.0.7 || ^6.4
- symfony/finder: ^4.4 || ^5.0.7 || ^6.4
- symfony/http-foundation: ^4.4 || ^5.0.7 || ^6.4
- symfony/mime: ^4.4 || ^5.1 || ^6.4
- symfony/process: ^4.4 || ^5.0.7 || ^6.4
Requires (Dev)
- kraken-io/kraken-php: ^1.6
- league/flysystem-async-aws-s3: ^3.0
- league/flysystem-aws-s3-v3: ^3.0
- phpstan/phpstan: ^1.8.4
- squizlabs/php_codesniffer: ^3.5
- symfony/debug: ^4.4 || ^5.0.7 || ^6.4
- symfony/dotenv: ^4.4 || ^5.1 || ^6.4
- symfony/var-dumper: ^4.4 || ^5.0.7 || ^6.4
- tinify/tinify: ^1.5
Suggests
- ext-imagick: Allow TIFF images to be implicitly converted to jpeg.
- kraken-io/kraken-php: Allow Kraken.io listener to optimize images
- tinify/tinify: Allow Tinify API listener to optimize images
- dev-master
- v4.1.1
- v4.1.0
- v4.0.5
- v4.0.4
- v4.0.3
- v4.0.2
- v4.0.1
- v4.0.0
- v3.3.4
- v3.3.3
- v3.3.2
- v3.3.1
- v3.3.0
- v3.2.3
- v3.2.2
- v3.2.1
- v3.2.0
- v3.1.1
- v3.1.0
- v3.0.3
- v3.0.2
- v3.0.1
- v3.0.0
- v2.4.0
- v2.3.0
- v2.2.0
- v2.1.3
- v2.1.2
- v2.1.1
- 2.1.0
- v2.0.0
- v1.0.1
- v1.0.0
- v0.1.9
- v0.1.8
- v0.1.7
- v0.1.6
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- v0.0.2
- v0.0.1
- dev-develop
- dev-feature/avif
This package is auto-updated.
Last update: 2024-09-08 11:26:38 UTC
README
一个可定制的 干预图像 包装器,用于在URL上使用图像简单重采样功能并配置缓存。
- 现成的 Docker 镜像
- 安装
- 配置
- 可用的操作
- 使用独立入口点
- 将作为库在项目中使用
- 使用URL重写
- 使用透明缓存
- 转换为webp
- 强制垃圾收集
- 扩展 Intervention Request
- 性能
- 优化
- 许可证
- 测试
现成的 Docker 镜像
Intervention Request 现在可以作为独立的Docker服务器使用,可用于您需要的任何CMS或语言。它声明了两个卷:一个用于您的图像存储,另一个用于缓存文件。
/var/www/html/web/images
: 您可以将其设置为只读,以防止任何写操作/var/www/html/web/assets
: 您必须将其设置为可写,以允许写入缓存文件
docker pull ambroisemaupate/intervention-request; # Make sure to share your volume with READ-ONLY flag docker run -v "/my/images/folder:/var/www/html/web/images:ro" -p 8080:80/tcp ambroisemaupate/intervention-request;
- 创建一个
/my/images/folder/your-image.png
- 然后尝试 https://:8080/assets/f300x300-s5/images/your-image.png.webp
垃圾收集器每小时作为 crontab
作业运行,并将删除超过 $IR_GC_TTL
秒创建的缓存文件。您仍然可以使用 docker compose exec -u www-data intervention bin/intervention gc:launch
命令手动执行它。
使用本地文件系统或远程文件系统
InterventionRequest 是基于 Flysystem 库构建的,用于抽象对您本地图像的访问。然后您可以将所有图像存储在 AWS 存储桶或 Scaleway 对象存储中,并在运行时处理它们。处理后的图像仍然存储在 InterventionRequest 本地存储中。这个新的文件系统抽象层允许并行运行多个 InterventionRequest Docker 容器,但仍然使用相同的图像后端存储,或者简单地将媒体存储逻辑从 InterventionRequest 应用程序中分离出来。
InterventionRequest
对象需要一个 FileResolverInterface
,可以是 LocalFileResolver
或 FlysystemFileResolver
,然后 FlysystemFileResolver
必须提供一个配置了任何 Flysystem 适配器的 League\Flysystem\Filesystem
对象。
如果您希望使用 ambroisemaupate/intervention-request
Docker 镜像,只有 AWS 适配器才有环境变量可用。
Docker Compose 示例
version: '3' services: intervention: image: ambroisemaupate/intervention-request:latest volumes: # You can store cache in a volume too #- cache:/var/www/html/web/assets - ./my/images/folder:/var/www/html/web/images:ro # You can override some defaults below environment: IR_GC_PROBABILITY: 400 IR_GC_TTL: 604800 IR_RESPONSE_TTL: 31557600 IR_USE_FILECHECKSUM: 0 IR_USE_PASSTHROUGH_CACHE: 1 IR_DRIVER: gd IR_CACHE_PATH: /var/www/html/web/assets IR_IGNORE_PATH: /assets IR_DEFAULT_QUALITY: 80 ## If using local storage file system IR_IMAGES_PATH: /var/www/html/web/images ## If using an AWS or Scaleway Object storage file system IR_AWS_ACCESS_KEY_ID: 'changeme' IR_AWS_ACCESS_KEY_SECRET: 'changeme' IR_AWS_ENDPOINT: 'https://s3.fr-par.scw.cloud' IR_AWS_REGION: 'fr-par' IR_AWS_BUCKET: 'my-bucket' IR_AWS_PATH_PREFIX: 'images' ports: - 8080:80/tcp # Uncomment lines below for Traefik usage #labels: # - "traefik.enable=true" # - "traefik.http.services.intervention.loadbalancer.server.scheme=http" # - "traefik.http.services.intervention.loadbalancer.server.port=80" # - "traefik.http.services.intervention.loadbalancer.passhostheader=true" # # Listen HTTP # - "traefik.http.routers.intervention.entrypoints=http" # - "traefik.http.routers.intervention.rule=Host(`intervention.test`)" # - "traefik.http.routers.intervention.service=intervention" #networks: # - default # - frontproxynet
如果您不打算将此库嵌入到PHP应用程序中,则无需继续阅读。
安装
composer require ambroisemaupate/intervention-request
Intervention Request 基于 symfony/http-foundation 组件来处理HTTP请求、响应和基本文件操作。它使用简单的文件缓存管理包装了 Intervention/image 功能。
配置
使用专用类来配置图像请求参数。在创建 InterventionRequest
对象之前,必须实例化一个新的 AM\InterventionRequest\Configuration
对象,并设置缓存和图像路径。
$conf->setCachePath(APP_ROOT.'/cache'); $conf->setImagesPath(APP_ROOT.'/images');
此代码将在与您的 PHP 脚本相同的文件夹中创建一个包含 cache 和 images 文件的配置。 请注意,在默认的 index.php
文件中,images 路径定义为 /test
文件夹,以便使用测试图像。您应该始终将此路径设置为您的网站图像文件夹,以防止处理其他文件。
您可以使用它们相应的 setter 编辑每个配置参数。
setCaching(true|false)
:是否使用请求缓存将生成的图像存储在文件系统中(默认:true
);setCachePath(string)
:图像缓存文件夹路径;setUsePassThroughCache(true|false)
:是否使用 pass-through 缓存来绕过 PHP 处理一次图像生成;setDefaultQuality(int)
:默认 90,当用户未指定时设置质量量;setImagesPath(string)
:请求图像的根路径;setTtl(integer)
:缓存图像的存活时间,供内部垃圾收集器使用(默认:1 周
);setResponseTtl(integer)
:图像 HTTP 响应的存活时间,供浏览器和代理缓存使用(默认:1 年
);setDriver('gd'|'imagick')
:选择可用的 Image Intervention 驱动器;setTimezone(string)
:PHP 时区用于构建用于缓存的 \DateTime 对象。如果您在php.ini
文件中没有设置它,请在这里设置;setGcProbability(integer)
:垃圾收集器概率除数。垃圾收集器启动概率是 1/$gcProbability,其中概率为 1/1 将在每次请求时启动 GC;setUseFileChecksum(true|false)
:使用文件校验和来测试文件是否不同,即使其名称未更改。此选项可能对大文件很贪婪。(默认:false
)。setJpegoptimPath(string)
:可选 — 告知jpegoptim
二进制文件的 JPEG 后处理位置(除非您需要坚持 100 的质量,否则不适用)。setPngquantPath(string)
:可选 — 告知pngquant
二进制文件的 PNG 后处理位置。 强烈建议使用此后处理工具,因为 PNG 没有它将不会得到优化。setLossyPng(true|false)
:可选 — 告知pngquant
/pingo
二进制文件使用 调色板 有损压缩(默认:false
);
可用的操作
适合位置
由于 URL 重新编写,align
过滤器只能接受一个或两个字母作为值。如果没有指定对齐过滤器,则使用 center
。
使用独立入口点
index.php
文件允许您将其用作独立应用程序。您可以根据需要调整配置来设置您本地的图像文件夹或启用/禁用缓存。
在您的 Web 服务器根目录中设置它,在 intervention-request
文件夹中,并调用此 URL(例如,在计算机上使用包含测试图像的 MAMP/LAMP):https://:8888/intervention-request/?image=images/testPNG.png&fit=100x100
将作为库在项目中使用
InterventionRequest
类与 Symfony 的 Request
和 Response
无缝协作。将其集成到 Symfony 控制器方案中非常容易。
use AM\InterventionRequest\Configuration; use AM\InterventionRequest\InterventionRequest; use AM\InterventionRequest\LocalFileResolver; /* * A test configuration */ $conf = new Configuration(); $conf->setCachePath(APP_ROOT.'/cache'); $conf->setImagesPath(APP_ROOT.'/files'); // Comment this line if jpegoptim is not available on your server $conf->setJpegoptimPath('/usr/local/bin/jpegoptim'); // Comment this line if pngquant is not available on your server $conf->setPngquantPath('/usr/local/bin/pngquant'); $fileResolver = new LocalFileResolver($conf->getImagesPath()); /* * InterventionRequest constructor asks 2 objects: * * - AM\InterventionRequest\Configuration * - AM\InterventionRequest\FileResolverInterface */ $intRequest = new InterventionRequest($conf, $fileResolver); // Handle request and process image $intRequest->handleRequest($request); // getResponse returns a Symfony\Component\HttpFoundation\Response object // with image mime-type and data. All you need is to send it! return $intRequest->getResponse($request);
使用URL重写
如果您想使用干净的 URL,您可以添加 ShortUrlExpander
类来监听缩短的 URL,如:https://:8888/intervention-request/f100x100-g/images/testPNG.png
。
首先,添加一个 .htaccess
文件(或其 Nginx 相当物)来激活重新编写。
# .htaccess # Pretty URLs <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [S=40] RewriteRule . index.php [L] </IfModule>
然后,在处理 InterventionRequest
之前,将这些行添加到您的应用程序中。 ShortUrlExpander
将在您的现有 $request
对象上工作。
use AM\InterventionRequest\ShortUrlExpander; /* * Handle short url with Url rewriting */ $expander = new ShortUrlExpander($request); // Enables using /cache in request path to mimic a pass-through file serve. //$expander->setIgnorePath('/cache'); $params = $expander->parsePathInfo(); if (null !== $params) { // this will convert rewritten path to request with query params $expander->injectParamsToRequest($params['queryString'], $params['filename']); }
快捷方式
可以使用 -
(破折号)字符组合 URL 短路。例如,f100x100-q50-g1-p0
代表 fit=100x100&quality=50&greyscale=1&progressive=0
。
使用透明缓存
干预请求可以将您的图像保存到公共文件夹,以便在生成后由 Apache 或 Nginx 提供服务。这可以减少 首次字节时间,因为不再调用 PHP。
- 确保在将请求代理到 PHP 之前,您已配置 Apache 或 Nginx 来提供真实文件。否则可能会导致文件覆盖!
- 如果使用
ShortUrlExpander
来模拟不带任何查询字符串的真实图像路径,则透传缓存才可用。 - 您的缓存文件夹 必须 是公开的(在您的文档根目录下),这样任何人都可以看到您的文档。如果您的图像必须通过 PHP 防火墙进行保护,则不应激活 透传 缓存。
- 垃圾收集器将不会调用,因为缓存图像将不再由您的 PHP 服务器提供,而是由 Apache 或 Nginx 提供。
- 透传缓存将首次在请求中使用的真实路径上保存图像,确保它不会覆盖任何应用程序文件。
将配置缓存路径定义为公共文件夹。
$conf = new Configuration(); $conf->setCachePath(APP_ROOT . '/cache'); $conf->setUsePassThroughCache(true);
然后启用 ShortUrlExpander
并 忽略您的缓存路径,以仅处理路径信息。
$expander = new ShortUrlExpander($request); // Enables using /cache in request path to mimic a pass-through file serve. $expander->setIgnorePath('/cache');
转换为webp
确保您的 PHP 已编译 WebP 图像格式。
Intervention Request 可以通过向现有图像文件追加 .webp
来自动生成 WebP 图像。
对于 /image.jpg
文件,使用 /image.jpg.webp
。
Intervention Request 将查找没有 .webp
扩展名的图像文件,如果不存在则抛出 404 错误。
强制垃圾收集
使用命令行
bin/intervention gc:launch /path/to/my/cache/folder --log /path/to/my/log/file.log
扩展 Intervention Request
Intervention Request 使用 处理器 来修改原始图像。默认情况下,每个可用的操作都由一个继承自 AbstractProcessor
的类(查看 src/Processor
文件夹)处理。
您可以创建自己的 处理器 并通过向您的 InterventionRequest
对象注入一个数组来覆盖默认的处理器。
/* * Handle main image request with a * custom list of Processors. */ $iRequest = new InterventionRequest( $conf, $fileResolver, $log, [ new Processor\WidenProcessor(), // add or replace with your own Processors ] );
请注意,处理器 在此数组中的位置非常重要,请参阅 InterventionRequest.php
类中的默认处理器。调整大小处理器应该是第一个,质量处理器应该是最后一个,因为图像操作将按照您处理器的顺序执行。
添加自定义事件订阅者
如果您需要在图像提供服务之前对其进行优化/修改,可以创建自定义操作,使用 ImageSavedEvent
和 Symfony 事件系统。
创建一个实现 ImageEventSubscriberInterface
的类,并例如监听 ImageSavedEvent::NAME
。
public static function getSubscribedEvents() { return [ ImageSavedEvent::class => 'onImageSaved', ]; }
此事件将携带一个包含所有您需要优化/修改内容的 ImageSavedEvent
对象。然后,使用 $interventionRequest->addSubscriber($yourSubscriber)
方法来注册它。
可用事件
监听器示例
WatermarkListener
将在您的图像上打印文本。KrakenListener
将使用 kraken.io 外部服务优化您的图像文件。TinifyListener
将使用 tinyjpg.com 外部服务优化您的图像文件。JpegTranListener
将使用本地的jpegtran
二进制文件优化您的图像文件。
当然,您可以构建自己的监听器并与我们分享!
性能
如果您的 Intervention-request 抛出类似错误
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 5184 bytes).
这是因为您正在尝试处理一个过大的图像。解决方案是增加您的 memory_limit
PHP 设置,超过 256M
。您可以在服务器的 php.ini
文件中编辑此文件。
如果您的托管计划允许您动态更改 PHP 配置,您可以在 index.php
文件中使用 ini_set('memory_limit', '256M');
。
一般来说,我们鼓励您在使用 Intervention-request 之前始终降低您原始图像的大小。
优化
jpegoptim
如果您在服务器上安装了 jpegoptim
,您可以将其添加到您的配置中。
$conf->setJpegoptimPath('/usr/local/bin/jpegoptim');
pngquant
如果您在服务器上安装了 pngquant
,您可以将其添加到您的配置中。
$conf->setPngquantPath('/usr/local/bin/pngquant'); $conf->setLossyPng(true); // use palette lossy png compression - default: false
oxipng
如果您在服务器上安装了 oxipng
,您可以将其添加到您的配置中。
$conf->setOxipngPath('/usr/local/bin/oxipng');
pingo
如果您在服务器上安装了 pingo
和 Wine
,您可以将其添加到配置中。
$conf->setPingoPath('/usr/local/bin/pingo.exe'); $conf->setLossyPng(true); // use palette lossy png compression - default: false $conf->setNoAlphaPingo(true); // Remove png transparency to compress more - default: false
kraken.io
如果您订阅了付费的 kraken.io 计划,您可以添加专门的 KrakenListener
以将缩放后的图片发送到外部服务。
$iRequest->addSubscriber(new \AM\InterventionRequest\Listener\KrakenListener( 'your-api-key', 'your-api-secret', true, $log ));
请注意,图片将通过 kraken.io API 发送,这将需要额外的时间。
tinyjpg.com
如果您订阅了付费的 tinyjpg.com 计划,您可以添加专门的 TinifyListener
以将缩放后的图片发送到外部服务。
$iRequest->addSubscriber(new \AM\InterventionRequest\Listener\TinifyListener( 'your-api-key', $log ));
请注意,图片将通过 kraken.io API 发送,这将需要额外的时间。
jpegtran
如果您想使用系统中的 jpegtran
或 Mozjpeg,您可以使用 JpegTranListener
。
$iRequest->addSubscriber(new \AM\InterventionRequest\Listener\JpegTranListener( '/usr/local/opt/mozjpeg/bin/jpegtran', $log ));
优化基准
默认质量为 90%。
AVIF 转换仅支持自定义编译的 ImageMagick,并且仅支持无损编码。
许可证
Intervention Request 由 Ambroise Maupate 精心制作,遵循 MIT 许可证。
祝您玩得开心!
测试
将 index.php
复制到 dev.php
,然后使用 router.php
作为路由器启动 PHP 服务器命令。
php -S 0.0.0.0:8088 -t web router.php
然后在浏览器中打开 http://0.0.0.0:8088/dev.php/w300/rhino.jpg
。您应该能够测试启用 ShortUrl 的 intervention-request。
如果您想测试 pass-through 缓存,取消注释 dev.php
中的第 46 和 56 行,然后打开 http://0.0.0.0:8088/dev.php/cache/w300/rhino.jpg
。第一次请求将由 PHP 处理(查看响应头),然后后续请求将直接由您的服务器处理(不再有 Intervention Request 头部)。