/** * Create GLImage from image file bytes (the contents of a jpg, gif or png file). Flip Y axis. * * @param pixels * @param w * @param h */ public GLImage(byte[] bytes) { BufferedImage img = makeBufferedImage(bytes); if (makeGLImage(img, true, false)) { GLApp.msg("GLImage(byte[]): loaded image from bytes[" + bytes.length + "]"); } else { GLApp.err("GLImage(byte[]): could not create Image from bytes[" + bytes.length + "]"); } }
/** * Create GLImage from image file bytes (the contents of a jpg, gif or png file). * * @param pixels * @param w * @param h */ public GLImage(byte[] bytes, boolean flipYaxis, boolean convertPow2) { BufferedImage img = makeBufferedImage(bytes); if (makeGLImage(img, flipYaxis, convertPow2)) { GLApp.msg("GLImage(byte[],bool,bool): loaded image from bytes[" + bytes.length + "]"); } else { GLApp.err( "GLImage(byte[],bool,bool): could not create Image from bytes[" + bytes.length + "]"); } }
/** * Load a BufferedImage from the given image file name. File can be in the local filesytem, in the * applet folder, or in a jar. */ public BufferedImage loadJavaImage(String imgName) { BufferedImage tmpi = null; try { tmpi = ImageIO.read(GLApp.getInputStream(imgName)); } catch (Exception e) { GLApp.err("GLImage.loadJavaImage() exception: FAILED TO LOAD IMAGE " + e); } return tmpi; }
/** * Scale the given BufferedImage to width and height that are powers of two. Return the new scaled * BufferedImage. */ public static BufferedImage convertToPowerOf2(BufferedImage bsrc) { // find powers of 2 equal to or greater than current dimensions int newW = GLApp.getPowerOfTwoBiggerThan(bsrc.getWidth()); int newH = GLApp.getPowerOfTwoBiggerThan(bsrc.getHeight()); if (newW == bsrc.getWidth() && newH == bsrc.getHeight()) { return bsrc; // no change necessary } else { AffineTransform at = AffineTransform.getScaleInstance( (double) newW / bsrc.getWidth(), (double) newH / bsrc.getHeight()); BufferedImage bdest = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB); Graphics2D g = bdest.createGraphics(); g.drawRenderedImage(bsrc, at); return bdest; } }
/** Scale this GLImage so width and height are powers of 2. Recreate pixels and pixelBuffer. */ public void convertToPowerOf2() { // make BufferedImage from original pixels BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); image.setRGB(0, 0, w, h, pixels, 0, w); // scale into new image BufferedImage scaledImg = convertToPowerOf2(image); // resample pixel data w = scaledImg.getWidth(null); h = scaledImg.getHeight(null); pixels = getImagePixels(scaledImg); // pixels in default Java ARGB format pixelBuffer = convertImagePixelsRGBA(pixels, w, h, false); // convert to bytes in RGBA format textureW = GLApp.getPowerOfTwoBiggerThan(w); // the texture size big enough to hold this image textureH = GLApp.getPowerOfTwoBiggerThan(h); // the texture size big enough to hold this image }
/** * Make a BufferedImage from the contents of an image file. * * @param imageFileContents byte array containing the guts of a JPG, GIF, or PNG */ public BufferedImage makeBufferedImage(byte[] imageFileContents) { BufferedImage bi = null; try { InputStream in = new ByteArrayInputStream(imageFileContents); bi = javax.imageio.ImageIO.read(in); } catch (IOException ioe) { GLApp.err("GLImage.makeBufferedImage(): " + ioe); } return bi; }
/** * Copy ARGB pixels to a ByteBuffer without changing the ARGB byte order. If used to make a * texture, the pixel format is GL12.GL_BGRA. With this format we can leave pixels in ARGB order * (faster), but unfortunately I had problems building mipmaps in BGRA format * (GLU.gluBuild2DMipmaps() did not recognize GL_UNSIGNED_INT_8_8_8_8 and * GL_UNSIGNED_INT_8_8_8_8_REV types so screwed up the BGRA/ARGB byte order on Mac). * * @return ByteBuffer */ public static ByteBuffer convertImagePixelsARGB( int[] jpixels, int imgw, int imgh, boolean flipVertically) { // flip Y axis if (flipVertically) { jpixels = flipPixels(jpixels, imgw, imgh); // flip Y axis } // put int pixels into Byte Buffer ByteBuffer bb = GLApp.allocBytes(jpixels.length * 4); // 4 bytes per pixel bb.asIntBuffer().put(jpixels); return bb; }
/** * Load an image from the given filename. If convertToPow2 is true then convert the image to a * power of two. Store pixels as ARGB ints in the pixels array and as RGBA bytes in the * pixelBuffer ByteBuffer. Hold onto image width/height. * * @param imgName */ public boolean makeGLImage(BufferedImage tmpi, boolean flipYaxis, boolean convertToPow2) { if (tmpi != null) { if (flipYaxis) { tmpi = flipY(tmpi); } if (convertToPow2) { tmpi = convertToPowerOf2(tmpi); } w = tmpi.getWidth(null); h = tmpi.getHeight(null); pixels = getImagePixels(tmpi); // pixels in default Java ARGB format pixelBuffer = convertImagePixelsRGBA(pixels, w, h, false); // convert to bytes in RGBA format textureW = GLApp.getPowerOfTwoBiggerThan(w); // the texture size big enough to hold this image textureH = GLApp.getPowerOfTwoBiggerThan(h); // the texture size big enough to hold this image // GLApp.msg("GLImage: loaded " + imgName + ", width=" + w + " height=" + h); return true; } else { // GLApp.err("GLImage: FAILED TO LOAD IMAGE " + imgName); pixels = null; pixelBuffer = null; h = w = 0; return false; } }
/** * Return the Image pixels in default Java int ARGB format. * * @return */ public static int[] getImagePixels(Image image) { int[] pixelsARGB = null; if (image != null) { int imgw = image.getWidth(null); int imgh = image.getHeight(null); pixelsARGB = new int[imgw * imgh]; PixelGrabber pg = new PixelGrabber(image, 0, 0, imgw, imgh, pixelsARGB, 0, imgw); try { pg.grabPixels(); } catch (Exception e) { GLApp.err("Pixel Grabbing interrupted!"); return null; } } return pixelsARGB; }
/** * Save an array of ARGB pixels to a PNG file. If flipY is true, flip the pixels on the Y axis * before saving. */ public static void savePixelsToPNG( int[] pixels, int width, int height, String imageFilename, boolean flipY) { if (pixels != null && imageFilename != null) { if (flipY) { // flip the pixels vertically (opengl has 0,0 at lower left, java is upper left) pixels = GLImage.flipPixels(pixels, width, height); } try { // Create a BufferedImage with the RGB pixels then save as PNG BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); image.setRGB(0, 0, width, height, pixels, 0, width); javax.imageio.ImageIO.write(image, "png", new File(imageFilename)); } catch (Exception e) { GLApp.err("GLImage.savePixelsToPNG(" + imageFilename + "): exception " + e); } } }
/** * Load pixels from an image file. Convert to RGBA format. * * @param imgName */ public GLImage(String imgName, boolean flipYaxis, boolean convertPow2) { BufferedImage img = loadJavaImage(imgName); if (makeGLImage(img, flipYaxis, convertPow2)) { GLApp.msg("GLImage(String,bool,bool): loaded " + imgName + ", width=" + w + " height=" + h); } }
/** * Load pixels from an image file. Flip Y axis. Convert to RGBA format. * * @param imgName */ public GLImage(String imgName) { BufferedImage img = loadJavaImage(imgName); if (makeGLImage(img, true, false)) { GLApp.msg("GLImage(String): loaded " + imgName + ", width=" + w + " height=" + h); } }