How to convert BMP image to 8-bit greyscale
<p>I have to make a program that reads a 24 bit BMP image(without ImageIO or any external library) and make it a 8 bit greyscale BMP image... I read that I must change the header of the image to make it a 8 bit, <a href="https://stackoverflow.com/questions/11086649/what-is-the-bmp-format-for-gray-scale-images">Source 1</a> and <a href="https://stackoverflow.com/questions/18744123/rgb-to-grayscale-bmp-image-in-java">Source 2</a>. So I read <a href="http://www.daubnet.com/en/file-format-bmp" rel="nofollow noreferrer">here</a> that the BitCount bytes are at 29 and 30 of the Header and try to change them... </p>

<p>First I read my file and generate the byte vector like this</p>

<pre><code>FileInputStream image= new FileInputStream(path);
byte[] bytesImage = new byte[image.available()];
image.read(bytesImage);
image.close();
</code></pre>

<p>Then I get the image header and copy it to a new vector</p>

<pre><code>int width = byteToInt(bytesImage[18], bytesImage[19], bytesImage[20], bytesImage[21]);
int height = byteToInt(bytesImage[22], bytesImage[23], bytesImage[24], bytesImage[25]);
int header = byteToInt(bytesImage[14], bytesImage[15], bytesImage[16], bytesImage[17]) + 14; // Add 14 for the header
vecGrey = Arrays.copyOf(bytesImage, bytesImage.length);
</code></pre>

<p>Then I change the header info bytes to make it an 8 bit BMP like this:</p>

<pre><code>byte[] values = intToByte(8);
vecGrey[28] = values[0];    // This is the index for the BitCount byte 1
vecGrey[29] = values[1];    // and this one is the index for the second one.
</code></pre>

<p>Okay now comes the problem, for some reason I can't write a file with the header in vecGrey if i try to write vecGrey with a diferent header as show here:</p>

<pre><code>FileOutputStream aGrey = new FileOutputStream(name+ "-gray.bmp");
aGrey.write(vecGrey);
aGrey.close();
// This is a method that displays the resulting image in a frame...
makeInterface(name + "-gray.bmp");
</code></pre>

<p>I know that I must change values in the vecGrey, but this should work showing incorrect output(probably a non greyscale image or not an image at all). But when I try to read the file that I generate in the makeInterface() method I get a </p>

<blockquote>
  <p>javax.imageio.iioexception unable to read the image header</p>
</blockquote>

<p>So I asume that the program is unable to read correctly the header, but I don't know why! If I change the BitCount value to 16 it still works, but to 1, 4 or 8 it doesn't work with the same error... I didn't upload my hole code because it's in spanish, but if needed I can translate it and edit here.</p>

<p>Thanks! </p>

<p>EDIT1: I'm only using 640x480 24-bit BMP images, so I don't need to check padding.</p>