Saving/loading document state quickly and robustly for image editor

753 views Asked by At

I'm looking for some critique on my approach for storing the state of a bitmap editor for Android and iPhone mobile phones. Even a "Looks fine to me!" response would be great!

In the application, the current user document contains several bitmap layers (each maybe 1024 by 768 pixels) that can each be painted on. The basic requirements for the application are:

  1. I need to be able to save and restore the document state.

  2. When the user quits the application or gets a phone call, I need to be able to save the document state quickly (within about 2 seconds).

  3. If the application crashes, I need to be able to restore the document state (it's OK if the user loses maybe 30 seconds of work though).

For 1, I cannot find any open file formats that support layers. I was going to go with the following file structure for storing my document:

document_folder/
  layer1.png
  layer2.png
  ...
  metadata.xml

The layers are just stored as .png files and the .xml file contains data such as which layers are currently visible. The document folder can either be opened as is by the application or the folder can be stored in a .zip file. This seems like a nice simple format for other applications to work with too.

In addition to .png files, I will also allow layers to be saved in a custom .raw file format which contain unprocessed raw pixel data from bitmaps. I can save these very quickly on the phone (<0.5s) whereas .png files take a second or two.

My plan for quick-saving the document was, on start-up, to create a folder called /autosave, and save .raw versions of all the layers there. After a few editing commands on one layer, I would then update the .raw file for that layer in a background thread. For robustness when saving, I would save the layer as e.g. layer1_tmp.raw and when I've confirmed the file has been fully written, replace layer1.raw with this file.

Should the application crash during use, I would just reopen the /autosave folder. When the application is closed or the user gets a phone call, I just have to update the last modified layer to autosave. When the user wants to save, I just convert all the .raw files to .png files and then zip the folder.

What do you think? Are there any obvious flaws? Is there a simpler way? Am I reinventing the wheel somehow? Thanks.

2

There are 2 answers

1
damian On

Your idea souds good to me: save the layers in the background, as you go. Any layer that the user isn't currently editing should be queued to be saved as soon as they switch away from it to a different layer. If the app is interrupted, you just have to save the current working layer, which as you say can be done in 0.5s.

Why bother with the png format anyway? You only need it if exporting data to another machine/system, right?

0
dbm On

I think you have a great plan there. I would probably go the same way (but that itself doesn't mean anything :-)

What I was thinking is if you could have not only a worker thread saving the file but a complete background service (with a worker thread of course, since a service itself also runs in the main thread).

This way you would have guaranteed that there is always something alive that can handle your layer deltas, regardless if the drawing activity has crashed or someone is calling you. Suddenly you don't have the same timing constraints (the write operation can take 10 seconds if it wants to, your activity is neither blocked, nor dependent of the write operation). Of course your service would then commit suicide when it has emptied its save queue (to save system resources).

What I don't know in order to further promote this idea is how much data you're writing to the raw-file? Do you write the complete 1024x768 layer every time or do you only rewrite the changed parts? I'm also unsure of how the data would actually be transmitted to the service (from the Activity). I don't know if there is a maximum size of a byte-array-extra an Intent can handle.

Hope this gives you further ideas.

Cheers!