Thursday, May 27, 2010

Experiment Extracting Windows Thumbnails (XP and Windows 2003 only)






<br />



Windows thumbnails have existed for eons. But in all that time I never really used the windows explorer thumbnail view. Yes, pictures are nice. But invariably I found myself needing the detail view with its listing of file types, sizes and dates.



Well, this week I came across an old stackoverflow thread which mentioned a C# tool for reading and extracting images from the windows thumbnail cache (ie thumbs.db). At least on older XP and Windows 2003 systems. (Vista and later use a slightly different format.) While there are tools galore in this category, the idea of a small DLL that could be called from CF was appealing. So I decided to give it a quick whirl with CF8, under XP.



After compiling the source with Visual C# Express, I changed my explorer settings so I actually had a thumbnails file to test. Next, I created an instance of the ThumbDB class and initialized it by passing in the path my thumbnails database. Once initialized, I used the GetThumbFiles() method to grab an array of all file names within that database.





&lt;cfset util = createObject(".net", "ThumbDBLib.ThumbDB", "c:/test/ThumbDBLib.dll")&gt;
&lt;cfset util.init( "C:/docs/thumbs.db" )&gt;
&lt;cfset fileNames = util.GetThumbFiles()&gt;
&lt;cfdump var="#fileNames#" label="Top 25 Files in Thumbs.db" top="25"&gt;



Next, I selected one of the file names and used the GetThumbData() method to retrieve the image bytes. I was hoping to create a CF image object from the bytes and display it in my browser. But every time I called ImageNew(), ColdFusion kept complaining about my argument type.





&lt;!--- this does NOT work ---&gt;
&lt;!--- grabbing an arbitrary file from the listing for testing ...---&gt;
&lt;cfset thumbnailName = fileNames[1] /&gt;
&lt;cfset bytes = util.GetThumbData( thumbnailName )&gt;
&lt;cfset img = ImageNew(bytes) /&gt;



That is when it hit me. A byte in C# is not the same as byte in Java. Unlike Java, C# has signed and unsigned types. So where C# has two data types, sbyte (-128 to 127) and byte (0 to 255), java has only one, byte (range -128 to 127). So according to the data type conversion matrix, the C# byte array was being converted to a short array.



Thanks to a tip from BlackWasp.com, I added a new method called GetJavaThumbData(), which converts the C# byte array into one that is compatible with Java. Using the new method, I was then able to display the thumbnail perfectly.



C# Code:



public sbyte[] GetJavaThumbData(string fileName)
{
byte[] data = GetThumbData(fileName);
if (data != null)
{
sbyte[] jvData = Array.ConvertAll(data, delegate(byte b) { return unchecked((sbyte)b); });
return jvData;
}
return null;
}



ColdFusion Code:



&lt;!--- grabbing an arbitrary file from the listing for testing ...---&gt;
&lt;cfset thumbnailName = fileNames[1] /&gt;
&lt;cfset bytes = util.GetJavaThumbData( thumbnailName )&gt;
&lt;cfset img = ImageNew( bytes )&gt;
&lt;cfimage action="writeToBrowser" source="#img#"&gt;



It is worth noting the ThumbDB class also has a method named GetThumbnailImage(), which returns a C# image object. You can use its properties to display things like height, width, resolution. The class also has several methods for saving the image to a file. Out of curiosity, I tried several of the overloaded save() methods. But I only had success with the simplest form: Image.save(filepath). I am not sure why. Though with CF's own image functions, they are not really needed anyway.





&lt;cfset img = util.GetThumbnailImage( thumbnailName ) /&gt;
&lt;cfoutput&gt;
&lt;strong&gt;Thumbnail: #thumbnailName#&lt;/strong&gt; &lt;hr /&gt;
Height = #img.Get_Height()#
Width = #img.Get_Width()#
PixelFormat = #img.Get_PixelFormat()#
Resolution = #img.Get_HorizontalResolution()# /
#img.Get_VerticalResolution()#
&lt;/cfoutput&gt;



Supposedly the Windows API Code pack can extract thumbnails on later systems like Windows 7. If anyone has used it, or something similar, on Windows 7, let me know. I would be interested in hearing your experiences with it.






Reference: http://cfsearching.blogspot.com/2010/05/experiment-extracting-windows.html

No comments:

Post a Comment