/* This file is part of Green. * * Copyright (C) 2005 The Research Foundation of State University of New York * All Rights Under Copyright Reserved, The Research Foundation of S.U.N.Y. * * Green is free software, licensed under the terms of the Eclipse * Public License, version 1.0. The license is available at * http://www.eclipse.org/legal/epl-v10.html */ package edu.buffalo.cse.green.util; import static edu.buffalo.cse.green.preferences.PreferenceInitializer.P_COLOR_COMPARTMENT_BORDER; import static edu.buffalo.cse.green.preferences.PreferenceInitializer.P_COLOR_NOTE; import static edu.buffalo.cse.green.preferences.PreferenceInitializer.P_COLOR_NOTE_BORDER; import static edu.buffalo.cse.green.preferences.PreferenceInitializer.P_COLOR_NOTE_TEXT; import static edu.buffalo.cse.green.preferences.PreferenceInitializer.P_COLOR_REL_ARROW_FILL; import static edu.buffalo.cse.green.preferences.PreferenceInitializer.P_COLOR_REL_LINE; import static edu.buffalo.cse.green.preferences.PreferenceInitializer.P_COLOR_REL_TEXT; import static edu.buffalo.cse.green.preferences.PreferenceInitializer.P_COLOR_TYPE_BORDER; import static edu.buffalo.cse.green.preferences.PreferenceInitializer.P_COLOR_TYPE_BORDER_HIDDENR; import static edu.buffalo.cse.green.preferences.PreferenceInitializer.P_COLOR_TYPE_TEXT; import static edu.buffalo.cse.green.preferences.PreferenceInitializer.P_COLOR_UML; import java.util.HashSet; import java.util.Set; import org.eclipse.draw2d.ColorConstants; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.SWTGraphics; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Drawable; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.graphics.PaletteData; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Display; import edu.buffalo.cse.green.PlugIn; /** * Converts from images (Draw2D) to picture file formats. * * @author evertwoo */ public class ImageWriterUtil { public static final int FORMAT_BMP = 0; public static final int FORMAT_GIF = 2; public static final int FORMAT_JPG = 4; public static final int FORMAT_PNG = 5; public static final int FORMAT_TIF = 6; private static RGB[] GRAYSCALE_COLORS; private static RGB[] GREEN_COLORS; private static final int GREEN_COLOR_BACKGROUND; static { GRAYSCALE_COLORS = new RGB[256]; for (int c = 0; c < GRAYSCALE_COLORS.length; ++c) { GRAYSCALE_COLORS[c] = new RGB(c, c, c); } // set up the palette to contain at least the UML colors Set<RGB> basicColorSet = new HashSet<RGB>(); basicColorSet.add(getRGB(ColorConstants.listBackground)); basicColorSet.add(getRGB(PlugIn.getColorPreference(P_COLOR_UML))); basicColorSet.add(getRGB(PlugIn.getColorPreference(P_COLOR_TYPE_BORDER))); basicColorSet.add(getRGB(PlugIn.getColorPreference(P_COLOR_TYPE_BORDER_HIDDENR))); basicColorSet.add(getRGB(PlugIn.getColorPreference(P_COLOR_TYPE_TEXT))); basicColorSet.add(getRGB(PlugIn.getColorPreference(P_COLOR_COMPARTMENT_BORDER))); basicColorSet.add(getRGB(PlugIn.getColorPreference(P_COLOR_NOTE))); basicColorSet.add(getRGB(PlugIn.getColorPreference(P_COLOR_NOTE_BORDER))); basicColorSet.add(getRGB(PlugIn.getColorPreference(P_COLOR_NOTE_TEXT))); basicColorSet.add(getRGB(PlugIn.getColorPreference(P_COLOR_REL_ARROW_FILL))); basicColorSet.add(getRGB(PlugIn.getColorPreference(P_COLOR_REL_LINE))); basicColorSet.add(getRGB(PlugIn.getColorPreference(P_COLOR_REL_TEXT))); GREEN_COLORS = new RGB[256]; basicColorSet.toArray(GREEN_COLORS); // Make the rest of the colors greyscale int startIndexBase = basicColorSet.size(); for (int c = startIndexBase; c < GREEN_COLORS.length; ++c) { int value = (c - startIndexBase) * GREEN_COLORS.length / (GREEN_COLORS.length - startIndexBase); GREEN_COLORS[c] = new RGB(value, value, value); } GREEN_COLOR_BACKGROUND = ImageWriterUtil.getPaletteIndex(255, 255, 255, GREEN_COLORS); } private ImageWriterUtil() {} /** * Writes a figure to a device. * * @param figure - The figure * @param dest - The destination to draw to. * @param format - The format to draw in. * @param backgroundColor - The background color. */ public static void writeFigureToDeviceContext( IFigure figure, Drawable dest, int format, RGB backgroundColor) { // Derived from org.eclipse.draw2d.BufferedGrapicsSource SWTGraphics destGraphics = new SWTGraphics(new GC(dest)); figure.setBackgroundColor(new Color(null, backgroundColor)); destGraphics.translate(figure.getBounds().getTopLeft().negate()); figure.paint(destGraphics); } /** * Loads a figure. * * @param figure - The figure. * @param imageIO - The loader. * @param format - The format. */ public static void writeFigureToLoader( IFigure figure, ImageLoader imageIO, int format) { writeFigureToLoader(figure, imageIO, format, GREEN_COLORS[GREEN_COLOR_BACKGROUND]); } /** * Loads a figure. * * @param figure - The figure. * @param imageIO - The loader. * @param format - The format. * @param backgroundColor - The background color. */ public static void writeFigureToLoader( IFigure figure, ImageLoader imageIO, int format, RGB backgroundColor) { Rectangle figureBounds = figure.getBounds(); imageIO.logicalScreenWidth = figureBounds.width; imageIO.logicalScreenHeight = figureBounds.height; Image destImage = new Image(null, figureBounds.width, figureBounds.height); writeFigureToDeviceContext(figure, destImage, format, backgroundColor); if (format == ImageWriterUtil.FORMAT_GIF) { // GIF only supports 8 bits // per pixel ImageData destImageData = ImageWriterUtil .getImageDataInEightBitColor(destImage.getImageData()); imageIO.data = new ImageData[] { destImageData }; imageIO.backgroundPixel = GREEN_COLOR_BACKGROUND; } else { imageIO.data = new ImageData[] { destImage.getImageData() }; } imageIO.repeatCount = 0; } /** * Loads an image. * * @param image - The image. * @param imageIO - The loader. * @param format - The format. */ public static void writeImageToLoader( Image image, ImageLoader imageIO, int format) { writeImageToLoader(image, imageIO, format, -1); } /** * Loads an image. * * @param image - The image. * @param imageIO - The loader. * @param format - The format. * @param backgroundColorIndex - The background color's index in the * palette. */ public static void writeImageToLoader( Image image, ImageLoader imageIO, int format, int backgroundColorIndex) { org.eclipse.swt.graphics.Rectangle imageBounds = image.getBounds(); imageIO.logicalScreenWidth = imageBounds.width; imageIO.logicalScreenHeight = imageBounds.height; if (format == ImageWriterUtil.FORMAT_GIF) { // GIF only supports 8 bits // per pixel ImageData imageData = ImageWriterUtil .getImageDataInEightBitColor(image.getImageData()); imageIO.data = new ImageData[] { imageData }; imageIO.backgroundPixel = backgroundColorIndex; } else { imageIO.data = new ImageData[] { image.getImageData() }; } imageIO.repeatCount = 0; } /** * Converts an image to 8-bit color. * * @param destImageData - The image data. * @return The converted image. */ protected static ImageData getImageDataInEightBitColor( ImageData destImageData) { ImageData destImageDataGrayscale = new ImageData(destImageData.width, destImageData.height, 8, new PaletteData(GREEN_COLORS)); Image origImage = new Image(Display.getDefault (), destImageData); Image gifImage = new Image(Display.getDefault (), destImageDataGrayscale); GC gifGC = new GC (gifImage); gifGC.drawImage(origImage, 0, 0); gifGC.dispose(); return gifImage.getImageData(); } /** * @param color - The color. * @param colorPalette - The palette. * @return The index of the color in the palette. */ public static int getPaletteIndex(int color, RGB[] colorPalette) { return getPaletteIndex((color & 0xFF), ((color >> 8) & 0xFF), ((color >> 16) & 0xFF), colorPalette); } /** * @param r - The red value of the color. * @param g - The green value of the color. * @param b - The blue value of the color. * @param colorPalette - The palette. * @return The index of the color in the palette. */ public static int getPaletteIndex(int r, int g, int b, RGB[] colorPalette) { int minDifference = 256 * 3; // some huge difference int indexMinDiff = -1; for (int c = 0; c < colorPalette.length; c++) { int difference = Math.abs(colorPalette[c].red - r) + Math.abs(colorPalette[c].green - g) + Math.abs(colorPalette[c].blue - b); if (difference < minDifference) { indexMinDiff = c; minDifference = difference; if (difference == 0) { break; } } } return indexMinDiff; } /** * @param color - The color. * @return The <code>RGB</code> representation of the given * <code>Color</code>. */ private static RGB getRGB(Color color) { return new RGB(color.getRed(), color.getGreen(), color.getBlue()); } }