LendKey

Wednesday, November 28, 2007

Get default folders in Windows

In order to get any system folder under Windows (I guess from 95 to Vista) by any programming language, you can call function:

HRESULT SHGetFolderPath( HWND hwndOwner,
int nFolder,
HANDLE hToken,
DWORD dwFlags,
LPTSTR pszPath
);
( http://msdn2.microsoft.com/en-us/library/ms647764.aspx )

and pass in the folder you are looking for, such as:
CSIDL_MYDOCUMENTS: My Document
CSIDL_COMMON_APPDATA: C:\Documents and Settings\All Users\Application Data
CSIDL_PROGRAM_FILES: C:\Program Files.

Check the following link for all IDs:
http://msdn2.microsoft.com/en-us/library/bb762494.aspx

Hope these two links can be handy to you.

Friday, November 23, 2007

Some tricks on ImageMagick

I had about 1000 images with all different resolutions. I needed to resize them to fit into 100x100 square. So I looked around and found a great command line tool that can do lots of different image manipulation in a batch.

The tools is called Image Magick, you can find it at:
http://www.imagemagick.org/script/index.php

After downloaded a Windows version and installed, I had a brief look at the manual find out the way to resize everything into a specific size and keep the image ratio at the same time:

c:convert -resize 100x100 -quality 100 ..\*.* %d.jpg

Basically I create a new folder under the folder where all my original images are located. Went to he new folder and ran the command above.

The command resized all image files under the parent folder ( original files ) to 100x100 area and kept original image ratio. The result files are named as numbers from 0.jpg to 999.jpg. All original files were converted to JPG format,not matter what they were.

Please be advised, the result image might not be exact 100x100. For example, if the original image is 400x200, the new image will end up as 100x50. You got the idea?

I set quality to 100, so shrunk image still looks pretty nice.

You can also add one more option -strip which is very helpful for me to strip out all image information stored in each file, such as tags, comments, etc. and saved me lots of space.

So far so good, untilthe second day. I suddenly realized an issue, when I show the images on my website in a 100x100 area, my tag on site requires 100x100 exact size, otherwise, the image will be stretched and got disordered. So I need to do another conversion:

convert -gravity Center -extent 100x100 ..\*.jpg %d.jpg

By this command, I was able to convert everything int a new image with exact 100x100 resolution. By using -gravity Center, the original image got placed at center of the new image. So everything is working perfectly now!

There're hundreds of commands provided by Image Magick. You have to either spend hours reading through all of them and become a guru, or like I did, simply search a word I want to work on my images, and jump to that command directly and try.

Image Magick is surely a great tool. I hope I can find more real-life tricks playing with it in the future. And hope you enjoy playing with it yourself too.

-Li

Thursday, October 18, 2007

A Thread Safe Date Formatter/Parser

I have seen many different ways to use DateFormat classes(most ly SimpleDateFormat) from different people including myself, and unfortunately, most of them are either buggy or not efficient.
The following are the most common scenarios I saw:
1. Use a static final formatter in different thread:
static final private DateFormat df = new SimpleDateFormat("yyyy/MM/ddd");
...
void myMethod()
{
df.parse(..)
df.format(..)
}
People, including me, were thinking to reduce number of instances of df and reuse it everywhere. But this is dead wrong! The JavaDoc has clearly mentioned that SimpleDateFormat is NOT thread-safe. So once you put multiple threads using the same instance, strange result will happen. Most of the time, people tent to ignore the warning from JavaDoc or don't even know it. And most of time, the code works ok, because after all, there is not that many threads running in parallel if you are only doing a small website.
2. Create DateFormat instance eveyrtime it is used
void myMethod()
{
DateFormat df= new SimpleDateFormat("yyyy/MM/dd");
df.parse(..);
df.format(..);
}
This works without bug, but you can tell lots of df objects will be created, they I always feel it is not good to create extra objects when you are coding for large and heavily loaded website.
3. Apache Jakarta Common Lang's FastDateFormat
http://www.jdocs.com/lang/2.1/org/apache/commons/lang/time/FastDateFormat.html
This is a thread-safe solution. But the problem is still you have to create each instance for different pattern. Many times in your code, you have to create multiple instance of the same pattern at many different places, which mean multiple different objects to do the same thing. The biggest problem with FastDateFormat is it only format and does not do parsing.
So after spending about an hour or so doing research, I came up with my own solution:
ThreadSafeDateParser.
Here's the class:

And the test Class:



Idea of the class is:
  1. Very easy to use. Just call those static methods and provide a string and pattern. The class will handle everything else, including formatter object creation, thread mangement, etc.
  2. For same patter and same thread, the class create only one instance of DateFormat, so you got thread-safe and use the minimum system resource
I tested the class with 1000 threads running at the same time, and it works solid with out any problem.

Hopefully this is something lots of people can reuse in your code.
I know I do not have locale and timezone handling yet. I you have any comment or suggestion, feel free to share.

Enjoy!

Li