使用 PHP 函数创建图像,但使用“内联”代码

Posted

技术标签:

【中文标题】使用 PHP 函数创建图像,但使用“内联”代码【英文标题】:Create image using PHP functions, but with "inline" code 【发布时间】:2018-10-23 16:38:39 【问题描述】:

注意:似乎有些人认为我在问“我应该使用这种代码风格吗?”,但我实际上是在问“我怎样才能做到这一点?”。抱歉,如果我的问题令人困惑。

要使用 php 创建图像,您可以使用这些基本函数:

http://php.net/manual/en/ref.image.php

但默认情况下,它看起来相当静态。示例:

/* file: PHPImage.php */

$img = imagecreatefrompng('logo.png');

// Do some stuff to that image

header('Content-type: image/png');
imagepng($img);
imagedestroy($img);

我想创建一个可以动态操作图像的类,并将一个可以在回调中操作$img 的函数传递给它,然后内联执行所有这些操作......像这样:

<?php
    $img = new PHPImage("baseimage.png", function(&$thisimg)
        // Color functions here etc
    );
?>

<img src="<?php echo $img->URLResource; ?>" />

我看到这是一个微不足道的例子,但我想知道这种工作流程是否可行。

我想知道的是:我知道您可以将 GET 参数传递给一个常量页面设置,例如。 scripts/PHPImage.php?w=160&amp;h=160&amp;bgcol=255-0-0,然后使用传递的参数在该页面上运行实际的图像功能。但是,您是否可以在图像上使用实际功能并在随意的工作流程中生成它,就像我上面的 PHPImage 类示例一样?

提前感谢您的帮助!

【问题讨论】:

这是对堆栈溢出的扩展,like my PHPImage class example above 是的,创建一个“包装器”或“装饰器”类。我有一个很旧的,几年前写的,不知道有多少仍然有效。欢迎您使用它作为起点GitHub。我大概在 2010 年为一个特定的网站写了它,所以有些东西只是部分实现,我从来没有时间完成它...... :-/ Stack Overflow 不适用于一般设计讨论。您必须针对您编写的代码提出具体问题,而不是针对您正在考虑的代码提出建议。 您可以让您的自定义类使用您想要的任何签名,例如将 $_GET 作为附加参数传递并将 w/h 作为选项。所以你的问题的答案是肯定的。 尝试使用intervention &amp; 应该通过引用工作,但我从未尝试过使用资源。我想它可以工作,我在 github 上还有另一个类,它是一个 ajax 包装器,类似的想法 HERE 它捕获输出和返回 AJAX 时抛出的异常,这非常有用。 【参考方案1】:

举个例子

<?php
echo "<pre>";

class PHPImage
    protected $callback;
    protected $src = '';
    protected $image = null;
    protected $type = null;

    public function __construct($src, $callback=null)
        $this->src = $src;
        $this->type = exif_imagetype($this->src);
        $this->image = $this->open($this->src);

        $this->callback = $callback->bindTo($this); 
        //bingTo, changes scope to this class
        //that lets us access internal methods
        //for exmaple if we had a method PHPImage::hight($image);
        //we could access it using $this->height($image); from inside
        //the callback  function($image) $height = $this->height($image); 
    

    public function execute()
        if(!$this->callback)return false;
        $this->image = $this->callback->__invoke($this->image); //call the magic method __invoke ($this->callback(), is not a method)
        return $this; //for  method chaining  $obj->foo()->bar();
    

    public function open($src)
        //if called directly
        $type = $this->type ? $this->type : exif_imagetype($src);
        switch($type)
        
            case IMAGETYPE_GIF:
                return imagecreatefromgif($src);
                break;
            case IMAGETYPE_JPEG:
                return imagecreatefromjpeg($src);
                break;
            case IMAGETYPE_PNG:
                $image = imagecreatefrompng($src);
                imagealphablending($image, true); // setting alpha blending on
                imagesavealpha($image, true); // save alphablending setting (important)
                return $image;
                break;
            case IMAGETYPE_WBMP:
                return imagecreatefromwbmp($src);
                break;
            default:
                throw new Exception('Unknown image type', 1);
        
    

    public function save($dest, $res=90)
        switch($this->type)
            case IMAGETYPE_GIF:
                imagegif($this->image, $dest, $res);
                break;
            case IMAGETYPE_JPEG:
                imagejpeg($this->image, $dest, $res);
                break;
            case IMAGETYPE_PNG:
                $res = ceil($res*0.1); //convert from 0-100 to 1-10
                imagepng($this->image, $dest, $res);
                break;
            case IMAGETYPE_WBMP:
                imagewbmp($this->image, $dest, $res);
                break;
            default:
                throw new Exception('Unknown image type',1);
        
    




(new PHPImage('C:\UniServerZ\www\artisticphoenix\public_html\wp\wp-content\uploads\2018\10\ajax.png', function($image)
    return imagerotate($image, 90, 0);
))->execute()->save(__DIR__.'/new.png');

echo "Complete";

我对此进行了测试(它的工作原理主要是透明 PNG 的一些问题)大部分代码是从我提到的 GitHub 上的图像类中获取(和修改)的。

基本上,任何从PHPImage::open() 中的函数接受图像资源的GD 函数都可以通过在回调中提供$image 参数来工作。

我应该注意$image 是一个资源而不是一个对象,所以你必须将它传回并返回,你也许可以像function(&amp;$image) 那样做,但我没有测试过。

享受吧!

【讨论】:

哇,没想到整节课!谢谢,这一切都说得通,所以最后一个问题:我是否必须在将图像输出到 之前保存图像,我想我想知道是否可以将图像数据传递给图像的 php 页面mime 类型,然后将其用作 img src。我很高兴勾选您的答案,只是想检查一下我在原始问题中措辞不佳的最后一点! 不,你不必保存,你可以将它作为base64_encoded()字符串返回,还有一些特殊的东西要放入src... yada yada,你可以google并发现这很容易。 (我写原始课程时不知道的事情)这是***.com/questions/8499633/…的SO帖子@ 好的,谢谢,我想我真的不知道要搜索什么,但这是有道理的。为你的帮助干杯! 我猜你可以使用ob_ 输出缓冲来捕获输出,这篇文章展示了***.com/questions/1206884/… 在我原来的类中是一个名为render 的方法,但我从来没有让它工作.. . 大声笑(我大约 6 年前写过) 我一直在为我的关闭/错误处理程序类处理类似的回调,基本上的想法是向它传递一个编写器(预定义)或向它发送一个回调,以记录、显示、发送电子邮件错误。它的HERE 但这(和其他事情)是我知道如何做bindTo 和回调的东西,如__invoke 欢呼。

以上是关于使用 PHP 函数创建图像,但使用“内联”代码的主要内容,如果未能解决你的问题,请参考以下文章

函数探幽

内联函数知识点

内联函数和宏比较

用内联取代宏代码

C# 使用 SmtpClient 发送内联图像的邮件

避免 if 语句的内联函数指针