X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.utils.ui%2Fsrc%2Forg%2Fsimantics%2Futils%2Fui%2Fgfx%2FImageUtils.java;fp=bundles%2Forg.simantics.utils.ui%2Fsrc%2Forg%2Fsimantics%2Futils%2Fui%2Fgfx%2FImageUtils.java;h=7647c4ee220f22b140a48d9f4ed7fd53c03719a2;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hp=f95262f6afa277a10200e7f696c87ef0a6565d1c;hpb=24e2b34260f219f0d1644ca7a138894980e25b14;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/gfx/ImageUtils.java b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/gfx/ImageUtils.java index f95262f6a..7647c4ee2 100644 --- a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/gfx/ImageUtils.java +++ b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/gfx/ImageUtils.java @@ -1,312 +1,312 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management - * in Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -/* - * Created on 12.11.2005 - * @author Toni Kalajainen - */ -package org.simantics.utils.ui.gfx; - -import java.awt.image.BufferedImage; -import java.awt.image.ColorModel; -import java.awt.image.ComponentColorModel; -import java.awt.image.DirectColorModel; -import java.awt.image.IndexColorModel; -import java.awt.image.WritableRaster; -import java.nio.ByteBuffer; - -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.PaletteData; -import org.eclipse.swt.graphics.RGB; - -public class ImageUtils { - - public final static PaletteData RGB24 = new PaletteData(0xff, 0xff00, 0xff0000); - - public static ImageData convertPaletteToRGB24(ImageData data) { - return convertPalette(data, RGB24, 24); - } - - /** - * Converts image data to RGB format - * - * @param data source data - * @return result data - */ - public static ImageData convertPalette(ImageData data, PaletteData newPalette, int newDepth) { - if (paletteDataEquals(data.palette, newPalette)) - return data; - ImageData result = new ImageData(data.width, data.height, newDepth, newPalette); - boolean hasAlpha = data.alphaData != null; - int width = data.width; - int height = data.height; - // Very slow operation - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) { - // convert RGBs - RGB rgb = data.palette.getRGB(data.getPixel(x, y)); - result.setPixel(x, y, result.palette.getPixel(rgb)); - - // convert alpha - if (hasAlpha) { - int alpha = data.getAlpha(x, y); - result.setAlpha(x, y, alpha); - } - } - return result; - } - - /** - * Convert Device-independent image data format from one format to another. - * - * @param sourceImage source image, it must contain image data - * @param destImage destination image, it must be empty image - */ - // public static void convertImageData(ImageData sourceImage, ImageData - // destImage) { - // int swid = sourceImage.width; - // int shei = sourceImage.height; - // int dwid = destImage.width; - // int dhei = destImage.height; - // - // // resize - // if (swid!=dwid || shei!=dhei) - // sourceImage = sourceImage.scaledTo(dwid, dhei); - // - // // Convert palette - // PaletteData spal = sourceImage.palette; - // PaletteData dpal = destImage.palette; - // } - public static boolean paletteDataEquals(PaletteData p1, PaletteData p2) { - if (p1.isDirect != p2.isDirect) - return false; - if (!p1.isDirect) { - RGB rgb1[] = p1.colors; - RGB rgb2[] = p2.colors; - if (rgb1.length != rgb2.length) - return false; - for (int i = 0; i < rgb1.length; i++) - if (rgb1[i].blue != rgb2[i].blue || rgb1[i].green != rgb2[i].green || rgb1[i].red != rgb2[i].red) - return false; - return true; - } - - if (p1.blueMask != p2.blueMask) - return false; - if (p1.blueShift != p2.blueShift) - return false; - if (p1.greenMask != p2.greenShift) - return false; - if (p1.greenMask != p2.greenMask) - return false; - if (p1.redMask != p2.redMask) - return false; - if (p1.redShift != p2.redShift) - return false; - - return true; - } - - // ks. org.eclipse.gmf.runtime.draw2d.ui.render.image.ImageConverter - // Sama toiminnallisuus, mutta GMF riippuvuus - public static BufferedImage convertToAWT(ImageData data) { - ColorModel colorModel = null; - PaletteData palette = data.palette; - if (palette.isDirect) { - // has alpha and is 24bit (others are not supported) - if (data.alphaData != null && data.depth==24) { - colorModel = new DirectColorModel(data.depth+8, palette.redMask, palette.greenMask, palette.blueMask, 0xff000000); - BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null); - WritableRaster raster = bufferedImage.getRaster(); - int[] pixelArray = new int[4]; - for (int y = 0; y < data.height; y++) { - for (int x = 0; x < data.width; x++) { - int pixel = data.getPixel(x, y); - RGB rgb = palette.getRGB(pixel); - pixelArray[0] = rgb.red; - pixelArray[1] = rgb.green; - pixelArray[2] = rgb.blue; - pixelArray[3] = data.getAlpha(x, y); - raster.setPixels(x, y, 1, 1, pixelArray); - } - } - return bufferedImage; - } else { - // FIXME: this does not work with 16bit images (colors are wrong) - colorModel = new DirectColorModel(data.depth, palette.redMask, palette.greenMask, palette.blueMask); - BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null); - WritableRaster raster = bufferedImage.getRaster(); - int[] pixelArray = new int[3]; - for (int y = 0; y < data.height; y++) { - for (int x = 0; x < data.width; x++) { - int pixel = data.getPixel(x, y); - RGB rgb = palette.getRGB(pixel); - pixelArray[0] = rgb.red; - pixelArray[1] = rgb.green; - pixelArray[2] = rgb.blue; - raster.setPixels(x, y, 1, 1, pixelArray); - } - } - return bufferedImage; - } - } else { - RGB[] rgbs = palette.getRGBs(); - byte[] red = new byte[rgbs.length]; - byte[] green = new byte[rgbs.length]; - byte[] blue = new byte[rgbs.length]; - for (int i = 0; i < rgbs.length; i++) { - RGB rgb = rgbs[i]; - red[i] = (byte) rgb.red; - green[i] = (byte) rgb.green; - blue[i] = (byte) rgb.blue; - } - if (data.transparentPixel != -1) { - colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue, data.transparentPixel); - } else { - colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue); - } - BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null); - WritableRaster raster = bufferedImage.getRaster(); - int[] pixelArray = new int[1]; - for (int y = 0; y < data.height; y++) { - for (int x = 0; x < data.width; x++) { - int pixel = data.getPixel(x, y); - pixelArray[0] = pixel; - raster.setPixel(x, y, pixelArray); - } - } - return bufferedImage; - } - } - - public static ImageData convertToSWT(BufferedImage bufferedImage) { - if (bufferedImage.getColorModel() instanceof DirectColorModel) { - DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel(); - PaletteData palette = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(), colorModel.getBlueMask()); - ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette); - WritableRaster raster = bufferedImage.getRaster(); - int[] pixelArray = { 0, 0, 0, 255 }; - for (int y = 0; y < data.height; y++) { - for (int x = 0; x < data.width; x++) { - raster.getPixel(x, y, pixelArray); - int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2])); - data.setPixel(x, y, pixel); - data.setAlpha(x, y, pixelArray[3]); - } - } - return data; - } else if (bufferedImage.getColorModel() instanceof IndexColorModel) { - IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel(); - int size = colorModel.getMapSize(); - byte[] reds = new byte[size]; - byte[] greens = new byte[size]; - byte[] blues = new byte[size]; - colorModel.getReds(reds); - colorModel.getGreens(greens); - colorModel.getBlues(blues); - RGB[] rgbs = new RGB[size]; - for (int i = 0; i < rgbs.length; i++) { - rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF); - } - PaletteData palette = new PaletteData(rgbs); - ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette); - data.transparentPixel = colorModel.getTransparentPixel(); - WritableRaster raster = bufferedImage.getRaster(); - int[] pixelArray = new int[1]; - for (int y = 0; y < data.height; y++) { - for (int x = 0; x < data.width; x++) { - raster.getPixel(x, y, pixelArray); - data.setPixel(x, y, pixelArray[0]); - } - } - return data; - } else if (bufferedImage.getColorModel() instanceof ComponentColorModel) { - // works with BufferedImage.TYPE_3BYTE_BGR - ComponentColorModel colorModel = (ComponentColorModel)bufferedImage.getColorModel(); - PaletteData palette = new PaletteData(0xFF0000, 0x00FF00, 0x0000FF); - ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette); - WritableRaster raster = bufferedImage.getRaster(); - int[] pixelArray = { 0, 0, 0, 255 }; - for (int y = 0; y < data.height; y++) { - for (int x = 0; x < data.width; x++) { - raster.getPixel(x, y, pixelArray); - int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2])); - data.setPixel(x, y, pixel); - data.setAlpha(x, y, pixelArray[3]); - } - } - return data; - } - return null; - } - - /** - * Creates ImageData from RGBA byte array - * - * @param width width of the image - * @param height height of the image - * @param data data of the image - * @return ImageData - */ - public static ImageData _getImageDataFromRGBA(int width, int height, byte[] data) { - // these seem to do nothing, r and b channels are flipped anyways - int redMask = 0x0000ff00; - int greenMask = 0x00ff0000; - int blueMask = 0xff000000; - PaletteData paletteData = new PaletteData(redMask, greenMask, blueMask); - // flipping r and b channels - int maxByte = width * height * 4; - byte t; - for (int i = 0; i < maxByte; i += 4) { - t = data[i]; - data[i] = data[i + 2]; - data[i + 2] = t; - } - ImageData imageData = new ImageData(width, height, 32, paletteData, 4, data); - // TODO add alpha channel - // imageData.alphaData = xyz - return imageData; - } - - - /** - * Converts ImageData to RGB(A) ByteBuffer - * @param imageData - * @param buffer - */ - public static void convertToRGBA(ImageData imageData, ByteBuffer buffer) { - int width = imageData.width; - int height = imageData.height; - if (!imageData.palette.isDirect || imageData.depth != 24) { - ImageUtils.convertPaletteToRGB24(imageData); - } - boolean hasAlpha = false; - if (imageData.alphaData != null) { - hasAlpha = true; - } - int index; - RGB rgb; - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - index = j*width + i; - rgb = imageData.palette.getRGB(imageData.getPixel(i, j)); - buffer.put((byte)rgb.red); - buffer.put((byte)rgb.green); - buffer.put((byte)rgb.blue); - if (hasAlpha) { - buffer.put(imageData.alphaData[index]); - } - } - } - - } - -} +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +/* + * Created on 12.11.2005 + * @author Toni Kalajainen + */ +package org.simantics.utils.ui.gfx; + +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.IndexColorModel; +import java.awt.image.WritableRaster; +import java.nio.ByteBuffer; + +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.RGB; + +public class ImageUtils { + + public final static PaletteData RGB24 = new PaletteData(0xff, 0xff00, 0xff0000); + + public static ImageData convertPaletteToRGB24(ImageData data) { + return convertPalette(data, RGB24, 24); + } + + /** + * Converts image data to RGB format + * + * @param data source data + * @return result data + */ + public static ImageData convertPalette(ImageData data, PaletteData newPalette, int newDepth) { + if (paletteDataEquals(data.palette, newPalette)) + return data; + ImageData result = new ImageData(data.width, data.height, newDepth, newPalette); + boolean hasAlpha = data.alphaData != null; + int width = data.width; + int height = data.height; + // Very slow operation + for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) { + // convert RGBs + RGB rgb = data.palette.getRGB(data.getPixel(x, y)); + result.setPixel(x, y, result.palette.getPixel(rgb)); + + // convert alpha + if (hasAlpha) { + int alpha = data.getAlpha(x, y); + result.setAlpha(x, y, alpha); + } + } + return result; + } + + /** + * Convert Device-independent image data format from one format to another. + * + * @param sourceImage source image, it must contain image data + * @param destImage destination image, it must be empty image + */ + // public static void convertImageData(ImageData sourceImage, ImageData + // destImage) { + // int swid = sourceImage.width; + // int shei = sourceImage.height; + // int dwid = destImage.width; + // int dhei = destImage.height; + // + // // resize + // if (swid!=dwid || shei!=dhei) + // sourceImage = sourceImage.scaledTo(dwid, dhei); + // + // // Convert palette + // PaletteData spal = sourceImage.palette; + // PaletteData dpal = destImage.palette; + // } + public static boolean paletteDataEquals(PaletteData p1, PaletteData p2) { + if (p1.isDirect != p2.isDirect) + return false; + if (!p1.isDirect) { + RGB rgb1[] = p1.colors; + RGB rgb2[] = p2.colors; + if (rgb1.length != rgb2.length) + return false; + for (int i = 0; i < rgb1.length; i++) + if (rgb1[i].blue != rgb2[i].blue || rgb1[i].green != rgb2[i].green || rgb1[i].red != rgb2[i].red) + return false; + return true; + } + + if (p1.blueMask != p2.blueMask) + return false; + if (p1.blueShift != p2.blueShift) + return false; + if (p1.greenMask != p2.greenShift) + return false; + if (p1.greenMask != p2.greenMask) + return false; + if (p1.redMask != p2.redMask) + return false; + if (p1.redShift != p2.redShift) + return false; + + return true; + } + + // ks. org.eclipse.gmf.runtime.draw2d.ui.render.image.ImageConverter + // Sama toiminnallisuus, mutta GMF riippuvuus + public static BufferedImage convertToAWT(ImageData data) { + ColorModel colorModel = null; + PaletteData palette = data.palette; + if (palette.isDirect) { + // has alpha and is 24bit (others are not supported) + if (data.alphaData != null && data.depth==24) { + colorModel = new DirectColorModel(data.depth+8, palette.redMask, palette.greenMask, palette.blueMask, 0xff000000); + BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null); + WritableRaster raster = bufferedImage.getRaster(); + int[] pixelArray = new int[4]; + for (int y = 0; y < data.height; y++) { + for (int x = 0; x < data.width; x++) { + int pixel = data.getPixel(x, y); + RGB rgb = palette.getRGB(pixel); + pixelArray[0] = rgb.red; + pixelArray[1] = rgb.green; + pixelArray[2] = rgb.blue; + pixelArray[3] = data.getAlpha(x, y); + raster.setPixels(x, y, 1, 1, pixelArray); + } + } + return bufferedImage; + } else { + // FIXME: this does not work with 16bit images (colors are wrong) + colorModel = new DirectColorModel(data.depth, palette.redMask, palette.greenMask, palette.blueMask); + BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null); + WritableRaster raster = bufferedImage.getRaster(); + int[] pixelArray = new int[3]; + for (int y = 0; y < data.height; y++) { + for (int x = 0; x < data.width; x++) { + int pixel = data.getPixel(x, y); + RGB rgb = palette.getRGB(pixel); + pixelArray[0] = rgb.red; + pixelArray[1] = rgb.green; + pixelArray[2] = rgb.blue; + raster.setPixels(x, y, 1, 1, pixelArray); + } + } + return bufferedImage; + } + } else { + RGB[] rgbs = palette.getRGBs(); + byte[] red = new byte[rgbs.length]; + byte[] green = new byte[rgbs.length]; + byte[] blue = new byte[rgbs.length]; + for (int i = 0; i < rgbs.length; i++) { + RGB rgb = rgbs[i]; + red[i] = (byte) rgb.red; + green[i] = (byte) rgb.green; + blue[i] = (byte) rgb.blue; + } + if (data.transparentPixel != -1) { + colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue, data.transparentPixel); + } else { + colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue); + } + BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null); + WritableRaster raster = bufferedImage.getRaster(); + int[] pixelArray = new int[1]; + for (int y = 0; y < data.height; y++) { + for (int x = 0; x < data.width; x++) { + int pixel = data.getPixel(x, y); + pixelArray[0] = pixel; + raster.setPixel(x, y, pixelArray); + } + } + return bufferedImage; + } + } + + public static ImageData convertToSWT(BufferedImage bufferedImage) { + if (bufferedImage.getColorModel() instanceof DirectColorModel) { + DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel(); + PaletteData palette = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(), colorModel.getBlueMask()); + ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette); + WritableRaster raster = bufferedImage.getRaster(); + int[] pixelArray = { 0, 0, 0, 255 }; + for (int y = 0; y < data.height; y++) { + for (int x = 0; x < data.width; x++) { + raster.getPixel(x, y, pixelArray); + int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2])); + data.setPixel(x, y, pixel); + data.setAlpha(x, y, pixelArray[3]); + } + } + return data; + } else if (bufferedImage.getColorModel() instanceof IndexColorModel) { + IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel(); + int size = colorModel.getMapSize(); + byte[] reds = new byte[size]; + byte[] greens = new byte[size]; + byte[] blues = new byte[size]; + colorModel.getReds(reds); + colorModel.getGreens(greens); + colorModel.getBlues(blues); + RGB[] rgbs = new RGB[size]; + for (int i = 0; i < rgbs.length; i++) { + rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF); + } + PaletteData palette = new PaletteData(rgbs); + ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette); + data.transparentPixel = colorModel.getTransparentPixel(); + WritableRaster raster = bufferedImage.getRaster(); + int[] pixelArray = new int[1]; + for (int y = 0; y < data.height; y++) { + for (int x = 0; x < data.width; x++) { + raster.getPixel(x, y, pixelArray); + data.setPixel(x, y, pixelArray[0]); + } + } + return data; + } else if (bufferedImage.getColorModel() instanceof ComponentColorModel) { + // works with BufferedImage.TYPE_3BYTE_BGR + ComponentColorModel colorModel = (ComponentColorModel)bufferedImage.getColorModel(); + PaletteData palette = new PaletteData(0xFF0000, 0x00FF00, 0x0000FF); + ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette); + WritableRaster raster = bufferedImage.getRaster(); + int[] pixelArray = { 0, 0, 0, 255 }; + for (int y = 0; y < data.height; y++) { + for (int x = 0; x < data.width; x++) { + raster.getPixel(x, y, pixelArray); + int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2])); + data.setPixel(x, y, pixel); + data.setAlpha(x, y, pixelArray[3]); + } + } + return data; + } + return null; + } + + /** + * Creates ImageData from RGBA byte array + * + * @param width width of the image + * @param height height of the image + * @param data data of the image + * @return ImageData + */ + public static ImageData _getImageDataFromRGBA(int width, int height, byte[] data) { + // these seem to do nothing, r and b channels are flipped anyways + int redMask = 0x0000ff00; + int greenMask = 0x00ff0000; + int blueMask = 0xff000000; + PaletteData paletteData = new PaletteData(redMask, greenMask, blueMask); + // flipping r and b channels + int maxByte = width * height * 4; + byte t; + for (int i = 0; i < maxByte; i += 4) { + t = data[i]; + data[i] = data[i + 2]; + data[i + 2] = t; + } + ImageData imageData = new ImageData(width, height, 32, paletteData, 4, data); + // TODO add alpha channel + // imageData.alphaData = xyz + return imageData; + } + + + /** + * Converts ImageData to RGB(A) ByteBuffer + * @param imageData + * @param buffer + */ + public static void convertToRGBA(ImageData imageData, ByteBuffer buffer) { + int width = imageData.width; + int height = imageData.height; + if (!imageData.palette.isDirect || imageData.depth != 24) { + ImageUtils.convertPaletteToRGB24(imageData); + } + boolean hasAlpha = false; + if (imageData.alphaData != null) { + hasAlpha = true; + } + int index; + RGB rgb; + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + index = j*width + i; + rgb = imageData.palette.getRGB(imageData.getPixel(i, j)); + buffer.put((byte)rgb.red); + buffer.put((byte)rgb.green); + buffer.put((byte)rgb.blue); + if (hasAlpha) { + buffer.put(imageData.alphaData[index]); + } + } + } + + } + +}