Sunday, July 12, 2009

Graphics - Format Selection

The Problem
So, you decided to edit an picture from you camera. Most likely, it came from the camera as a JPG or JPEG file. However, if you edit it and save, and especially repeat this process couple times, your image will look different. Wherever there was a smooth transition from one color, or shade, to another color or shade, you will notice strange lines, like contour lines on a map.

The Mystery Revealed
The reason is, each time your editing software saves a file in JPEG format, it compresses the image and introduces small changes to your picture. These changes are small and they are not noticeable. Because JPEG compression algorithm is allowed to perform these small changes, it is able to compress the file so nicely. So, it all works great, unless you save it not once but 3, 4 or 8 times. Then these small changes accumulate and the deformations are very well visible and not really pretty. Your picture is ruined.

The Solution
So, what, shall you avoid the JPEG format? Not at all. However, if you decide to edit the picture, save it in a lossless format. You can open it, edit and save as many times as you want, and you picture will not deteriorate. Than, when you are ready to post the picture to your website or print it, save it as a JPEG file. But what is a lossless format? Well, there are two good candidates: TIFF and PNG. TIFF is better, in a way, because it can save more than just the image. It can also save paths and layers (I'm not sure of layers, though). Just make sure, that you don't let the TIFF formatter use JPEG as compression. You would get into the same problem as described above. PNG may be even a bit smaller, but it will not save anything more than the image itself.

Tool
GIMP image editor will allow you to open and save in all these formats without problems.

Sunday, July 5, 2009

Date, Time, SQLite and Android

This post summarizes my recent experience (problem, finally solved) with storing and then reading and displaying the date and time in Android application.

Storing the current time/date in SQLite
The most common way is to do:
database.execSQL("update TABLE_NAME set COLUMN_NAME = datetime('now') where ...");
As a result, SQLite stores a string representing the current time in UTC (GMT), using the ISO8601 date/time format. This format (YYYY-MM-DD HH:MM:SS), is by the way suitable for date/time comparisons. The fact that the value stored is in UTC and not in a local time zone, is actually nice. More about it below.

Retrieving a time/date and displaying it
To retrieve the value, follow the recommended Android practice:
Cursor row = databaseHelper.query(true, TABLE_NAME, new String[] {
COLUMN_INDEX}, ID_COLUMN_INDEX + "=" + rowId,
null, null, null, null, null);
String dateTime = row.getString(row.getColumnIndexOrThrow(COLUMN_INDEX));
This, returns a string, parse it and reformat to your local format and time zone:
DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
date = iso8601Format.parse(dateTime);
} catch (ParseException e) {
Log.e(TAG, "Parsing ISO8601 datetime failed", e);
}

long when = date.getTime();
int flags = 0;
flags |= android.text.format.DateUtils.FORMAT_SHOW_TIME;
flags |= android.text.format.DateUtils.FORMAT_SHOW_DATE;
flags |= android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
flags |= android.text.format.DateUtils.FORMAT_SHOW_YEAR;

String finalDateTime = android.text.format.DateUtils.formatDateTime(context,
when + TimeZone.getDefault().getOffset(when), flags);
Note the when + TimeZone.getDefault().getOffset(when) above. This does the trick to convert the UTC time/date to local time. The DateUtils.formatDateTime() seem to be supposed to do this, but it doesn't, or I wasn't able to find a way to achieve it.

And that's it.