/*******************************************************************************
* Copyright (C) 2013 JMaNGOS <http://jmangos.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package org.jmangos.tools.openGL;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
/*****************************************************************************
* A convenience class for loading icons from images.
*
* Icons loaded from this class are formatted to fit within the required
* dimension (16x16, 32x32, or
* 128x128). If the source image is larger than the target dimension, it is
* shrunk down to the
* minimum size that will fit. If it is smaller, then it is only scaled up if
* the new scale can be a
* per-pixel linear scale (i.e., x2, x3, x4, etc). In both cases, the image's
* width/height ratio is
* kept the same as the source image.
*
* @author Chris Molini
*****************************************************************************/
public class IconLoader {
/*************************************************************************
* Loads an icon in ByteBuffer form.
*
* @param loader
* A Loader pointing to the image.
*
* @return An array of ByteBuffers containing the pixel data for the icon in
* various sizes (as
* recommended by the OS).
*************************************************************************/
public static ByteBuffer[] load(final String fileName) {
BufferedImage image = null;
try {
image = ImageIO.read(new File(fileName));
} catch (final IOException e) {
e.printStackTrace();
}
ByteBuffer[] buffers = null;
final String OS = System.getProperty("os.name").toUpperCase();
if (OS.contains("WIN")) {
buffers = new ByteBuffer[2];
buffers[0] = loadInstance(image, 16);
buffers[1] = loadInstance(image, 32);
} else if (OS.contains("MAC")) {
buffers = new ByteBuffer[1];
buffers[0] = loadInstance(image, 128);
} else {
buffers = new ByteBuffer[1];
buffers[0] = loadInstance(image, 32);
}
return buffers;
}
/*************************************************************************
* Copies the supplied image into a square icon at the indicated size.
*
* @param image
* The image to place onto the icon.
* @param dimension
* The desired size of the icon.
*
* @return A ByteBuffer of pixel data at the indicated size.
*************************************************************************/
private static ByteBuffer loadInstance(final BufferedImage image, final int dimension) {
final BufferedImage scaledIcon =
new BufferedImage(dimension, dimension, BufferedImage.TYPE_INT_ARGB_PRE);
final Graphics2D g = scaledIcon.createGraphics();
final double ratio = getIconRatio(image, scaledIcon);
final double width = image.getWidth() * ratio;
final double height = image.getHeight() * ratio;
g.drawImage(image, (int) ((scaledIcon.getWidth() - width) / 2),
(int) ((scaledIcon.getHeight() - height) / 2), (int) (width), (int) (height), null);
g.dispose();
return convertToByteBuffer(scaledIcon);
}
/*************************************************************************
* Gets the width/height ratio of the icon. This is meant to simplify
* scaling the icon to a new
* dimension.
*
* @param src
* The base image that will be placed onto the icon.
* @param icon
* The icon that will have the image placed on it.
*
* @return The amount to scale the source image to fit it onto the icon
* appropriately.
*************************************************************************/
private static double getIconRatio(final BufferedImage src, final BufferedImage icon) {
double ratio = 1;
if (src.getWidth() > icon.getWidth()) {
ratio = (double) (icon.getWidth()) / src.getWidth();
} else {
ratio = icon.getWidth() / src.getWidth();
}
if (src.getHeight() > icon.getHeight()) {
final double r2 = (double) (icon.getHeight()) / src.getHeight();
if (r2 < ratio) {
ratio = r2;
}
} else {
final double r2 = icon.getHeight() / src.getHeight();
if (r2 < ratio) {
ratio = r2;
}
}
return ratio;
}
/*************************************************************************
* Converts a BufferedImage into a ByteBuffer of pixel data.
*
* @param image
* The image to convert.
*
* @return A ByteBuffer that contains the pixel data of the supplied image.
*************************************************************************/
public static ByteBuffer convertToByteBuffer(final BufferedImage image) {
final byte[] buffer = new byte[image.getWidth() * image.getHeight() * 4];
int counter = 0;
for (int i = 0; i < image.getHeight(); i++) {
for (int j = 0; j < image.getWidth(); j++) {
final int colorSpace = image.getRGB(j, i);
buffer[counter + 0] = (byte) ((colorSpace << 8) >> 24);
buffer[counter + 1] = (byte) ((colorSpace << 16) >> 24);
buffer[counter + 2] = (byte) ((colorSpace << 24) >> 24);
buffer[counter + 3] = (byte) (colorSpace >> 24);
counter += 4;
}
}
return ByteBuffer.wrap(buffer);
}
}