The golden rain in this summer.

阿勃勒

阿勃勒

DSC02581

DSC02587

DSC02588

DSC02576

DSC02594


It’s so excited that iPhone 4 was announced this morning. BUT, it’s even more excited that I just received some magazines from Singapore with my photo published. It’s really a big shot for me. It’s so unrealistic and so unbelievable. Seriously? My photo was getting published in international magazines!!! Oh, it’s true.

It’s really uncommon that I receive an international air mail.
Received magazines from Singapore

And I’ve never seen an envelope with so many postage stamps. That’s amazing!
There are a lot of postage stamps

There are three different kind of publications in the envelope. According to the Wikipedia, Qualatex is the most popular balloon brand among professional twisters.
Magazines from Qualatex

One of my photo was published on the 2nd page of the Qualatex catalog.
My photo in the magazine

And the same one was also published in the calendar.
My photo on the calendar


New milestone

30May10

It’s really excited that Sheri and I will have our first app for iPhone and iPod Touch on the App Store soon. I’ve been waiting for a long time to see this happening. Years ago, I founded Ollix and became a freelancer while I was a university student. However, I actually don’t have too much time to do my business because I still need to spend a lot of time for school. Finally, I finished almost all the courses for my master’s degree, and thanks to many people who support me, now I can put more focus on my business.

Our first iPhone/iPod Touch app targets to people living in Taiwan and people who are going to Taiwan. It’s designed for the Taiwan High Speed Rail, which is the fastest train in Taiwan, with maximum speed of 300 km/h. The app’s name varies according to the user’s locale. In English, it’s called “Take Taiwan High Speed Rail”, in Traditional Chinese, it’s called “我要搭高鐵”, in Simplified Chinese, it’s called “搭台湾高铁”, and in Japanese, it’s called “台湾新幹線”. All these four languages are full supported in this app.

By using this app, you can use your iPhone or iPod Touch to search times and fares offline, book tickets and pay fares online. You can preserve your booking information to avoid typing the same data over again and again, and you can keep your booking history for convenience of picking up tickets. The best part of this app is that, you don’t need to compromise with browsers at all. All operations can simply be done in this app.

If you are interesting in this app, please visit our official website at http://www.ollix.com. You can follow us on Twitter or become a fan on Facebook for more information, and here are some preview screenshots:


Recently I need to create thumbnail images in one of my Qt applications, so I googled the Internet and found an article called Creating thumbnail preview by Ariya Hidayat. Ariya introduced three methods to create thumbnail images, all of them uses the QImage::scaled() function. Here’s a quick review of the three methods he introduced respectively.

The first method is using the nearest-neighborhood algorithm as following:

QImage image("/path/to/image");
QImage thumbnail = image.scaled(200, 200, Qt::KeepAspectRatio, Qt::FastTransformation);

The second is using the bilinear filtering to get a better quality, but the drawback is that it’s slower compared to the previous method:

QImage image("/path/to/image");
QImage thumbnail = image.scaled(200, 200, Qt::KeepAspectRatio, Qt::SmoothTransformation);

The third is tricky, Ariya mixed the previous two methods as he claimed this method has the similar quality to the second method but is even faster than the first method, and he called this method as “cheat scaling”, as following:

QImage image("/path/to/image");
QImage thumbnail = image.scaled(800, 800, Qt::KeepAspectRatio, Qt::FastTransformation).scaled(200, 200, Qt::KeepAspectRatio, Qt::SmoothTransformation);

However, after I tried all of these methods, I found that the performance is actually unacceptable even though I used the third method. My original images are usually at size around 4MB, and it spends too much time to create thumbnail images using any of above methods. Therefore, I tried to find other ways to improve the performance, and I did it. The answer is QImageReader class. Here’s the code I implemented to do the same thing as above:

int length = 200;
QImageReader image_reader("/path/to/image");
int image_width = image_reader.size().width();
int image_height = image_reader.size().height();
if (image_width > image_height) {
  image_height = static_cast<double>(length) / image_width * image_height;
  image_width = length;
} else if (image_width < image_height) {
  image_width = static_cast<double>(length) / image_height * image_width;
  image_height = length;
} else {
  image_width = length;
  image_height = length;
}
image_reader.setScaledSize(QSize(image_width, image_height));
QImage thumbnail = image_reader.read();

The code is much longer than using the QImage::scaled() function, but its performance is much better. Here’s the benchmark I tried to create thumbnail images for 10 jpeg images, and each of them has the size around 4MB.
Image scaling performance

As you can see, all three methods using QImage::scaled() are actually no much difference, but by using the QImageReader class, we got 46% performance improvement than using the Qt::FastTransformation. The algorithm QImageReader::setScaledSize() used for scaling depends on the image format. However, in this experiment, the quality of created thumbnail images are no difference between Qt::SmoothTransformation and cheat scaling and QImageReader methods.

For convenience, I implemented this function in my open source Qitty library. You can find this project at http://github.com/ollix/qitty. To create thumbnail images using this library, you’ll need to include the header file in your source code:

#include <qitty/image.h>

And use the qitty_utils::SacledImage() function:
QImage thumbnail = qitty_utils:ScaledImage("/path/to/image", 200);


Yesterday I introduced my new project, MicroAgent, in my data mining class. I designed an algorithm to find relevant keywords, titles, descriptions, and categories for images according to only a few of keywords, and it works pretty well. I think this application would be very useful for all microstock photographers because in my experience, to submit photos to microstock agencies is always a time consuming mess, as we need to figure out what keywords, titles, descriptions, or categories would best fit our images, and further help us increase the selling rate.

MicroAgent is the perfect solution for you, anyone who want to add metadata to their images would benefit from MicroAgent. However, MicroAgent is still at early state because I’d like to add more useful features to it (auto submission, statistics, etc). So, it may take a while to publish an official release. In the mean time, any idea or suggestion would be welcomed. By the way, MicroAgent will be available for Windows, Mac OS X, and Linux, so most people could take advantage of it. Just wait and see. :)


I implemented the Advanced Encryption Standard (AES)[4] using Restricted Python (RPython)[1], which is a subset of the standard Python programming language and comes from the PyPy[2] project. By using RPython, we can write our code in high level programming language similar to Python and later be translated to various backends such as C, Java Virtual Machine (JVM), or Common Language Infrastructure (CLI). As a result, we can develop our programs very quickly and get the performance similar to the one written in pure C, Java, or C# .NET.

However, RPython is not as powerful as standard CPython, so that’s why it is called “Restricted” Python. There are some restrictions in RPython. For example, you can’t use most Python packages comes from the CPython world because they are not written in RPython. Also, translated code are compiled to executables, not compiled Python modules, neither Python packages. Fortunately, these restrictions are trivial in this simple program because I’m intend to create executables and I don’t need libraries not supported by PyPy. Most importantly, performance matters.

In my experiments, to encrypt and decrypt a file on my iMac (Early 2008), the translated C executable is about 150 times faster than the pure Python code running on top of CPython, and the translated Java bytecode is about 16 times faster. Consequently, RPython should be very useful in case we don’t need serious dependencies. We just need to figure out a better way to integrate it with pure Python code, much like the C extensions for Python.

The AES algorithm implemented in this project is mostly following the AES Tutorial[3] and the Advanced Encryption Standard[4]; the values of Rijndael’s S-box and Inverse S-box are copied from [5]; and the implementation of Rijndael key schedule is following [6].

To test the program, you can use executables put under the bin directory shipped with the source code. There are 4 executables compiled in C, one compiled to Java bytecode as a JAR file (JVM), and one translated to C# and compiled for .NET framework (CLI). Now say that you want to encrypt a file under Mac OS X using the C executable. You can do this by:

bin/aes-mac-c  encrypt  mypassword  path_to_input_file  path_to_encrypted_file



To decrypt the file on a Java Virtual Machine, you can then run:

java  -jar  bin/aes-jvm.jar  decrypt  mypassword  path_to_encrypted_file  path_to_decrypted_file



You can also run the pure Python code on top of CPython or other Python implementation, but you’ll need to get the PyPy’s source code. You can find its repository at their website[2].

Here’s some benchmarks I made on Snow Leopard, Windows XP, and Gentoo Linux respectively.

  1. iMac (Early 2008)
    • Mac OS X 10.6.2 (Snow Leopard)
    • 2.8 GHz Intel Core 2 Duo
    • 4 GB 800 MHz DDR2 SDRAM
    • GCC version: 4.2.1
    • CPython version: 2.6.1
    • Java version: 1.6.0_17 (JVM)
    • Mono version: 2.6.1 (CLI)

  2. Windows XP 32-bit
    • Running in VirtualBox on iMac (Early 2008)
    • 1 GB RAM
    • Microsoft Visual Studio 2008 Express Edition
    • Java version: 1.6.0_17
    • CPython version: 2.6.4

  3. Gentoo Linux 2008 (amd64)
    • AMD Athlon 64 Processor 3500+
    • 2GB DDR 400 SDRAM
    • GCC version: 4.1.2
    • Java version: 1.6.0_17
    • Mono version: 2.4.2.3
    • CPython version: 2.6.4

References:
[1] Restricted Python: http://codespeak.net/pypy/dist/pypy/doc/coding-guide.html#restricted-python
[2] PyPy: http://codespeak.net/pypy/
[3] AES Tutorial: http://www.progressive-coding.com/tutorial.php
[4] Advanced Encryption Standard: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
[5] Rijndael S-box: http://en.wikipedia.org/wiki/Rijndael_S-box
[6] Rijndael key schedule: http://en.wikipedia.org/wiki/Rijndael_key_schedule


Qt Designer is an important tool for designing and building graphical user interface from Qt components. However, if you are a Java programmer and want to use Qt Designer with Qt Jambi in Mac, you can’t simply double-click the Designer app bundle shipped with Qt Jambi SDK. If you do so, you can still invoke the Designer, but… with the C++ environments, it’s useless for Java programmers. Instead, if you want to use Qt Designer with Qt Jambi. You have to start the program from a `designer.sh` script placed in your Qt directory. It’s pretty annoying because you’ll need a Terminal to run this script until you turn it off. Also, it’s not intuitive.

So, I checked the script code and found what it does is simply to set some environment variables and then execute the Designer binary within the Designer app bundle. Therefore, I decided to make a “real” app bundle for the Qt Designer with Qt Jambi. It’s pretty easy to do this job by using Jump, one of my open source projects. Here’s the instructions.

  1. Go to the `QTDIR/bin` directory in Finder.
  2. Right-click the `Designer` app bundle, select `Show Package Contents`, and it will open a new Finder window.
  3. In the new opened Finder window, go to the `Contents/MacOS` directory, then copy the `Designer` binary back to `QTDIR/bin`.
  4. Now pick a location to start writing our wrapper. I simply make a directory called `designer` in my home directory, then open a Terminal and switch to it.
  5. Back to the new opened Finder window, copy the `Contents/Resources/designer.icns` file to our new created `designer` directory.
  6. Create a Python module named `designer.py` in `designer` directory, and its content looks like this:
    import os
    # Replace this path to your QTDIR
    qt_home = '/Users/olliwang/workspace/qtjambi-mac-lgpl-4.5.2_01'
    
    def main():
        os.environ['QTDIR'] = qt_home
        os.environ['DYLD_LIBRARY_PATH'] = os.path.join(qt_home, 'lib')
        os.environ['QT_PLUGIN_PATH'] = os.path.join(qt_home, 'plugins')
        os.environ['PATH'] = os.path.join(qt_home, 'bin')
    
        classpaths = []
        for filename in os.listdir(qt_home):
            if filename.endswith('.jar'):
                classpath = os.path.join(qt_home, filename)
                classpaths.append(classpath)
        os.environ['CLASSPATH'] = ':'.join(classpaths)
        os.system(os.path.join(qt_home, 'bin/Designer'))
  7. Create a `config.jp` file with following content:
    dist_name = Designer
    main_entry_point = designer:main
    icns = designer.icns
  8. Run `jump app` in your Terminal, and you’ll see a new created directory called `dist`, our new app bundle is in there.
  9. Copy the created app bundle back to the `QTDIR/bin` directory, now double-click the `Designer` app bundle and everything should work fine. Cheers!

I use Python to write this wrapper for easy, you can of course do the same thing in Java. Just remember to modify the `main_entry_point` to the `Main Class` in config file.


Carl Zeiss 16-80mm F3.5-4.5

OK, I know it’s been a while, but I received my first Carl Zeiss lens a half month ago. Unfortunately, I didn’t have too much time to go out and take pictures recently because I’m a little busy with my new projects.

However, I did find a problem with this lens, that is, the focusing system doesn’t work well when using the wide-angle side. The camera will tell you it already focuses but it actually doesn’t. This occurs when the camera body focuses an object at the shortest length. I tried this with my A350 and new model A550, and three different 16-80mm lenses from three different stores, two of them are even SonyStyle stores, but the result is all the same. You need to step back about 1-5 centimeters to the object you are taking to make sure you won’t take out-of-focus pictures. I still don’t know why this happened, neither do the salesclerks.

Besides the only problem I found, this lens is still fine, it has a longer focal length than my previous one. The image quality is sharp from center to edge, and has nice color. More excited, it’s a Carl Zeiss lens!

ZEISS lens cap

I also bought a MC protector with Carl Zeiss T* coating, but I still have no idea about what does “MC” mean. Can anyone tell me, please? It would be appreciated.

SONY 62mm MC Protector with Carl Zeiss T* Coating




Follow

Get every new post delivered to your Inbox.