Silverstripe - 覆盖 Image.php - 可能性?
Silverstripe - Overwrite Image.php - possibilities?
每当 Silverstripe 从图像创建调整大小的版本时,系统也会生成该图像的 webp 版本。
通过 .htaccess
然后我可以将使用 chrome 浏览器的用户转发到这个 webp image
.
到目前为止,我的想法是扩展 image.php
class,问题是扩展不能覆盖现有方法。
有什么方法可以让我在从模板调用 $Image.setWidth(200)
时仍然可以执行此操作,我的函数将是 运行?
我的目标仍然是防止更改所有可行的方法名称。
$Image.webpSetWidth(200)
可以与普通图片扩展一起使用。但如果可能的话,我会避免这种情况。
检查了 Image.php
(和 GD.php
)是否有可能扩展它,但至少在 Silverstripe 3.6
中是不可能的。
更新:
感谢 Brett 的提示,我找到了正确的方向。
<?php
class WebPGDBackend extends GDBackend
{
public function writeTo($filename)
{
parent::writeTo($filename);
if (function_exists('imagewebp')) {
$picname = pathinfo($filename, PATHINFO_FILENAME);
$directory = pathinfo($filename, PATHINFO_DIRNAME);
list($width, $height, $type, $attr) = getimagesize($filename);
switch ($type) {
case 2:
if (function_exists('imagecreatefromjpeg')) {
$img = imagecreatefromjpeg($filename);
$webp = imagewebp($img, $directory.'/'.$picname.'.webp');
$gif = imagegif($img, $directory.'/'.$picname.'.gif');
}
break;
case 3:
if (function_exists('imagecreatefrompng')) {
$img = imagecreatefrompng($filename);
imagesavealpha($img, true); // save alphablending setting (important)
$webp = imagewebp($img, $directory.'/'.$picname.'.webp');
}
}
}
}
}
每当保存调整大小的图像(以 jp(e)g/png 格式)时,这将创建一个 webp 副本。
为了使其工作,必须使用适当的标志编译 gdlib。
此外,您必须通过以下方式将 class 添加到 config.php
Image::set_backend("WebPGDBackend");
.
请记住,这仅适用于新调整大小的图形。
有了上面的内容,就可以配置 .htaccess
将 jpeg/png 请求转发给理解 webp
的浏览器到新图形。
我通过以下代码片段意识到这一点:
<IfModule mod_rewrite.c>
RewriteEngine On
# Check if browser support WebP images
RewriteCond %{HTTP_ACCEPT} image/webp
# Check if WebP replacement image exists
RewriteCond %{DOCUMENT_ROOT}/.webp -f
# Serve WebP image instead
RewriteRule (assets.+)\.(jpe?g|png)$ .webp [T=image/webp,E=accept:1]
</IfModule>
<IfModule mod_headers.c>
Header append Vary Accept env=REDIRECT_accept
</IfModule>
<IfModule mod_mime.c>
AddType image/webp .webp
</IfModule>
我不确定 SS 3.6 是否具有开箱即用的功能来生成此内容,但是您可以使用 ImagickBackend 并通过扩展对其进行修改以适应。
例如
<?php
if(class_exists('Imagick')) {
class MyImagickBackend extends ImagickBackend {
// default format to use
private static $format = 'webp';
public function __construct($filename = null) {
parent::__construct($filename);
$this->setImageFormat( Config::inst()->get('MyImagickBackend','format') );
}
}
然后在 _config.php
中,您只需将后端设置为用于图像
Image::set_backend("MyImagickBackend");
注意: 这确实需要安装 ImageMagick 并启用 PHP 模块。
注意:这里没有直接测试,所以可能需要为webp设置其他ImageMagick参数
参考文献:
http://php.net/manual/en/book.imagick.php
https://github.com/silverstripe/silverstripe-framework/blob/3.6/filesystem/ImagickBackend.php
每当 Silverstripe 从图像创建调整大小的版本时,系统也会生成该图像的 webp 版本。
通过 .htaccess
然后我可以将使用 chrome 浏览器的用户转发到这个 webp image
.
到目前为止,我的想法是扩展 image.php
class,问题是扩展不能覆盖现有方法。
有什么方法可以让我在从模板调用 $Image.setWidth(200)
时仍然可以执行此操作,我的函数将是 运行?
我的目标仍然是防止更改所有可行的方法名称。
$Image.webpSetWidth(200)
可以与普通图片扩展一起使用。但如果可能的话,我会避免这种情况。
检查了 Image.php
(和 GD.php
)是否有可能扩展它,但至少在 Silverstripe 3.6
中是不可能的。
更新:
感谢 Brett 的提示,我找到了正确的方向。
<?php
class WebPGDBackend extends GDBackend
{
public function writeTo($filename)
{
parent::writeTo($filename);
if (function_exists('imagewebp')) {
$picname = pathinfo($filename, PATHINFO_FILENAME);
$directory = pathinfo($filename, PATHINFO_DIRNAME);
list($width, $height, $type, $attr) = getimagesize($filename);
switch ($type) {
case 2:
if (function_exists('imagecreatefromjpeg')) {
$img = imagecreatefromjpeg($filename);
$webp = imagewebp($img, $directory.'/'.$picname.'.webp');
$gif = imagegif($img, $directory.'/'.$picname.'.gif');
}
break;
case 3:
if (function_exists('imagecreatefrompng')) {
$img = imagecreatefrompng($filename);
imagesavealpha($img, true); // save alphablending setting (important)
$webp = imagewebp($img, $directory.'/'.$picname.'.webp');
}
}
}
}
}
每当保存调整大小的图像(以 jp(e)g/png 格式)时,这将创建一个 webp 副本。
为了使其工作,必须使用适当的标志编译 gdlib。
此外,您必须通过以下方式将 class 添加到 config.php
Image::set_backend("WebPGDBackend");
.
请记住,这仅适用于新调整大小的图形。
有了上面的内容,就可以配置 .htaccess
将 jpeg/png 请求转发给理解 webp
的浏览器到新图形。
我通过以下代码片段意识到这一点:
<IfModule mod_rewrite.c>
RewriteEngine On
# Check if browser support WebP images
RewriteCond %{HTTP_ACCEPT} image/webp
# Check if WebP replacement image exists
RewriteCond %{DOCUMENT_ROOT}/.webp -f
# Serve WebP image instead
RewriteRule (assets.+)\.(jpe?g|png)$ .webp [T=image/webp,E=accept:1]
</IfModule>
<IfModule mod_headers.c>
Header append Vary Accept env=REDIRECT_accept
</IfModule>
<IfModule mod_mime.c>
AddType image/webp .webp
</IfModule>
我不确定 SS 3.6 是否具有开箱即用的功能来生成此内容,但是您可以使用 ImagickBackend 并通过扩展对其进行修改以适应。
例如
<?php
if(class_exists('Imagick')) {
class MyImagickBackend extends ImagickBackend {
// default format to use
private static $format = 'webp';
public function __construct($filename = null) {
parent::__construct($filename);
$this->setImageFormat( Config::inst()->get('MyImagickBackend','format') );
}
}
然后在 _config.php
中,您只需将后端设置为用于图像
Image::set_backend("MyImagickBackend");
注意: 这确实需要安装 ImageMagick 并启用 PHP 模块。
注意:这里没有直接测试,所以可能需要为webp设置其他ImageMagick参数
参考文献:
http://php.net/manual/en/book.imagick.php
https://github.com/silverstripe/silverstripe-framework/blob/3.6/filesystem/ImagickBackend.php