package nl.fontys.sofa.limo.domain.component; import com.google.gson.annotations.Expose; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.stream.MemoryCacheImageInputStream; /** * An icon used by hubs and legs. * * @author Dominik Kaisers {@literal <d.kaisers@student.fontys.nl>} */ public class Icon implements Serializable { @Expose private byte[] data; @Expose private String imageType; @Expose private transient BufferedImage image; @Expose private static final transient int ICON_WIDTH = 64, ICON_HEIGHT = 64; /* CONSTRUCTORS */ public Icon() { imageType = ""; data = new byte[]{}; } public Icon(byte[] data, String imageType) { this.data = data; this.imageType = imageType; this.buildImageFromData(); } public Icon(Image image, String imageType) { this.setImage(image, imageType); this.resizeIcon(); } /* GETTERS */ public byte[] getData() { return this.data; } public BufferedImage getImage() { if (this.image == null) { this.buildImageFromData(); } return this.image; } public String getImageType() { return this.imageType; } /* SETTERS */ public void setImageType(String imageType) { this.imageType = imageType; } /** * Set data (byte[]) for image, given the imagetype (how data should be * interpreted) * * @param data Byte[] w/ data of the image where data has to be set for * @param imageType Type of the image */ public void setData(byte[] data, String imageType) { this.data = data; this.imageType = imageType; this.buildImageFromData(); } /** * Set icon by image. * * @param image New icon image. * @param imageType Type of the image. */ public final void setImage(Image image, String imageType) { this.imageType = imageType; if (!(image instanceof BufferedImage)) { this.image = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_4BYTE_ABGR); Graphics2D bGr = this.image.createGraphics(); bGr.drawImage(image, 0, 0, null); bGr.dispose(); } else { this.image = (BufferedImage) image; } resizeIcon(); } /** * Set icon by path. Old one will not change upon error. * * @param imagePath Path to new icon. */ public void setImage(String imagePath) { byte[] dataBuffer = this.data; String imageTypeBuffer = imageType; try { File imageFile = new File(imagePath); if (imageFile.exists()) { this.imageType = imagePath.split("\\.")[imagePath.split("\\.").length - 1]; this.image = ImageIO.read(imageFile); resizeIcon(); } } catch (IOException ex) { System.out.println("Image: '" + imagePath + "' could not get loaded"); this.data = dataBuffer; this.imageType = imageTypeBuffer; buildImageFromData(); } } /** * Set data var (ByteArray) from previously set image */ private void setByteArrayFromImage() { if (image != null) { try { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(image, imageType, outputStream); data = outputStream.toByteArray(); } catch (IOException ex) { System.out.println(ex.getMessage()); } } } /** * Create/set image from previously set data (byteArray) */ private void buildImageFromData() { try { Iterator<ImageReader> imageReaderIterator = ImageIO.getImageReadersByFormatName(getImageType()); while (imageReaderIterator.hasNext()) { ImageReader imageReader = imageReaderIterator.next(); imageReader.setInput(new MemoryCacheImageInputStream(new ByteArrayInputStream(getData()))); this.image = imageReader.read(imageReader.getMinIndex()); } resizeIcon(); } catch (IOException ex) { Logger.getLogger(Icon.class.getName()).log(Level.SEVERE, null, ex); } } /** * Resize method to resize to 64x64 */ private void resizeIcon() { if (image != null) { if (image.getWidth() != ICON_WIDTH || image.getHeight() != ICON_HEIGHT) { BufferedImage resizedImage = new BufferedImage(ICON_WIDTH, ICON_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR); Graphics graphics = resizedImage.createGraphics(); graphics.drawImage(image, 0, 0, ICON_WIDTH, ICON_HEIGHT, null); this.setImage(resizedImage, getImageType()); graphics.dispose(); } setByteArrayFromImage(); } } }