001 /* 002 * RGBQuantizer 003 * 004 * Copyright (c) 2001, 2002 Marco Schmidt. 005 * All rights reserved. 006 */ 007 008 package net.sourceforge.jiu.color.quantization; 009 010 import net.sourceforge.jiu.data.Palette; 011 012 /** 013 * An interface for an RGB color quantizer. 014 * Color quantizers take an input image and produce an output image 015 * that looks like the original but uses less colors. 016 * Keeping the error (the difference between input and output image) as small 017 * as possible is important - the more similar input and output are, the better. 018 * <p> 019 * Similarity between to pixels (or, more accurately, the colors of two pixels) 020 * can be defined by their distance in color space. 021 * Imagine two colors given by <em>(r<sub>1</sub>, g<sub>1</sub>, b<sub>1</sub>)</em> 022 * and 023 * <em>(r<sub>2</sub>, g<sub>2</sub>, b<sub>2</sub>)</em>. 024 * The distance can then be defined as 025 * <em>sqrt((r<sub>1</sub> - r<sub>2</sub>)<sup>2</sup> + 026 * (g<sub>1</sub> - g<sub>2</sub>)<sup>2</sup> + (b<sub>1</sub> - b<sub>2</sub>)<sup>2</sup>)</em> 027 * (with <em>sqrt</em> being the square root). 028 * <p> 029 * A quantizer has two main tasks: 030 * <ol> 031 * <li><strong>Find a palette.</strong> 032 * Some quantizers create <em>custom</em> palettes for a 033 * given input (e.g. {@link MedianCutQuantizer} or {@link OctreeColorQuantizer}, 034 * other quantizers use fixed palettes (e.g. {@link UniformPaletteQuantizer}). 035 * Using a custom palette typically results in a better output image 036 * (it is more similar because it takes into consideration the content 037 * of the input). 038 * However, using <em>fixed</em> palettes requires less CPU time and memory and 039 * is sufficient in many cases from a point of view of output quality. 040 * <p> 041 * If a quantizer does use a fixed palette, this first step obviously is not 042 * so much about finding the palette but about specifying it. 043 * </li> 044 * <li><strong>Map the input image to the palette.</strong> 045 * For each pixel in the truecolor input image the mapping procedure must 046 * find the color in the palette that is closest to that input pixel 047 * so that the difference between source and destination pixel 048 * is as small as possible. 049 * <p> 050 * The code that does the mapping from the original to any given palette 051 * could be shared among quantizers - after all, the goal is always the same, 052 * picking the palette entry with the smallest distance in color space 053 * to the original pixel. 054 * However, sometimes the data structures built while finding the palette 055 * can be reused for faster mapping from the original to output. 056 * This is the case for both the MedianCutQuantizer and the OctreeColorQuantizer. 057 * </li> 058 * </ol> 059 * <p> 060 * Dithering methods like error diffusion dithering 061 * may be used to increase 062 * the quality of the output. 063 * Note however that dithering introduces noise that makes the quantized image harder to 064 * compress and in some cases unusable for post-processing (the noise may be an obstacle for 065 * image processing algorithms). 066 * <p> 067 * This quantizer interface was designed with JIU's error diffusion dithering operation 068 * {@link net.sourceforge.jiu.color.dithering.ErrorDiffusionDithering} in mind. 069 * 070 * 071 * @author Marco Schmidt 072 */ 073 public interface RGBQuantizer 074 { 075 /** 076 * Return a Palette object with the list of colors to be used in the quantization 077 * process. 078 * That palette may be fixed or created specifically for a given input image. 079 * @return Palette object for destination image 080 */ 081 Palette createPalette(); 082 083 /** 084 * This method maps a triplet of intensity values to its quantized counterpart 085 * and returns the palette index of that quantized color. 086 * The index values for the two arrays are taken from RGBIndex. 087 * @param origRgb the three samples red, green and blue for which a good match is searched in the palette 088 * @param quantizedRgb will hold the three samples found to be closest to origRgb after the call to this method 089 * @return int index in the palette of the match quantizedRgb 090 */ 091 int map(int[] origRgb, int[] quantizedRgb); 092 }