Jump to content
97s

$image->size(); configuration questions

Recommended Posts

So in general I really love how PW does its sizing and centers the focus on the picture so if you size it different that its true aspect ratio it focuses on the center of the picture, which in general is perfect for what we need.

However, I was wondering if it was possible to change the parameters of where it focuses on. I am doing a photography website and I have some really awesome vertical images that are getting clipped at the top where the top is the most important part of the models picture.

I am wondering if anyone has any good advice on how to best approach this issue inside of Process Wire Where does the magic happen and can I adjust it?

You can see the issue here: http://peterson-medi...io/people/ Third row down, 3rd right picture(unless he moves it, or your browser is narrow in width, basically just any of the pictures with the heads cut off :-[ .)

I would just make the layout different, but since this layout is fully responsive and changes sizes drastically I need to figure out how to do this.

I was hoping to maybe write some php that would check to see if the height parameters of the picture were bigger than the width, then if so, focus on the top of the picture instead of the middle.

Thanks a lot, and I hope someone can help me figure this one out.

Share this post


Link to post
Share on other sites

Okay, so I completely missed this the first time I was looking over $image configurations.

$image->size($width, $height, $options)Return a new $image with the given dimensions. By default it will get upscaled and center cropped with a quality of 90%. To resize and keep proportions you can 0 for height or width value. As third argument you can pass an array to overwrite the default settings: $defaultOptions = array( 'upscaling' => true, 'cropping' => true, 'quality' => 90 );

If there was a 3rd option for cropping not to be center focused, and instead upward focused? or can I write one to be somewhere?

So it would be nice if I could do a check for height, then if over a certain height I could do 'cropping' => upward or something.

  • Like 1

Share this post


Link to post
Share on other sites

Looking at what I am wanting to do, I can definitely use PW to check the height of the image($image->height;), then write something to then take a thumbnail using upward cropping instead of center crop, I just need to know how to get PW to upward crop.

Share this post


Link to post
Share on other sites

A couple of options for you might be:

  1. Antti's Thumbnails module: http://modules.processwire.com/modules/fieldtype-crop-image/ - for the images where centre cropping isn't sufficient.
  2. something like phpThumb where you can specify a zone to crop from - top left, centre left, top middle etc. To do that you could have a custom field with each of phpThumbs as an option.

Regards

Marty

  • Like 1

Share this post


Link to post
Share on other sites

I am trying to use Antti's thumbnails module but im having a hard time understanding how to pull the thumbnails into my template.

I guess I will make a post on that thread, then reply with the answer here for future users.

Share this post


Link to post
Share on other sites
If there was a 3rd option for cropping not to be center focused, and instead upward focused? or can I write one to be somewhere?

There will be soon. Just need to figure out how to do it. :) But that's part of the reasons the $options array is there, so that we can include additional options like crop direction.

  • Like 1

Share this post


Link to post
Share on other sites

There will be soon. Just need to figure out how to do it.

Ryan, I have bookmarked a ImageClass on github which has this functionality. I never used this class, your ImageSizer and Antti's Thumbnails where alwas sufficant for me, but maybe you can copy some lines from there?

https://github.com/s...Images.php#L151

Edit:

Now I think this class isn't very useful for this. The time I bookmarked it I thought it is great, but now with some weeks working with php and PW at least cropping part of this class looks pretty simple. It guess PW made me learn some php.

  • Like 2

Share this post


Link to post
Share on other sites

The image manipulation stuff gets into a math territory that my mind has always had trouble with. So much of what you see in the ImageSizer class is adapted from things learned in comments at php.net. I have no doubt that others here may be more adept at expanding the utility of the ImageSizer class, so if anyone is interested in working on it and adding a crop direction option to it, I'd welcome the help. Otherwise, I hope to have this figured out by PW 2.4. My thought is that the crop direction option would be specified with one of: NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast, as a grid:

NorthWest North NorthEast

West Center East

SouthWest South SouthEast

This is similar to the -gravity option from ImageMagick, if anyone is familiar with that.

Share this post


Link to post
Share on other sites

I just tested this proposed gravity like cropping hardcoded in ImageSizer.php

I have not done any proper implementation using the options array yet, just some dirty hacking, but it seems to work. For a proper implementation we should reflect the cropping direction in the generated url too I guess? But the math part was simple like this. This code replaces line 208 - 211 in ImageSizer.php of the dev branch:

btw, I replaced "imagecopyresampled()" by "imagecopyresized()", as we are not doing any resizing in this line, just cropping. The resizing is already done when this code get executed. Should give slightly better performance?

    // centercrop defaults:
 $w1 = ($gdWidth - $targetWidth ) / 2;
 $h1 = ($gdHeight - $targetHeight) / 2;
    // read the crop direction from options, hardcoded for testing only:
    $cropDirection = 'southeast';
    switch (strtolower($cropDirection)) {
	    case 'northwest':
		    $w1 = 0;
		    $h1 = 0;
		    break;
	    case 'north':
		    $h1 = 0;
		    break;
	    case 'northeast':
		    $w1 = $gdWidth - $targetWidth;
		    $h1 = 0;
		    break;
	    case 'west':
		    $w1 = 0;
		    break;
	    case 'east':
		    $w1 = $gdWidth - $targetWidth;
		    break;
	    case 'southwest':
		    $w1 = 0;
		    $h1 = $gdHeight - $targetHeight;
		    break;
	    case 'south':
		    $h1 = $gdHeight - $targetHeight;
		    break;
	    case 'southeast':
		    $w1 = $gdWidth - $targetWidth;
		    $h1 = $gdHeight - $targetHeight;
		    break;
    }
 imagecopyresized($thumb2, $thumb, 0, 0, $w1, $h1, $targetWidth, $targetHeight, $targetWidth, $targetHeight);
  • Like 1

Share this post


Link to post
Share on other sites

Thanks Interrobang this is great!

For a proper implementation we should reflect the cropping direction in the generated url too I guess?

Perhaps so, but practically speaking I wonder if it's worth it. This being an API function rather than an interactive one, it seems like the developer be setting a default position and sticking to it.

I replaced "imagecopyresampled()" by "imagecopyresized()", as we are not doing any resizing in this line, just cropping. The resizing is already done when this code get executed. Should give slightly better performance?

It sounds like you know the workings of these functions a lot better than I do. I've always been a bit confused by the various GD function names. :) But I'm good with whatever you think produces a better result.

Share this post


Link to post
Share on other sites

+1 from me. I always end up with different cropping scenarios. What I have been doing when I don't use Antti's thumbnails module is wrap my images in an HTML container with overflow:hidden, then resize the image and position it inside my container to look like it's cropped from the direction I wanted it cropped by. Kinda fake, not ideal, but good in a pinch ;)

  • Like 1

Share this post


Link to post
Share on other sites

It sounds like you know the workings of these functions a lot better than I do. I've always been a bit confused by the various GD function names. :) But I'm good with whatever you think produces a better result.

Actually, I just read the docs and comments on php.net. This is the first time I have used any of the php image functions. The math part is the only thing I already was familiar with as I had to do things like that a lot back when I was making flash websites with actionscript.

You are probably right, that in the moment the options don't need to be reflected in the resized image url. On the long way, if you want to implement some basic image filters like grayscale and blur it would get necessary.

Share this post


Link to post
Share on other sites

It probably does make sense for us to go ahead and expand the file naming format to account for more variation beyond dimensions, and introduce it with the new crop positions. This will mean a few more considerations in the updates, but seems worthwhile.

Share this post


Link to post
Share on other sites

Would't it enough to build a md5 of the user optional options array like this

$basename .= '.' . $width . 'x' . $height . "." . $this->ext() . "." . md5(implode($options)); // i.e. myfile.100x100.1f3870be274f6c49b3e31a0c6728957f.jpg;

and ignore the md5 part in the getVariatons calls?

Share this post


Link to post
Share on other sites

Could certainly do that. Not sure I'd want to make such long filenames full of MD5 hashes though. I suppose I'd prefer to have a human-readable filename that isn't quite so long. Though the scalable benefits of the hash are hard to argue with. Definitely something to think about.

Share this post


Link to post
Share on other sites

Just checked on this forum, as I like to see if anyone needed help with things I struggled with. This would be epic to have a cropping direction. I ended up using the modules and the crop tools, which worked great for my client. Thanks for all the hard work you & the others put into processwire. I hope one day to know enough about php and processwire to help the community as much as you guys help me.

Share this post


Link to post
Share on other sites

Cropping direction has been added to the latest commit on the dev branch. Example of usage:

$image = $page->image->size(300, 200, array('cropping' => 'north'));

// or you can use this shorter syntax
$image = $page->image->size(300, 200, 'north');

That would make it crop towards the top of the image. Possible values for crop direction include: northwest, north, northeast, west, center, east, southwest, south, southeast or a blank string to disable. If you prefer, you can use short versions like 'nw' for northwest or 's' for south, etc.

Crop direction can also be used with the width/height functions:

$image = $page->image->width(300, 'north'); 

PW now supports this shorter syntax for crop direction, and also with quality and upscaling. If you specify a string for the last argument, it assumes you are specifying a crop direction. If you specify an integer, it assumes you mean a 'quality' setting. If you specify a boolean, it assumes you mean an 'upscaling' toggle on/off. If you need to combine multiple options then of course you should specify an array, as before. This behavior applies to the size(), width() and height() functions.

If interested, more details are in the function comments.

Thanks to interrobang for providing the implementation of crop directions.

  • Like 7

Share this post


Link to post
Share on other sites

Thanks that definitely looks interesting and useful. When we comes to these API functions, we're basically blind, so the cropping functions are really about trying to ballpark an area. We assume you may have a "group of images" context, but not a single image context. For instance, say you've got an employee directory containing a vertical head shot photo for each person. Then lets say you need square thumbnails for a listing page. In these thumbnails, you'll want to gravitate towards the "north" so that their head doesn't get chopped off. For other situations where you aren't blind and do have a single image context, then I think Apeisa's thumbnails module is the best way to go. Though the next step with the API may be to add more pinpointed cropping functions, but I suspect they will really only be useful for people developing a front-end to them for cropping individual photos.

Share this post


Link to post
Share on other sites

One thing I can imagine is to have a second image that can be used as watermark with processwire. I think this is a nice addition. Although I don't know how it should be added.

  • Like 1

Share this post


Link to post
Share on other sites

Greetings,

Thanks Ryan for giving us one more tool to make our sites better.

This brings up the constant need to emphasize to clients the need to follow some basic principles with photos! It seems that with every project, I have a tutorial session with the client explaining that photos need to be of the same proportion, NOT cropped in all sorts of ways, and more. I've started putting this together in some standard documentation I share with them.

Having options in the API like this can help overcome some issues with photos that are not right for the job. Client education needs to fill the rest of the void!

Matthew

  • Like 1

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By a.masca
      Goodmorning everyone,
      sorry for the inconvenience but I have a problem that I can't find in any other post.
      Strange things happen on a site:
      - despite everything being configured correctly (as already done in dozens of other sites) only superusers can create new pages
      - if I insert in a selector "include = all" the result is always 0
      - I should restore a series of pages incorrectly inserted in the trash, but I cannot select them with the selector "status = Trash"
      Some idea?
      Thanks so much for your valuable support.
    • By LAPS
      According to this old post, I'm trying to use the PW cache feature:
      $my_page = $pages->get($pageId); if($my_page->viewable()) { $content = $cache->get("my_page"); if(!$content) { $content = renderCustom($my_page->children); $cache->save('my_page', $content, 3600); } echo $content; } function renderCustom(PageArray $items) { foreach($items as $item) { echo $item->title; // ... heavy content loading } } After loading the page which renders the above code, in the admin I can see something was cached (note: I'm using ClearCacheAdmin) :

      But when I reload the page the cached value seems do not be used and the page loads slowly.
      The result of doing var_dump() is the following:
      var_dump($cache); // return object(ProcessWire\WireCache)#20 (0) { } $content = $cache->get("my_page"); var_dump($content); // return string(0) ""  
      What could be the problem?
    • By LAPS
      Can you confirm that the function renderField for fieldset fields, even having the file /site/templates/fields/fieldName.php or /site/templates/fields/fieldName/$file.php (using $file argument), does not render anything as expected?
      $page->renderField('fieldsetName') // returns nothing ... or am I wrong on something?
    • By LAPS
      Hi there,
      I'm working on an email message template and would like to render a custom one to be sent.
      I tried to use $files->render() this way
      // rendering file e.g. a template file or a hook statement in ready.php $body = $files->render('emails/myfile', array( 'myVar1' => $var1, 'myVar2' => $var2, ... )); but $vars seems to be not accessible from within the rendered file. That is, $vars seems to be not set:
      // rendered file emails/myfile.php $myVar1 = $vars['myVar1']; // is not set $myVar2 = $vars['myVar2']; // is not set ... // is not set How can I get the $vars so to properly render the custom message template for sending the email?
       
      Notes:
      By using $files->include() the $vars is accessible but I cannot use this method because I should retrieve the output $body as a return value for sending the email later. So, I'm still looking to render the custom message using $files->render(). This thread is someway related to this one.
    • By Markus (Blue Tomato)
      I'am working on a migration script from the ImageExtra Module to the new Custom Image Fields feature in ProcessWire.
      I have some problems while setting a field value to the new custom image field. I have set up the custom field and it works correct in the admin panel but not via the API:
      $page->images->my_custom_image_field = "test"; $page->save(); Results into:
      Fatal error: Uncaught ProcessWire\WireException: Item 'my_custom_image_field' set to ProcessWire\Pageimages is not an allowed type in /var/www/html/wire/core/WireArray.php:458
       
       
×
×
  • Create New...