46971

RGB to Grayscale, bmp image in java

Question:

My teacher gave us a task to make a class that takes an 640x480 bmp colored image, to convert it in grayscale image, I found some sources with ideas so i did it. But there's a problem because it seems that it makes it cause it doesn't give me error, but the output doesn't appear. I think it's my code. My code is

import java.io.*; public class Grayscale{ FileInputStream image; FileOutputStream img; byte[] datos; int gray; public Grayscale(String nombre)throws Exception{ this.image = new FileInputStream(nombre); this.img = img; this.datos = new byte[image.available()]; this.gray = gray; } public void gray()throws Exception{ image.read(datos); img = new FileOutputStream("grayscaleprueba.bmp"); for (int i = 0; i<datos.length; i++){ 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; } img.write(datos); } }

Answer1:

There are some problems apart from those that @joni mentioned. This problem is a bit deeper than what it first seems to be.

<h3>BMP file format</h3> <ul><li>The <a href="http://en.wikipedia.org/wiki/BMP_file_format" rel="nofollow">BMP format</a> has a header. You should skip (or probably update) the header before doing the image transformation.</li> <li>color table: you assume a "straight" palette: the color index the same as the RGB value. But this might be different... (<strong>BTW:</strong> If the picture uses a color table, then you could alter only that to get a grayscale image however...)</li> <li>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.</li> <li>compression: yep, the image might be compressed - you'd have to decode it to do anything with the pixel values themselves.</li> </ul><h3>Loop</h3>

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; } <h3>Signed byte</h3>

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.

<h3>Pixel transformation values range</h3>

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

Answer2:

There are a few problems with this code:

<ol><li>The available method only tells you how many bytes are immediately available, without actually having to read from disk. It may well return 0.</li> <li>The read method reads only a part of the data. The return value tells you how many bytes it actually read.</li> <li>You don't close the output stream. Without closing the output there is no guarantee that anything at all is written to the output file.</li> </ol>

Answer3:

There are a lot of things that won't work in your code.

<ul><li>The available method does not necessarily returns the number of bytes in a file. You should use a dynamic container for the data you read from the input file.</li> <li>

The read method doesn't read the entire file. You have to use this method in a loop until it returns an incorrect value:

while ((byte = fis.read()) != -1) { //do something with byte }

</li> <li>

You make your conversion over every byte of the file. I don't know of any picture format where this would work. There are headers and padding, even in the most simple BMP format. You should read about the format you want to use because it won't be as simple as iterating over the whole stream and make the average of every block of 3 bytes.

</li> </ul>

Recommend

  • Format excel column to decimal doing export from c#
  • StringResult+format doesn't seem to work in Webix datepicker
  • Conditional formatting based on the previous cell in Excel 2013
  • splitting date and time in data frame
  • XslTransform with xml-stylesheet
  • cross combine two RDDs using pyspark
  • Changing One Tag Name in an XML File Using XSLT
  • How to Divide an array on c#?
  • Returning this from a constructor function in JS
  • cordova is not defined - cordova.js has already been loaded :: Ionic
  • jQuery: add elements until a particular height is reached
  • Combining two different ActiveRecord collections into one
  • android.support.v7.widget.Toolbar VectorDrawableCompat IllegalStateException when using support lib
  • saving file generated by TCPDF
  • How to view images from protected folder with php?
  • Textfile Structure (tables)
  • How to use carriage return with multiple line?
  • Refering to the class itself from within a class mehod in Objective C
  • How reduce the height of an mschart by breaking up the y-axis
  • Why doesn't :active or :focus work on text links in webkit? (safari & chrome)
  • How to apply VCL Styles to DLL-based forms in Inno Setup?
  • vba code to select only visible cells in specific column except heading
  • Font Awesome Showing Box instead of Icons
  • Delete MySQLi record without showing the id in the URL
  • Properly structure and highlight a GtkPopoverMenu using PyGObject
  • Run Powershell script from inside other Powershell script with dynamic redirection to file
  • Unanticipated behavior
  • Comma separated Values
  • retrieve vertices with no linked edge in arangodb
  • using conditional logic : check if record exists; if it does, update it, if not, create it
  • Load html files in TinyMce
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • Trying to get generic when generic is not available
  • Understanding cpu registers
  • Why joiner is not used after Sequence generator or Update statergy
  • coudnt use logback because of log4j
  • Android Google Maps API OnLocationChanged only called once
  • Add sale price programmatically to product variations
  • Is it possible to post an object from jquery to bottle.py?
  • Python/Django TangoWithDjango Models and Databases