package org.jzy3d.plot3d.rendering.image;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.PixelGrabber;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class GLImage {
	public static ByteBuffer getImageAsGlByteBuffer(Image image, int width, int height){
		int[] px  = GLImage.getImagePixels(image, width, height);
		return GLImage.convertImagePixels(px, width, height, true);
	}	
	
	// FOLLOWING CONVERTER FUNCTIONS HAVE BEEN PICKED FROM:
	// http://www.potatoland.com/code/gl/GLImage.java

	/** Return the image pixels in default Java int ARGB format. */
	public static int[] getImagePixels(Image image, int width, int height) {
		int[] pixels = null;

		if (image != null) {
			pixels = new int[width * height];
			PixelGrabber pg = new PixelGrabber(image, 0, 0, width, height,
					pixels, 0, width);
			try {
				pg.grabPixels();
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		return pixels;
	}

	/**
	 * Convert ARGB pixels to a ByteBuffer containing RGBA pixels.
* Can be drawn in ORTHO mode using:
* GL2.glDrawPixels(imgW, imgH, GL2.GL_RGBA, GL2.GL_UNSIGNED_BYTE, byteBuffer);
* If flipVertically is true, pixels will be flipped vertically for OpenGL * coord system. * * @param imgFilename * @return ByteBuffer */ public static ByteBuffer convertImagePixels(int[] jpixels, int imgw, int imgh, boolean flipVertically) { byte[] bytes; // will hold pixels as RGBA bytes if (flipVertically) { jpixels = flipPixels(jpixels, imgw, imgh); // flip Y axis } bytes = convertARGBtoRGBA(jpixels); return allocBytes(bytes); // convert to ByteBuffer and return } /** * Flip an array of pixels vertically * * @param imgPixels * @param imgw * @param imgh * @return int[] */ public static int[] flipPixels(int[] imgPixels, int imgw, int imgh) { int[] flippedPixels = null; if (imgPixels != null) { flippedPixels = new int[imgw * imgh]; for (int y = 0; y < imgh; y++) { for (int x = 0; x < imgw; x++) { flippedPixels[((imgh - y - 1) * imgw) + x] = imgPixels[(y * imgw) + x]; } } } return flippedPixels; } /** * Convert pixels from java default ARGB int format to byte array in RGBA * format. * * @param jpixels * @return */ public static byte[] convertARGBtoRGBA(int[] jpixels) { byte[] bytes = new byte[jpixels.length * 4]; // will hold pixels as RGBA // bytes int p, r, g, b, a; int j = 0; for (int i = 0; i < jpixels.length; i++) { // int outPixel = 0x00000000; // AARRGGBB p = jpixels[i]; a = (p >> 24) & 0xFF; // get pixel bytes in ARGB order r = (p >> 16) & 0xFF; g = (p >> 8) & 0xFF; b = (p >> 0) & 0xFF; bytes[j + 0] = (byte) r; // fill in bytes in RGBA order bytes[j + 1] = (byte) g; bytes[j + 2] = (byte) b; bytes[j + 3] = (byte) a; j += 4; } return bytes; } public static byte[] getRGBABytes(int[] jpixels) { byte[] bytes = new byte[jpixels.length * 4]; // will hold pixels as RGBA // bytes int p, r, g, b, a; int j = 0; for (int i = 0; i < jpixels.length; i++) { // int outPixel = 0x00000000; // AARRGGBB p = jpixels[i]; r = (p >> 24) & 0xFF; // get pixel bytes in RGBA order g = (p >> 16) & 0xFF; b = (p >> 8) & 0xFF; a = (p >> 0) & 0xFF; bytes[j + 0] = (byte) r; // fill in bytes in RGBA order bytes[j + 1] = (byte) g; bytes[j + 2] = (byte) b; bytes[j + 3] = (byte) a; j += 4; } return bytes; } /** * Same function as in GLApp.java. Allocates a ByteBuffer to hold the given * array of bytes. * * @param bytearray * @return ByteBuffer containing the contents of the byte array */ public static ByteBuffer allocBytes(byte[] bytearray) { ByteBuffer bb = ByteBuffer.allocateDirect(bytearray.length * SIZE_BYTE) .order(ByteOrder.nativeOrder()); bb.put(bytearray).flip(); return bb; } protected static final int SIZE_BYTE = 1; public static ByteBuffer toByteBuffer(Image img, int imgWidth, int imgHeight) { // Create a raster with correct size, // and a colorModel and finally a bufImg. // WritableRaster raster = Raster.createInterleavedRaster( DataBuffer.TYPE_BYTE, imgWidth, imgHeight, 4, null); ComponentColorModel colorModel = new ComponentColorModel(ColorSpace .getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 8 }, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE); BufferedImage bufImg = new BufferedImage(colorModel, // color model raster, false, // isRasterPremultiplied null); // properties // Filter img into bufImg and perform // Coordinate Transformations on the way. // Graphics2D g = bufImg.createGraphics(); AffineTransform gt = new AffineTransform(); gt.translate(0, imgHeight); gt.scale(1, -1d); g.transform(gt); g.drawImage(img, null, null); // Retrieve underlying byte array (imgBuf) // from bufImg. DataBufferByte imgBuf = (DataBufferByte) raster.getDataBuffer(); byte[] imgRGBA = imgBuf.getData(); ByteBuffer bb = ByteBuffer.allocateDirect(imgRGBA.length).order(ByteOrder.nativeOrder()); bb.put( imgRGBA ).flip(); return bb; } }

Ads help maintain this website.