Pro Java 9 Games Development Leveraging the JavaFX APIs

(Michael S) #1

Chapter 2 ■ an IntroduCtIon to Content CreatIon: 2d new MedIa asset FundaMentals


Digital Image Data Optimization: Using Compression, Indexed Color,


and Dithering


A number of factors affect digital image compression, and you can use some basic techniques to achieve a
better-quality result with a smaller data footprint. This is a primary objective in optimized digital imagery;
obtaining the smallest possible data footprint for your application (in this case it is a game) while at the same
time achieving the highest-quality visual result. We’ll start with the aspects that most significantly affect the
data footprint and examine how each of these contributes to data footprint optimization for any given digital
image. Interestingly, these are similar to the order of the digital imaging concepts that we have covered thus
far during this section on imaging.
The most critical contributor to a resulting digital image asset file size, what I like to call the data
footprint, is going to be the number of pixels, or the resolution of a digital image. This is logical, because
each of the pixels needs to be stored, along with the color and alpha values that are contained in their three
(24-bit) or four (32-bit) channels. The smaller you can get your image resolution, while still having it look
sharp, the smaller the resulting file size will be.
Raw (or uncompressed) image size is calculated by width times height times 3 for 24-bit RBG images,
or for 32-bit ARGB images that would be width times height times 4. For instance, an uncompressed,
true-color, 24-bit VGA image will have 640 times 480 times 3, equaling 921,600 bytes of original (raw)
uncompressed digital image data. To determine the number of kilobytes that is in this raw VGA image, you
would divide 921,600 by 1024 (the number of bytes that are in a kilobyte), and this would give you an even
900 KB of data in a true-color VGA image.
It is important to optimize for raw (uncompressed) image size by optimizing your digital imagery
resolution. This is because once an image is decompressed out of a game application file into system
memory, this is the amount of memory that it is going to occupy since the image is going to be stored pixel
for pixel using a 24-bit (RGB) or 32-bit (ARGB) representation in memory. This is one of the reasons I’m
using PNG24 and PNG32 for my game development and not indexed color (GIF or PNG8) because if the
OS is going to transmute the color to a 24-bit color “space,” then we should utilize that 24-bit color space for
quality reasons and deal with (accept) a slightly larger application file size.
Image color depth is the next most critical contributor to the data footprint of a compressed image,
because the number of pixels in the image is multiplied by one (8-bit), two (16-bit), three (24-bit), or four
(32-bit) color data channels. This small file size is the reason 8-bit indexed color images are still widely used,
especially using the GIF image format.
Indexed color images can simulate true-color images, if the colors that are used to make up the image
do not vary too widely. Indexed color imagery uses only 8 bits of data (256 colors) to define the image pixel
color, using what is called a palette of up to 256 optimally selected colors, instead of 3 RGB color channels,
or 4 ARGB color channels, containing 256 levels of color each. Again, it is important to note that after you
turn a 24-bit image into an 8-bit image by compressing it, then once it is decompressed in system memory
and turned back into a 24-bit RGB or ARGB data model used for the game (the representation used out of
system memory), you only have a potential (maximum) 256 colors out of the original 16.8M colors to use!
This is why I am advocating using PNG24 or PNG32 imagery, rather than GIFs or PNG1 (1-color), PNG2
(4-color), PNG4 (16-color), and PNG8 (256-color) images that JavaFX also supports.
Depending on how many colors are used in any given 24-bit source image, using 256 colors to represent
an image originally containing 16,777,216 colors can cause an effect called banding. This is where the
transfer between adjoining colors in the resulting (from compression) 256 (or less) color palette is not
gradual and thus doesn’t appear to be a smooth color gradient. Indexed color images have an option to
visually correct for banding, called dithering.
Dithering is an algorithmic process of creating dot patterns along those edges between any adjoining
colors within an image to trick the eye into thinking there’s a third color used. Dithering will give you a
maximum perceptual amount of colors of 65,536 colors (256x256), but this will occur (be necessary) only
if each of those 256 colors borders one of the other (different) 256 colors. Still, you can see the potential for

Free download pdf