Search code examples
javagraphicsgraphics2d

Render a 2D image targeted for a device with a limited colour palette


I need to render a bitmap image (on my PC), intended to be displayed on a device with an extremely limited colour palette (e.g. 16 colours consisting of RED (0xFF0000), DARK_RED (0x880000), GRAY etc). I only need to render 2D geometric objects - text, points, lines, polygons, and arcs. I want to use anti-aliasing (though due to the limited palette this may itself be very limited). I'd like to display it on the screen before saving it as say PNG to be transferred to the target device.

What's the basic approach, assuming I'm starting with a GraphicsD obj obtained from a BufferedImage? I know how to display the image on an AWT Frame and how to save it with ImageIO, but am less clear on rendering the shapes with a specific palette in mind.

Options that spring to mind are:

  1. Render it in full 24bit colour using Graphics2D API, and with anti-aliasing enabled. Post-process to map each colour to it's closest neighbour in the target palette.

  2. Convince Graphics2D to use the target palette (IndexColorModel?). Render via Graphics2D API.

  3. Write my own primitives for rendering lines, shapes etc.

Option 3 I'm not keen on. Option 1 is doable, but I can't help feeling that anti-aliasing would work better if it was doing so against the target palette. This may just be paranoia.

Option 2 is unclear to me, perhaps not possible.

Ideas?


Solution

  • The solution appears to be quite straightforward. First create an IndexColorModel that contains the colors available on the target device. Then create a BufferedImage, specifying TYPE_BYTE_INDEXED, and supply the IndexColorModel. And then enable anti-aliasing :

    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_INDEXED, indexColorModel);
    Graphics2D gfx2d = image.createGraphics();
    gfx2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
    gfx2d.setColor(Color.WHITE);
    gfx2d.drawLine(10, 10, 100, 160);
    

    The Graphics2D rendering primitives will apply anti-aliasing using only the colours in the IndexColorModel, i.e. the target device colours.