Reputation: 7563
I have a CSS container that is 500px x 200px in size.
What I need to do is scale my images so that they fill the container but I want to use a ColdFusion image function to reduce/expand until it fills the dimensions.
For example, if I have a large image that's 1920px x 1080px, then I want ColdFusion to reduce it in size (while maintaining the aspect ratio) until it its just big enough to fill the container dimensions of 500px x 200px. Equally, a small image should be scaled up until it is both at least 500px wide and 200px wide. The key word is at least, because it doesn't matter if goes beyond these dimensions by much.
I could use ImageScaleToFit()
, but it will reduce the image until one of the dimensions (either 500px or 200px) is met. So ImageScaleToFit will reduce the image until its 500px wide, but there is a very high chance that the height maybe just 100px. Rather than this, I want ColdFusion to reduce the image until it is at leastboth 500px wide and 200px in height.
I have also tried to use ImageCrop()
to simply take a 500px x 200px slice out of an image thats bigger than these dimensions but its not working out very well because on a large image you haven't got a clue what the cropped image was originally meant to be.
How can I solve this? The best analogy I can use to explain what I want is if you create a canvas in Photoshop that is 500px x 200px, and then you place an image on that canvas and use the transform tool to expand/reduce it until that canvas is filled. Obviously not all of the image will appear on the canvas, but that's ok because most of it is there.
Upvotes: 2
Views: 143
Reputation: 5510
You can do the math yourself, I loop over some sample data, but only as a demonstration.
<cfset dimlist="1000|800,1000|1000,800|1000,1000|200,500|1000,600|1000,230|40,400|300,300|500,499|200,500|199,499|199">
<cfloop list="#dimlist#" index="dims">
<Cfset dheight = listfirst(dims,"|")>
<cfset dwidth = listlast(dims,"|")>
<cfset hratio = dheight / 500>
<cfset wratio = dwidth / 200>
<cfif dwidth / hratio gte 200>
<cfset finalh = int(dheight / hratio)>
<cfset finalw = int(dwidth / hratio)>
<cfelse>
<cfset finalh = int(dheight / wratio)>
<cfset finalw = int(dwidth / wratio)>
</cfif>
<cfoutput> #dheight# x #dwidth# converts to #finalh# x #finalw#<br /></cfoutput>
</cfloop>
In truth, you could turn this into a function easily
<cfscript>
function CalcSz(numeric ih, numeric iw, numeric dh = 500, numeric dw = 200) {
var hratio = arguments.ih / arguments.dh;
var wratio = arguments.iw / arguments.dw;
if(arguments.iw / hratio > arguments.dw) {
var finalh = int(arguments.ih / hratio);
var finalw = int(arguments.iw / hratio);
} else {
var finalh = int(arguments.ih / wratio);
var finalw = int(arguments.iw / wratio);
}
return {height = finalh, width = finalw};
}
</cfscript>
<cfset dimlist="1000|800,1000|1000,800|1000,1000|200,500|1000,600|1000,230|40,400|300,300|500,499|200,500|199,499|199">
<cfloop list="#dimlist#" index="dims">
<Cfset dheight = listfirst(dims,"|")>
<cfset dwidth = listlast(dims,"|")>
<cfset dimstruct = CalcSz(dheight,dwidth)>
<cfoutput> #dheight# x #dwidth# converts to #dimstruct.height# x #dimstruct.width#<br /></cfoutput>
</cfloop>
This returns a struct containing .height and .width, as you can see.
As you can also see, it has no problem with conversions downsizing, upsizing, or when either is very close (499 or 199).
Needless to say, don't pass a 0 as any argument :).
Upvotes: 3