title: Writing ico files java
body: <p>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 <a href="http://en.wikipedia.org/wiki/ICO_%28file_format%29" rel="nofollow noreferrer">http://en.wikipedia.org/wiki/ICO_%28file_format%29</a></p>
  
  <pre><code>    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();
  }
  </code></pre>
  
  <p>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.</p>
  
  <p>On my desktop the image looks like this
  <img src="https://i.stack.imgur.com/MiyEH.png" alt="enter image description here"></p>
  
  <p>When i try to open it in Windows Photo Gallery it displays this error</p>
  
  <p><img src="https://i.stack.imgur.com/bWueW.png" alt="enter image description here"></p>
  
  <p>After having failed with the png attempt i tried it with bitmap image instead, here is my new code</p>
  
  <pre><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);
      }
  }
  </code></pre>
  
  <p>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.
  <img src="https://i.stack.imgur.com/xeiGf.png" alt="enter image description here"></p>