Tuesday, June 26, 2007
At CFunited 07
See you there !
Monday, June 18, 2007
New CFDocument hotfix released !
Some of the important issues that we fixed in this hotfix are
1. Text getting chopped / clipped
2. Image zoom or image cropped
3. Header/Footer overwriting the text in the page body.
If you use cfdocument, it is a must have hotfix for you.
You can download the hotfix here but do not forget to read the instructions to apply this hotfix. Enjoy !
Friday, June 08, 2007
Finding Image Type for a file
We will use this API to find out the image type of a given file. Here is the udf.
<cffunction name="getMimeType">
<cfargument name="filepath">
<cfset var urlConn = createObject("java", "java.net.URLConnection")>
<cfset var fileobj = fileopen(filepath, "readbinary")>
<!--- just read the first 20 characters of the file as thats sufficient --->
<cfset var bytes = fileread(fileobj, 20)>
<cfset var istream = createObject("java", "java.io.ByteArrayInputStream").init(bytes)>
<cfset fileobj.close()>
<cfreturn urlConn.guessContentTypeFromStream(istream)>
</cffunction>
<cffunction name="GetImageType">
<cfargument name="filepath">
<cfset var mimetype = getMimeType(filepath)>
<cfset var imagetype="">
<cfif not isDefined("mimetype")>
<cfthrow message="Not an Image file">
</cfif>
<cfswitch expression="#mimetype#">
<cfcase Value="image/gif">
<cfset imagetype="gif">
</cfcase>
<cfcase Value="image/x-bitmap">
<cfset imagetype="bmp">
</cfcase>
<cfcase Value="image/png">
<cfset imagetype="png">
</cfcase>
<cfcase Value="image/jpeg">
<cfset imagetype="jpeg">
</cfcase>
<cfcase Value="image/jpg">
<cfset imagetype="jpeg">
</cfcase>
<cfdefaultcase>
<cfthrow message="Not an Image file">
</cfdefaultcase>
</cfswitch>
<cfreturn imagetype>
</cffunction>
If I run the code below
<cfset filepath = "C:\temp\test.jpg">
<cfoutput>#GetImageType(filepath)#</cfoutput>
It nicely prints out "jpeg".
You should note that I used the new File IO function added in ColdFusion 8 using which I can read as many no of bytes from the file as I want. No more reading the entire file into memory.
More extensive post on File IO functions coming next !
Finding mime type of any file
guessContentTypeFromName(String name) - that simply checks the extension of the file name specified and gets the mime type from a static map it maintains. This can be very useful in many scenarios. The map it uses is quite extensive and contains almost all the mime types.
But this has a problem. What if some one has renamed a gif to jpg? This method will say that the file is a jpg image whereas it was a gif.
Thankfully there is another method in the same class which can address this problem.
guessContentTypeFromStream(InputStream stream) - which reads the stream, takes a look at the initial bits of the file and uses that to determine the file type.
This method does a check for the following mime types :-
- application/java-vm
- application/x-java-serialized-object
- text/html
- application/xml
- image/gif
- image/x-bitmap
- image/x-pixmap
- image/png
- image/jpeg
- image/jpg
- image/vnd.fpx
- audio/basic
- audio/x-wav
Though this method leaves out many of other common types such as mp3, it is still very useful. This makes it so easy to find out the type of an image.
Saturday, June 02, 2007
ListToArray with empty elements - Part II
So, a list "a,b,,c,d,," when converted to array will have only 5 elements instead of 7.
Incidently Charlie had also talked about the same some time back here and he mentions another problem with this approach. The array that is returned after split method is read only and you can not modify this array.
In order to address both these, I had to write this UDF which I guess many people would have written anyways..
<cfscript>
function list2Array(list)
{
var endCommaCount = 0;
var i = 0; var c = "";
var stringForSplit = ""; var retList=""; var arr = "";
for(i=len(list); i > 0; i--)
{
c = list.charAt(i-1);
if(c == ',')
endCommaCount++;
if( c != ',' && c != ' ')
break;
}
retlist = ArrayNew(1);
if(i != 0)
{
stringForSplit = left(list, i);
arr = stringForSplit.split("\s*,\s*");
for(i = 1; i <= ArrayLen(arr); i++)
ArrayAppend(retList, arr[i]);
}
for(i = 0; i < endCommaCount; i++)
ArrayAppend(retList, "");
return retList;
}
</cfscript>
UPDATE : Thanks to Andrew Clark for the split tip which makes it more slim and elegant. The code above changes like
<cfscript>
function list2Array(list)
{
var i = 0;
var retlist = ArrayNew(1);
var arr = list.split(",", -1);
for(i = 1; i <= ArrayLen(arr); i++)
ArrayAppend(retList, arr[i]);
return retList;
}
</cfscript>
Lets test this udf and see if it works..
<cfset cflist = "a,b,,c,,d, ,">
<cfset cfarr1 = ListToArray(cflist)>
<cfset ArrayAppend(cfarr1, "END")>
<cfset cfarr2 = List2Array(cflist)>
<cfset ArrayAppend(cfarr2, "END")>
With CF Function : <cfdump var="#cfarr1#" format="text">
With UDF : <cfdump var="#cfarr2#" format="text">
And this produces this result.
With CF Function :
array - Top 6 of 6 rowsWith UDF :
1) a
2) b
3) c
4) d
5)
6) END
array - Top 9 of 9 rows
1) a
2) b
3) [empty string]
4) c
5) [empty string]
6) d
7) [empty string]
8) [empty string]
9) END
One thing to note here is that I am using new cfscript operators added in ColdFusion 8 which is so cool!!!
Friday, June 01, 2007
ListToArray with empty elements
<cfset cflist="a,b,,c,,,d">
<cfset cfarr1 = ListToArray(cflist)><cfset cfarr2 = cflist.split(",")>
<cfset cfarr2 = cflist.split(",", -1)>
<cfdump var="#cfarr1#">
<cfdump var="#cfarr2#">
<cfscript>
for(i=1; i <= ArrayLen(cfarr2); i++)
{
writeoutput("Element #i# : #cfarr2[i]# <br>");
}
</cfscript>
As you can see, 3rd, 5th and 6th element in this cfarr2 are empty.
ColdFusion 8 beta has arrived
And that means I am back on blogsphere after a long hiatus. Seriosuly, what a fabulous journey it has been! It is a result of nearly one and half year of hard work, huge amount of research, so many design discussions, fights over nitties-gritties of features, many spec review meetings (which many a times reminded me of the college time ragging or soap box for elections at IIT kgp), many beer parties (because some one was beer boy coz he broke the build) and eating rubber chicken few times (becoz the build was broken again !!) etc etc etc.. -- all to ensure that there is enough sting in the Scorpio. :)
Everyone of us in the team is really proud of the stuff that we have built and I am sure people gonna love it.
And we are not done yet! Ashwin's cartoon says it all !!!