Jump to content

API: resize images on upload


Dennis Spohr
 Share

Recommended Posts

Hi all,

in the backend of ProcessWire it's possible to define a maximum width and height for images. If you upload an image, it will be resized automatically. I find this feature very handy to safe space. Very often users upload images which are much bigger than needed.

On my application users can upload their images via the frontend. But if you upload images using the API, images won't be resized automatically.

Is there any way to do this?

Currently that's my code:

if ($_FILES['thumbnail']['name'])
{
	$upload = new WireUpload('thumbnail');
	$upload->setMaxFiles(1);
	$upload->setOverwrite(true);
	$upload->setDestinationPath($lesson->video_image->path());
	$upload->setValidExtensions(array('jpg', 'jpeg', 'png'));

	$lesson->video_image->removeAll();

	foreach ($upload->execute() as $file)
		$lesson->video_image->add($file);
}

Thanks very much!

Dennis

  • Like 1
Link to comment
Share on other sites

I would use the hook that is called on adding the image to the images field. This is called everytime you add a new image, regardless if you do it via API or via Inputfield.

An up to date code example for this hook is here:

In this example you can check for a $p->template->name to match as condition to run different code parts, etc.
To resize the original image itself, you may want to invoke the imagesizer manually.

----------

Instead of the hook, (for your case above), you only may use the manually invoked ImageSizer for each uploaded file *before* you add it to the image field:

    // set the max dimensions
    $targetWidth = 800;
    $targetHeight = 600;

    foreach($upload->execute() as $file) {

        // first get the filename of the *original image* (in case when hooking into file add !!)
        $filenameOrig = $file;

        // set options to not upscale, and set quality to 100%, if this image is a source for variations!!
        $options = array('upscaling' => false, 'quality' => 100, 'sharpening' => 'soft');

        // call the imagesizer
        $imageSizer = new ImageSizer($filenameOrig, $options);
        $success = $imageSizer->resize($targetWidth, $targetHeight); // resize to max dimensions

        if($success) $lesson->video_image->add($filenameOrig);
    }

 

----------

If you first need to inspect an image, (for conditional processing), you may use the ImageInspector :


    $imageInspector = new ImageInspector();

    foreach($imageFiles as $filename) {
        $result = $imageInspector->inspect($filename);

        // to check if we have a valid result, it must be an array
        if(!is_array($result)) continue;

        // $result['info'] has all relevant data, like width, height, imageType, mime, orientation, rotate, flip, channels, bits, ...
        $width = $result['info']['width']; 
        $height = $result['info']['height'];

        // ...
        
    }

 

  • Like 5
Link to comment
Share on other sites

I just did a test, but unfortunately it doesn't work somehow.

I have the following code:

if ($_FILES['thumbnail']['name'])
{
	$upload = new WireUpload('thumbnail');
	$upload->setMaxFiles(1);
	$upload->setOverwrite(true);
	$upload->setDestinationPath($lesson->video_image->path());
	$upload->setValidExtensions(array('jpg', 'jpeg', 'png'));

	$lesson->video_image->removeAll();

	foreach ($upload->execute() as $file)
	{
            $original = $file;
            $options  = array('upscaling' => false, 'quality' => 100);

            $imageSizer = new ImageSizer($original, $options);
            $success    = $imageSizer->resize(500, 500);

            if ($success)
        	$lesson->video_image->add($original);
	}
}

I always get this error:

Quote

Error: Exception: no valid filename passed to image inspector (in D:\xampp\htdocs\test\wire\core\ImageSizerEngine.php line 428)

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Similar Content

    • By Saleena Jhon
      Hello There, I have saw a post that was covering event-calendar with php, ajax and js. That was showing a monthly overview when I click on a "month" button or when I switch the month. And show the events on one particular date when I pick a day. Also, most events are kind of exhibitions and so they have a start date and an end date much later, and occur on each day in-between as well. So on the template I put two date picking fileds date_start and date_end. Is there an elegant way to select the events using the API? If yes, kindly help me out.
      Thanks in Advance
      Regards: 
       
    • By opalepatrick
      I am working on my first Process Module. I am creating forms. Fairly straightforward. However, I really can't work out how to create multiple fieldsets?
      $fieldset = $this->modules->get('InputfieldFieldset'); $fieldset->label = 'Customer Source'; $field = $this->modules->get('InputfieldPage'); $field->inputfield = 'InputfieldSelect'; $field->findPagesSelector = 'parent_id=1449, include=hidden'; $field->labelFieldName = 'yff-lead'; $field->name = 'yfflead'; $field->columnWidth = 16; $fieldset->add($field); $field = $this->modules->get('InputfieldPage'); $field->inputfield = 'InputfieldSelect'; $field->findPagesSelector = 'parent_id=1452, include=hidden'; $field->labelFieldName = 'customer-type'; $field->name = 'customertype'; $field->columnWidth = 16; $fieldset->add($field); //Rinse and Repeat $fieldset->label = 'Contacts'; $field = $this->modules->get('InputfieldPage'); $field->inputfield = 'InputfieldSelect'; $field->findPagesSelector = 'parent_id=1538, include=hidden'; $field->labelFieldName = 'salutation'; $field->name = 'salutation'; $field->columnWidth = 16; $fieldset->add($field); I can create the first fieldset (Customer Source) but then get into trouble as the second fieldset overwrites the first. I understand why, but trying to use the open and close fieldset routine has flummoxed me. Any help appreciated.
    • By spercy16
      These issues should be fairly easy for any intermediate to advanced ProcessWire developer to answer. I'm new to PHP and relatively new to ProcessWire and just need a bit of help. What I'm trying to do is bring in a couple of cards from my Projects page to display on my home page. I finally got the code right to bring in the cards but right now they're using my original images instead of my resized "variations". So firstly, I would like to know how to reference the variations of my images instead of using the original. Secondly, I need to grab only four of the cards from the Project page and not import in all ten. It should be just two small changes to my code to do these things (I would imagine). Here is the code I currently have for that section:
      <?php // https://processwire.com/api/arrays/ // check if the array of images has items if (count($pages->get("/projects/")->images)) : // get array of images from the field $images = $pages->get("/projects/")->images; $count = 0; // iterate over each one foreach ($images as $image) : $count++; $sectionText = $pages->get("/projects/")->get("paragraph_$count"); $img = $image; $buttonCode = $pages->get("/projects/")->get("url_$count"); ?> <span id="card<?php echo $count?>" class="card"> <img class="cardThumb" src="<?php echo $img->url; ?>" alt="<?php echo $image->description; ?> Thumbnail" /> <div class="cardBody"> <div class="cardText"> <h2><?php echo $img->description; ?></h2> <?php echo $sectionText; ?> </div> <div class="primaryBtn"> <a href="https://www.paypal.com/donate?hosted_button_id= <?php echo $buttonCode; ?> &source=url"> <button> <i class="fas fa-donate"></i> Donate </button> </a> </div> </div> </span> <?php endforeach; endif; ?> Thanks in advance for any help!
    • By VeiJari
      Hello forum, we're trying to use Processwire as our REST-API. We are having problems with our API login to Processwire from frontend. It gives us 403 error.
      We have installed ProcessWire to subdirectory (/api/*) and our frontend is static JS files at root ( / ). Apache access logs gives 404 to our POST-request, but browser devtools shows 403 for our POST /api/login request. 
      Processwire backend panel works. We also have a GET endpoint for the API that returns 200 with correct payload.  So we're wondering why does our GET works but POST doesn't?
      Does this have something to do with Processwire .htaccess, or is this because of our webhost? What should we check first? Any help would be appreciated.
    • By picarica
      so hello there i have fiel field type i have lots of stuff there, and also an image i can easily get image from that field using
                                                        
      $options = array('quality' => 85, 'upscaling' => true, 'cropping' => 'north', 'sharpening' => 'medium'); $word = ".png"; // Test if string contains the word foreach($childgames->subor_hry as $file) { if(strpos($file, $word) !== false){ /* $imger = $file->size(473, 266, $options); */ echo $file; /* echo $file->url; */ } } so i get the fiel i tried invoking size on it like the commented out part and it doesnt work i get error Oh snizzle… Error:     Exception: Method Pagefile::size does not exist or is not callable in this context (in
      what am i doing wrong? can you guys help me by all logic this should work
×
×
  • Create New...