There are some problems apart from those that @joni mentioned. This problem is a bit deeper than what it first seems to be.
BMP file format
- The BMP format has a header. You should skip (or probably update) the header before doing the image transformation.
- color table: you assume a "straight" palette: the color index the same as the RGB value. But this might be different... (BTW: If the picture uses a color table, then you could alter only that to get a grayscale image however...)
- how many bits per pixel are there? You assumed that it is 24 bits per pixel, in a 8-8-8 distribution. This is not guarranteed... The header provides this info.
- compression: yep, the image might be compressed - you'd have to decode it to do anything with the pixel values themselves.
Loop
You deal with 3 bytes for each pixel, and you loop through the file in the increments of 1. The resulting image might happen to be quite interesting to watch through 3D glasses, but will mean some strange image appearing.
for (int i = 0; i<datos.length; i+=3){ // increment by 3 instead of 1
gray = (byte)(datos[i]*0.3 + datos[i+1]*0.59 + datos[i+2]);
datos[i] = (byte)gray;
datos[i+1] = (byte)gray;
datos[i+2] = (byte)gray;
}
Signed byte
Byte in Java is signed. It goes from -128 to 127, so your arithmetic is not valid. For each byte, I'd use it as an int, and add 128 to it before summing them with weights. Then after summing, subtract the 128, and then cast to byte.
Pixel transformation values range
You sum up 3 numbers in the saem range, and would want to get a number in the range itself. However, your weights don't reflect this: the weights should add up to 1. For starters, I'd use 0.33 for all values (that does not give perfect color weights,but should technically works).
//using double to have some precision
double temp = datos[i]/3.0d + datos[i+1]/3.0d + datos[i]/3.0d;
gray = (byte)(Math.round(temp)-128); //rounding to Long, and converting to byt value range