This week a user sent in what I thought was a rather simple request. He needed to find the center of an image. That's pretty trivial math, so I fired back with the following:
2 <cfset myImg = imageNew(image)>
3 <cfset centerX = myimg.width/2>
4 <cfset centerY = myimg.height/2>
Basically, your center is the point defined at half your width and half your height. However, I misunderstood his initial request. He wanted to take an image and crop it to a smaller size. But he wanted the crop to "center" around, well, the center. Let me explain with an example that demonstrates how just finding the center isn't enough. We will begin with our source image - which is not mine and I cannot find the credit.
Pretty snazzy, right? Now let's look at code that finds the center, and then crops at that point:
2 <cfset myImg = imageNew(image)>
3
4 <cfimage action="writeToBrowser" source="#myimg#">
5 <p/>
6
7 <cfset centerX = myimg.width/2>
8 <cfset centerY = myimg.height/2>
9
10 <cfset imageCrop(myImg, centerX, centerY, 300, 200)>
11
12 <cfimage action="writeToBrowser" source="#myImg#">
You can see my math in there (ok, it's division, and it's simple, but it's still math!) and the imageCrop that works with the center. However, this creates a crop that is displayed. It's from the lower right hand size of the image.
In order to correct this, we need to make a slight tweak to our code. Our math formula becomes:
x=width of image/2 - desiredwidth/2
y=height of image/2 - desiredheight/2
Here is the corrected code:
2 <cfset myImg = imageNew(image)>
3
4 <cfset imageCrop(myImg, (myimg.width/2) - (300/2), (myimg.height/2) - (200/2), 300, 200)>
5 <cfimage action="writeToBrowser" source="#myImg#">
Which produces the following:
Better, right?
Comment 1 written by Christopher David Kowalski on 3 February 2010, at 5:26 PM
Thanks again for helping me out with this request.
PS: Caught a typo with the word "simpe".
Comment 2 written by Jonathan Gailing on 3 February 2010, at 5:47 PM
Comment 3 written by Raymond Camden on 3 February 2010, at 7:18 PM
Comment 4 written by Brian Lang on 3 February 2010, at 10:29 PM
Comment 5 written by Patrick Heppler on 5 February 2010, at 4:29 AM
Comment 6 written by Raymond Camden on 5 February 2010, at 6:54 AM
Comment 7 written by Gareth on 11 March 2010, at 4:03 PM
"Crop The rectangular crop area must not be outside the image."
What if I am dynamically calling in an image as part of a repeat region where the images will all have different sizes?
Here is my code:
<cfif qShowSearch.showImage1 NEQ "">
<div class="no_img">
<a href="show.cfm?showID=#qShowSearch.showID#">
<cfset image = "images/show_images/#qShowSearch.ShowImage1#">
<cfset myImg = imageNew(image)>
<cfset imageCrop(myImg, (myimg.width/2) - (300/2), (myimg.height/2) - (200/2), 300, 200)>
<cfimage action="writeToBrowser" source="#myImg#">
</a>
</div>
</cfif>
Comment 8 written by Raymond Camden on 11 March 2010, at 4:05 PM
Comment 9 written by Christopher David Kowalski on 11 March 2010, at 4:06 PM
Haven't reviewed your code to see if this really is the issue, but in my implementation I didn't hardcode the height/width values of the image that's getting cropped, I let CFIMAGE determine the shortest side, then crop by that value instead.
Comment 10 written by Gareth on 11 March 2010, at 4:31 PM
For my own application I am trying o create a thumbnail that is to a fixed width and height of 100px, hence the centre crop that will visually look better, as in such apps like Facebook.
Thanks in advance.
Comment 11 written by Christopher David Kowalski on 11 March 2010, at 4:35 PM
Maybe Ray can whip up a quick example for you, but just use CFIMAGE to determine the height and width of the image. Then, whatever value is smaller, crop the image by that...
So, say you have a tall image, 500 pixels tall, 200 pixels wide.
CFIMAGE will tell you the shortest side is 200. Thus, on your imageCrop you would use the "200" value for height/width.
Comment 12 written by Raymond Camden on 11 March 2010, at 4:55 PM
[Add Comment] [Subscribe to Comments]