Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Running two consecutive Image methods NULLifies the Image?


Reply


8 Posts   1536 Views

Avatar
Xurk

Community Member, 50 Posts

1 February 2011 at 2:57am

Hey guys,

I'm finishing up a project at the moment and one minor to-do is left - visitors on the website can generate and save PDF files for instances of a DataObject class on the website, which have images linked to them. The PDF displays the DataObject's main image in it, on top of a polaroid background sprite.

In order to place the image exactly on top of the polaroid part of the background, it is first resized depending on its orientation (orientation 0 = SetSize, 1 = SetWidth, 2 = SetHeight). This keeps the aspect ratio of the image intact while making sure that at least one dimension of the image fits inside the polaroid. Unless the image is square (very rare), it still overflows one of the dimensions though.

Now we can just display the image at the maximum width and height allowed within the polaroid and we'd be done, but this defeats the purpose of resizing it in the first place because it would still end up skewed. So after the first resize (see previous paragraph), I've added in another line whcih uses the CroppedImage method of the Image class, to just "cut off" any part of the image which doesn't fit inside the polaroid. This way, most of the image is still showed and it doesn't become skewed. On the frontend some CSS (overflow: hidden) would suffice, but this doesn't seem to be possible in FPDF (the PDF extension we're using), which is why I'm trying to achieve the cropping this way.

The problem is, SilverStripe only seems to let me do one or the other - SetSize/-Width/-Height OR CroppedImage. If I try to consecutively execute both methods, the object variable turns into NULL, rendering it useless. I'm guessing this is because of all of these methods turning the Image object into an instance of Image_Cached? Does anyone have any ideas on this?

I've tried creating a new instance of Image and storing the resized image into it, then cropping that new instance. But it didn't get me anywhere. I can't use the GD2 methods because I don't think the server supports them; "GD Support" is "enabled" in phpinfo() but I get the "the method 'croppedresize' does not exist on 'Image'" error when I try to use one of the methods. SilverStripe version is 2.4.3.

Sorry for the long post (I have a habit of being long-winded), I hope it's clear what the problem is.

Avatar
Willr

Forum Moderator, 5513 Posts

1 February 2011 at 1:24pm

I think the issue is because when you create a new thumbnail SilverStripe does not return that thumbnail as a GD / Image object so you can't therefore chain calls.

"the method 'croppedresize' does not exist on 'Image'" error when I try to use one of the methods.

No you are getting that error because that method doesn't exist. It is named 'generateCroppedImage()' in Image.php

Avatar
Xurk

Community Member, 50 Posts

1 February 2011 at 9:50pm

Edited: 01/02/2011 9:51pm

Thanks for your reply, Willr.

I'm with you on the first part of your reply, I can understand that SilverStripe returns an instance of Image_Cached after you manipulate an Image with (e.g.) the SetWidth() method and therefore revokes your access to the Image methods.

But about that error - it is odd, but I receive exactly the same error when I try to use the generateCroppedImage() method as well. As a matter of fact, calling the [url=http://doc.silverstripe.org/sapphire/en/reference/image]croppedResize()[/url] method also gives me the exact same error.

I know that the [url=http://api.silverstripe.org/2.4/sapphire/filesystem/Image.html#methodgenerateCroppedImage]generatedCroppedImage()[/url] method expects a GD instance as one of its arguments, so I've tried to use the method in the following manners:

$myImage->generateCroppedImage($myImage, 145, 140);
$myImage = $myImage->generateCroppedImage($myImage, 145, 140);
$myImage = generateCroppedImage($myImage, 145, 140);


But none of those seems to cut it. Am I missing something obvious?

On a side-note: we had a closer look at GD support on our server and it seems that we have one of the latest versions (2.0.34 whereas [url=http://www.libgd.org/Downloads#Download_the_latest_.282.0.35.29]the latest version[/url] is 2.0.35), so that shouldn't be causing the problem.

Avatar
Willr

Forum Moderator, 5513 Posts

2 February 2011 at 12:18pm

Try $image->generateFormattedImage("CroppedImage", 130, 140);

generateFormattedImage creates the GD object for you.

Avatar
Xurk

Community Member, 50 Posts

2 February 2011 at 10:03pm

Thanks! That turned out to be the key to success in the end :)

I tried it out and also discovered the "getFormattedImage()" and "cacheFilename()" methods, which was all I really needed to get everything working orderly. Also, this saves me the trouble of having to check the Orientation property and calling SetWidth/-Height first for each image in the DataObjectSet, which slowed the page down quite a bit.

I don't know how I missed that set of methods before, but I'm glad you pointed me in the right direction!

Avatar
Wade

Community Member, 6 Posts

7 September 2011 at 2:54pm

Would you mind sharing how you accomplished this?

Thanks
Wade

Avatar
Xurk

Community Member, 50 Posts

7 September 2011 at 7:19pm

Sure :) It has been quite a while since I last looked at the code for the page in question, but these are the exact lines I ended up with:

$oLogo = $oInitiative->getComponent('Logo');
$oLogo->getFormattedImage("CroppedImage", 141, 130);
$sLogoFilename = $oLogo->cacheFilename("CroppedImage", 141, 130);


Hope it helps you out somewhat.

Avatar
merrick_sd

Community Member, 97 Posts

13 September 2013 at 2:01am

Edited: 13/09/2013 2:03am

Silvertripe version 3.05 question

i want to resize the image down to a certain Width and then crop is that possible?

example

class ServicePage extends Page {

public static $db = array(
'SmallListImage' => 'Text',
);

public static $has_one = array(
'ServiceImage' => 'ServicePage_ServiceImage'
);

function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main',
$uploadField =new UploadField('ServiceImage','Upload'),'Content');
$uploadField->setFolderName('Service');
return $fields;
}

}

class ServicePage_ServiceImage extends Image {

function generateBox($gd){
$gd->resizeByWidth(300)->croppedImage(240,160);
return $gd;
}
}


I just get either

the method 'croppedimage' does not exist on 'GD' or
the method 'formattedimage' does not exist on 'GD'

why is it quoting in lowercase?