Tuesday, May 27, 2014

Image Rendering Refactoring

While working on the faster image loading mechanism for Cornerstone, I found myself making further changes to the drawImage() function.  I already felt this function was too complex as it had to deal with at least 12 different flows due to the different types of images and caching scenarios.  I realized that adding support for the different faster image loading the function would quickly become hard to read and unmaintainable.  Clearly something had to change, but what?

After thinking about it for a bit, I had an "aha" moment and realized that the image rendering responsibility should be moved to the image loader.  The image loader design was already providing flexibility with respect to the image format and protocol used and it would also have to be aware of the various fast image loading techniques being used.  Adding the image rendering responsibility to the image loader will allow the fastest possible rendering.

The only issue with moving rendering to the image loader is code reuse.  I envision a wide variety of image loaders that pull full uncompressed pixel data from different servers in different formats.  For these types of image loaders, it doesn't make sense to have them cut and paste the rendering code from another image loader.  It would be much better to have this generic image rendering mechanism in a shared location.

Based on the above, I decided to split the drawImage() function into three new functions - renderGrayscaleImage(), renderColorImage() and renderWebImage().  This simple refactoring immediately made the code easier to understand so I knew I was on the right path.  The drawImage() function was simplified to some boilerplate logic and delegated the actual rendering to the image object returned by the image loader.  I then proceeded to modify each of the image loaders to call one of the three newly created render functions and everything was working again.

This simple refactoring not only made the existing code simpler and easier to understand, but it also prepares Cornerstone for the more complex functionality that will be needed to handle faster image loading.  You can find the commit for these changes here

No comments:

Post a Comment