Recently i have become interested in creating .ico file or windows icon files in java. This is the current code i use. I have gotten the file format specs from here http://en.wikipedia.org/wiki/ICO_%28file_format%29
BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
Graphics g = img.getGraphics();
g.setColor(Color.GREEN);
g.fillRect(0, 0, 16, 16);
byte[] imgBytes = getImgBytes(img);
int fileSize = imgBytes.length + 22;
ByteBuffer bytes = ByteBuffer.allocate(fileSize);
bytes.order(ByteOrder.LITTLE_ENDIAN);
bytes.putShort((short) 0);//Reserved must be 0
bytes.putShort((short) 1);//Image type
bytes.putShort((short) 1);//Number of image in file
bytes.put((byte) img.getWidth());//image width
bytes.put((byte) img.getHeight());//image height
bytes.put((byte) 0);//number of colors in color palette
bytes.put((byte) 0);//reserved must be 0
bytes.putShort((short) 0);//color planes
bytes.putShort((short) 0);//bits per pixel
bytes.putInt(imgBytes.length);//image size
bytes.putInt(22);//image offset
bytes.put(imgBytes);
byte[] result = bytes.array();
FileOutputStream fos = new FileOutputStream("C://Users//Owner//Desktop//picture.ico");
fos.write(result);
fos.close();
fos.flush();
private static byte[] getImgBytes(BufferedImage img) throws IOException
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(img, "png", bos);
return bos.toByteArray();
}
The problem is that windows doesn't seem to be able to open the image, giving an error when i try to open the image using Windows Photo Gallery. However when i try to open the image using gimp the image opens fine. What am i doing wrong. I feel like i am messing up something in the file header. Edit: Even stranger on the desktop the picture looks right, just not when i try to open it.
On my desktop the image looks like this
When i try to open it in Windows Photo Gallery it displays this error
After having failed with the png attempt i tried it with bitmap image instead, here is my new code
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import javax.imageio.ImageIO;
public class IconWriter
{
public static void main(String[] args) throws HeadlessException, AWTException, IOException
{
BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
Graphics g = img.getGraphics();
g.setColor(Color.GREEN);
g.fillRect(0, 0, 16, 16);
byte[] imgBytes = getImgBytes(img);
int fileSize = imgBytes.length + 22;
ByteBuffer bytes = ByteBuffer.allocate(fileSize);
bytes.order(ByteOrder.LITTLE_ENDIAN);
bytes.putShort((short) 0);//Reserved must be 0
bytes.putShort((short) 1);//Image type
bytes.putShort((short) 1);//Number of images in file
bytes.put((byte) img.getWidth());//image width
bytes.put((byte) img.getHeight());//image height
bytes.put((byte) 0);//number of colors in color palette
bytes.put((byte) 0);//reserved must be 0
bytes.putShort((short) 0);//color planes
bytes.putShort((short) 0);//bits per pixel
bytes.putInt(imgBytes.length);//image size
bytes.putInt(22);//image offset
bytes.put(imgBytes);
byte[] result = bytes.array();
FileOutputStream fos = new FileOutputStream("C://Users//Owner//Desktop//hi.ico");
fos.write(result);
fos.close();
fos.flush();
}
private static byte[] getImgBytes(BufferedImage img) throws IOException
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(img, "bmp", bos);
byte[] bytes = bos.toByteArray();
return Arrays.copyOfRange(bytes, 14, bytes.length);
}
}
now when i try to open my image in photo gallery the image looks like this i have no idea why it isn't working now and especially why the weird lines are appearing, although i suspect it has to with the color planes attribute in the ico image header.