ColdFusion Image Processing - Shrinking an image, but not the canvas

This post is more than 2 years old.

After my presentation yesterday, someone in the audience asked an interesting question. He wanted to shrink an image, but keep the original size. So imagine taking a large image, shrinking down the visual part of it, but keeping the image at the same size with some form of background now. This is relatively easy to do. First we can read in our source image:

<cfset source = "presentations/webmaniacs/images_lecture/originals/insp_captkirk.png">

<!--- read it ---> <cfset myimage = imageRead(source)>

Then we can shrink it:

<!--- shrink it ---> <cfset imageScaleToFit(myimage,250,250)>

Now let's create a new canvas. This will be a blank image. I'm picking an arbitrary size here. You could have checked the original images size instead, but for this example, I'll just use 400x400. Also note I intentionally picked a non-white background so I could see it working.

<!--- new canvas ---> <cfset img = imageNew("", 400, 400, "rgb", "##c0c0c0")>

Lastly, all you do is paste the shrunken image over the blank canvas we just made:

<!--- paste it in ---> <cfset imagePaste(img, myimage, 0,0)>

Here is the final result:

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Steve Good posted on 5/20/2008 at 9:55 PM

Drat, I was hoping for a new and amazing way to do this. I suppose I should just be glad I've been doing it right. Thanks Ray!

Comment 2 by Andy Lynch posted on 5/21/2008 at 3:29 PM

I'm sorry, I *need* to know where you found taht poster of Kirk. It looks like one of the demotivators products, but I couldn't find it there...

I have a friend that really needs to have this given to them. :-)

Comment 3 by Raymond Camden posted on 5/21/2008 at 3:34 PM

http://www.echosphere.net/s...

Next time I present, I need to share that URL. I'm not being fair by withholding that info.

Comment 4 by Will Swain posted on 5/23/2008 at 1:16 AM

Hey Ray,

Good timing for me this post. I'm working on a system that allows a user to upload an image - I then run some checks to see if the image is over a certain width or height, and create a thumbnail if it is. However, I want all my thumbnails to be square, to fit within the viewing area nicely.

No problem - I'll create a square canvas, and then paste in the resized image much as you do above. It all works great, but I really want the resized thumbnail to be centered in the new canvas. This is where my brain starts to hurt.

Here's an example of where I am at the moment - this is creating the thumbnails, but sticking the resized image in the top left corner of the canvas of course:

<cffile action="upload" destination="#application.image_root#" nameConflict="makeunique" filefield="theImage" result="fileupload">

<cfset newfile = fileupload.serverdirectory & "\" & fileupload.serverfile>
<cfset thumbfile = fileupload.serverdirectory & "\" & fileupload.SERVERFILENAME & "_thumb." & fileupload.SERVERFILEEXT>

<cfset smallSize = 180>

<!--- create a thumbnail image of exactly 180 x 180 if the image is larger) --->

<cfset newimage = imageRead(#newfile#)>

<cfif newimage.width GT smallSize OR newimage.height GT smallSize>

<cfif newimage.width GT newimage.height>

<cfset imageScaleToFit(newimage,#smallSize#,"")>

<!--- new canvas --->
<cfset canvas = imageNew("", 180, 180, "rgb", "##FFFFFF")>

<!--- paste it in --->
<cfset imagePaste(canvas, newimage, 0,0)>

<cfimage source="#canvas#" action="write" destination="#thumbfile#" overwrite="yes">

<cfelseif myImage.height GT myImage.width>

<cfset imageScaleToFit(newimage,"",#smallSize#)>

<!--- new canvas --->
<cfset canvas = imageNew("", 180, 180, "rgb", "##FFFFFF")>

<!--- paste it in --->
<cfset imagePaste(canvas, newimage, 0,0)>

<cfimage source="#canvas#" action="write" destination="#thumbfile#" overwrite="yes">

</cfif>

<cfelse>

<cfimage action="resize" height="#smallSize#" width="" source="#newfile#"
destination="#thumbfile#" overwrite="true"/>

</cfif>

Any suggestions on centering this thumbnail within the canvas.

Comment 5 by Raymond Camden posted on 5/23/2008 at 1:19 AM

All you need is math. The x and y position for your paste is

(Width of Total Canvas - Width of small canvas) / 2

Comment 6 by Will Swain posted on 5/23/2008 at 1:30 AM

Of course!! It's late here in the UK, at least that's my excuse.

Logically then, assuming the original image isn't square, if it's wider I'd need to position by the y co-ordinate and if it's higher, I'd need to position by the x co-ordinate.

Thanks Ray.

How you getting on with Game of Thrones BTW? Finished it yet?

Comment 7 by Raymond Camden posted on 5/23/2008 at 1:35 AM

@Will - No - it shouldn't matter. Use the same math for both.

I'm about 90% done - well, 95% done. Darn, darn good. I should wrap by tonight.

Comment 8 by Will Swain posted on 5/23/2008 at 1:38 AM

Thanks Ray, got this working now with your help. Damn I love ColdFusion and the way it makes things like this so sensible.

Enjoy! I'm 1/4 of the way through the next book. Loving it. I might get a chance to read some tonight now I have this working.