1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
13 * Created on 12.11.2005
\r
14 * @author Toni Kalajainen
\r
16 package org.simantics.utils.ui.gfx;
\r
18 import java.awt.image.BufferedImage;
\r
19 import java.awt.image.ColorModel;
\r
20 import java.awt.image.ComponentColorModel;
\r
21 import java.awt.image.DirectColorModel;
\r
22 import java.awt.image.IndexColorModel;
\r
23 import java.awt.image.WritableRaster;
\r
24 import java.nio.ByteBuffer;
\r
26 import org.eclipse.swt.graphics.ImageData;
\r
27 import org.eclipse.swt.graphics.PaletteData;
\r
28 import org.eclipse.swt.graphics.RGB;
\r
30 public class ImageUtils {
\r
32 public final static PaletteData RGB24 = new PaletteData(0xff, 0xff00, 0xff0000);
\r
34 public static ImageData convertPaletteToRGB24(ImageData data) {
\r
35 return convertPalette(data, RGB24, 24);
\r
39 * Converts image data to RGB format
\r
41 * @param data source data
\r
42 * @return result data
\r
44 public static ImageData convertPalette(ImageData data, PaletteData newPalette, int newDepth) {
\r
45 if (paletteDataEquals(data.palette, newPalette))
\r
47 ImageData result = new ImageData(data.width, data.height, newDepth, newPalette);
\r
48 boolean hasAlpha = data.alphaData != null;
\r
49 int width = data.width;
\r
50 int height = data.height;
\r
51 // Very slow operation
\r
52 for (int y = 0; y < height; y++)
\r
53 for (int x = 0; x < width; x++) {
\r
55 RGB rgb = data.palette.getRGB(data.getPixel(x, y));
\r
56 result.setPixel(x, y, result.palette.getPixel(rgb));
\r
60 int alpha = data.getAlpha(x, y);
\r
61 result.setAlpha(x, y, alpha);
\r
68 * Convert Device-independent image data format from one format to another.
\r
70 * @param sourceImage source image, it must contain image data
\r
71 * @param destImage destination image, it must be empty image
\r
73 // public static void convertImageData(ImageData sourceImage, ImageData
\r
75 // int swid = sourceImage.width;
\r
76 // int shei = sourceImage.height;
\r
77 // int dwid = destImage.width;
\r
78 // int dhei = destImage.height;
\r
81 // if (swid!=dwid || shei!=dhei)
\r
82 // sourceImage = sourceImage.scaledTo(dwid, dhei);
\r
84 // // Convert palette
\r
85 // PaletteData spal = sourceImage.palette;
\r
86 // PaletteData dpal = destImage.palette;
\r
88 public static boolean paletteDataEquals(PaletteData p1, PaletteData p2) {
\r
89 if (p1.isDirect != p2.isDirect)
\r
92 RGB rgb1[] = p1.colors;
\r
93 RGB rgb2[] = p2.colors;
\r
94 if (rgb1.length != rgb2.length)
\r
96 for (int i = 0; i < rgb1.length; i++)
\r
97 if (rgb1[i].blue != rgb2[i].blue || rgb1[i].green != rgb2[i].green || rgb1[i].red != rgb2[i].red)
\r
102 if (p1.blueMask != p2.blueMask)
\r
104 if (p1.blueShift != p2.blueShift)
\r
106 if (p1.greenMask != p2.greenShift)
\r
108 if (p1.greenMask != p2.greenMask)
\r
110 if (p1.redMask != p2.redMask)
\r
112 if (p1.redShift != p2.redShift)
\r
118 // ks. org.eclipse.gmf.runtime.draw2d.ui.render.image.ImageConverter
\r
119 // Sama toiminnallisuus, mutta GMF riippuvuus
\r
120 public static BufferedImage convertToAWT(ImageData data) {
\r
121 ColorModel colorModel = null;
\r
122 PaletteData palette = data.palette;
\r
123 if (palette.isDirect) {
\r
124 // has alpha and is 24bit (others are not supported)
\r
125 if (data.alphaData != null && data.depth==24) {
\r
126 colorModel = new DirectColorModel(data.depth+8, palette.redMask, palette.greenMask, palette.blueMask, 0xff000000);
\r
127 BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null);
\r
128 WritableRaster raster = bufferedImage.getRaster();
\r
129 int[] pixelArray = new int[4];
\r
130 for (int y = 0; y < data.height; y++) {
\r
131 for (int x = 0; x < data.width; x++) {
\r
132 int pixel = data.getPixel(x, y);
\r
133 RGB rgb = palette.getRGB(pixel);
\r
134 pixelArray[0] = rgb.red;
\r
135 pixelArray[1] = rgb.green;
\r
136 pixelArray[2] = rgb.blue;
\r
137 pixelArray[3] = data.getAlpha(x, y);
\r
138 raster.setPixels(x, y, 1, 1, pixelArray);
\r
141 return bufferedImage;
\r
143 // FIXME: this does not work with 16bit images (colors are wrong)
\r
144 colorModel = new DirectColorModel(data.depth, palette.redMask, palette.greenMask, palette.blueMask);
\r
145 BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null);
\r
146 WritableRaster raster = bufferedImage.getRaster();
\r
147 int[] pixelArray = new int[3];
\r
148 for (int y = 0; y < data.height; y++) {
\r
149 for (int x = 0; x < data.width; x++) {
\r
150 int pixel = data.getPixel(x, y);
\r
151 RGB rgb = palette.getRGB(pixel);
\r
152 pixelArray[0] = rgb.red;
\r
153 pixelArray[1] = rgb.green;
\r
154 pixelArray[2] = rgb.blue;
\r
155 raster.setPixels(x, y, 1, 1, pixelArray);
\r
158 return bufferedImage;
\r
161 RGB[] rgbs = palette.getRGBs();
\r
162 byte[] red = new byte[rgbs.length];
\r
163 byte[] green = new byte[rgbs.length];
\r
164 byte[] blue = new byte[rgbs.length];
\r
165 for (int i = 0; i < rgbs.length; i++) {
\r
167 red[i] = (byte) rgb.red;
\r
168 green[i] = (byte) rgb.green;
\r
169 blue[i] = (byte) rgb.blue;
\r
171 if (data.transparentPixel != -1) {
\r
172 colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue, data.transparentPixel);
\r
174 colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue);
\r
176 BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null);
\r
177 WritableRaster raster = bufferedImage.getRaster();
\r
178 int[] pixelArray = new int[1];
\r
179 for (int y = 0; y < data.height; y++) {
\r
180 for (int x = 0; x < data.width; x++) {
\r
181 int pixel = data.getPixel(x, y);
\r
182 pixelArray[0] = pixel;
\r
183 raster.setPixel(x, y, pixelArray);
\r
186 return bufferedImage;
\r
190 public static ImageData convertToSWT(BufferedImage bufferedImage) {
\r
191 if (bufferedImage.getColorModel() instanceof DirectColorModel) {
\r
192 DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel();
\r
193 PaletteData palette = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(), colorModel.getBlueMask());
\r
194 ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
\r
195 WritableRaster raster = bufferedImage.getRaster();
\r
196 int[] pixelArray = { 0, 0, 0, 255 };
\r
197 for (int y = 0; y < data.height; y++) {
\r
198 for (int x = 0; x < data.width; x++) {
\r
199 raster.getPixel(x, y, pixelArray);
\r
200 int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
\r
201 data.setPixel(x, y, pixel);
\r
202 data.setAlpha(x, y, pixelArray[3]);
\r
206 } else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
\r
207 IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel();
\r
208 int size = colorModel.getMapSize();
\r
209 byte[] reds = new byte[size];
\r
210 byte[] greens = new byte[size];
\r
211 byte[] blues = new byte[size];
\r
212 colorModel.getReds(reds);
\r
213 colorModel.getGreens(greens);
\r
214 colorModel.getBlues(blues);
\r
215 RGB[] rgbs = new RGB[size];
\r
216 for (int i = 0; i < rgbs.length; i++) {
\r
217 rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
\r
219 PaletteData palette = new PaletteData(rgbs);
\r
220 ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
\r
221 data.transparentPixel = colorModel.getTransparentPixel();
\r
222 WritableRaster raster = bufferedImage.getRaster();
\r
223 int[] pixelArray = new int[1];
\r
224 for (int y = 0; y < data.height; y++) {
\r
225 for (int x = 0; x < data.width; x++) {
\r
226 raster.getPixel(x, y, pixelArray);
\r
227 data.setPixel(x, y, pixelArray[0]);
\r
231 } else if (bufferedImage.getColorModel() instanceof ComponentColorModel) {
\r
232 // works with BufferedImage.TYPE_3BYTE_BGR
\r
233 ComponentColorModel colorModel = (ComponentColorModel)bufferedImage.getColorModel();
\r
234 PaletteData palette = new PaletteData(0xFF0000, 0x00FF00, 0x0000FF);
\r
235 ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
\r
236 WritableRaster raster = bufferedImage.getRaster();
\r
237 int[] pixelArray = { 0, 0, 0, 255 };
\r
238 for (int y = 0; y < data.height; y++) {
\r
239 for (int x = 0; x < data.width; x++) {
\r
240 raster.getPixel(x, y, pixelArray);
\r
241 int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
\r
242 data.setPixel(x, y, pixel);
\r
243 data.setAlpha(x, y, pixelArray[3]);
\r
252 * Creates ImageData from RGBA byte array
\r
254 * @param width width of the image
\r
255 * @param height height of the image
\r
256 * @param data data of the image
\r
257 * @return <code>ImageData</code>
\r
259 public static ImageData _getImageDataFromRGBA(int width, int height, byte[] data) {
\r
260 // these seem to do nothing, r and b channels are flipped anyways
\r
261 int redMask = 0x0000ff00;
\r
262 int greenMask = 0x00ff0000;
\r
263 int blueMask = 0xff000000;
\r
264 PaletteData paletteData = new PaletteData(redMask, greenMask, blueMask);
\r
265 // flipping r and b channels
\r
266 int maxByte = width * height * 4;
\r
268 for (int i = 0; i < maxByte; i += 4) {
\r
270 data[i] = data[i + 2];
\r
273 ImageData imageData = new ImageData(width, height, 32, paletteData, 4, data);
\r
274 // TODO add alpha channel
\r
275 // imageData.alphaData = xyz
\r
281 * Converts ImageData to RGB(A) ByteBuffer
\r
285 public static void convertToRGBA(ImageData imageData, ByteBuffer buffer) {
\r
286 int width = imageData.width;
\r
287 int height = imageData.height;
\r
288 if (!imageData.palette.isDirect || imageData.depth != 24) {
\r
289 ImageUtils.convertPaletteToRGB24(imageData);
\r
291 boolean hasAlpha = false;
\r
292 if (imageData.alphaData != null) {
\r
297 for (int j = 0; j < height; j++) {
\r
298 for (int i = 0; i < width; i++) {
\r
299 index = j*width + i;
\r
300 rgb = imageData.palette.getRGB(imageData.getPixel(i, j));
\r
301 buffer.put((byte)rgb.red);
\r
302 buffer.put((byte)rgb.green);
\r
303 buffer.put((byte)rgb.blue);
\r
305 buffer.put(imageData.alphaData[index]);
\r