-1

NOTE: it seems some think I am asking the question "Should I use this code style?", but I am actually asking "How can I achieve this?". Sorry If my question is confusing.

To create an image with PHP you can use these kind of base functions:

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

But by default it seems rather static. Example:

/* file: PHPImage.php */

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

// Do some stuff to that image

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

I would like to create a class that can manipulate images on the fly and pass it a function that can manipulate the $img on a call back, and do all of that inline.. something like this:

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

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

I see that this is a feeble example but just wondering if this kind of workflow is possible.

What I'm wondering is: I get that you could pass GET parameters to a constant page setup for this eg. scripts/PHPImage.php?w=160&h=160&bgcol=255-0-0, and then use the passed parameters to run the actual image functions on that page. But is there anyway you could use the actual functions on the image and generate it in a casual workflow, like my PHPImage class example above?

Thanks in advance for any help!

9
  • 1
    This is to broad for stack overflow, like my PHPImage class example above yes make a "wrapper" or "decorator" class. I have a very old one I wrote some years ago not sure how much of it still works. Your welcome to use it as a starting place GitHub. I wrote it for a specific site back in probably 2010, so somethings are only partial implemented, I never got around to finishing it up... :-/ Commented Oct 23, 2018 at 16:42
  • Stack Overflow is not for general design discussions. You have to ask a specific question about code you've written, not advice about code you're considering. Commented Oct 23, 2018 at 16:44
  • You can have your custom class use any signature you want, such as passing $_GET as additional parameter and treat w/h as options. So the answer to your question would be yes. Commented Oct 23, 2018 at 16:47
  • Try use intervention Commented Oct 23, 2018 at 16:48
  • 1
    & should work by reference, but I never tried it with a resource. I imagine it works though, I have yet another class on github that is an ajax wrapper same kind of idea HERE it traps output and exceptions thrown when returning AJAX, something that's incredibly useful. Commented Oct 26, 2018 at 10:02

1 Answer 1

1

For an example

<?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";

I tested this (and it works, mostly, some issues with transparent PNGs) most of the code was taken (and modified) from my image class I mentioned that's on GitHub

Basically any GD functions that accept an image resource from on of the functions in PHPImage::open() would work by feeding it the $image argument inside the callback.

I should note the $image is a resource and not an object, so you have to pass it back with return, you may be able to do it like function(&$image) but I didn't test that.

Enjoy!

Sign up to request clarification or add additional context in comments.

6 Comments

Wow I didn't expect a whole class! Thanks, that all makes sense, so one final question: Do I HAVE to save the image before outputting it in a <img />, I guess I was wondering if I could pass the image data to a php page that is of an image mime type, then use that as the img src. I am happy to tick your answer, just want to check this final point which I poorly worded in my original question!
No, you do not have to save it, you can return it as a base64_encoded() string, and there is some special stuff to put in src... yada yada, you can google and find that easy enough. (something I didn't know when I wrote the original class) Here is a SO post on that stackoverflow.com/questions/8499633/…
Ok thanks, I guess I didn't really know what to search for but that makes sense. Cheers for all your help!
I guess you can capture the output with ob_ output buffering, this other post shows how stackoverflow.com/questions/1206884/… In my original class is a method named render but I never got it to work ... lol (I wrote that about 6 years ago)
I been working on a similar callback for my shutdown/error handler class, basically the idea is to pass it a writer (predefined) or send it a callback, to log, show, email errors. Its HERE but that (and other things) is how I know how to do the bindTo and callback stuff like __invoke cheers.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.