0

I am trying to create a (average) greyscale of an image, and I do not seem to get the values for each pixel. I think I am not doing the right calculations when summarizing the average, but I can not find what is wrong.

public byte[] changePixelValues(byte blue, byte green, byte red) {
            //Convert to greyscale by average
            byte avg;
            int sum = 0;
            sum +=blue;
            sum += green;
            sum += red;
            avg = (byte) (sum / 3);

            //System.out.println("avg: " +  avg);
            byte[] values = new byte[3];

            values[0] = avg;
            values[1] = avg;
            values[2] = avg;

            return values;

Is there something that I missed in the type conversion?

EDIT:

The input is the following where byte[] data is the raw data from a BufferedImage, which in this case does not have an alphaRaster.

for (int i = 0; i < data.length; i += 3) {
      byte [] newData = changer.changePixelValues(data[i], data[i+1], data[i+2]);
      System.arraycopy(newData,0,data,i,3);
}
  • Can you show us some sample inputs and outputs? Your code looks fine. – Tim Biegeleisen Jul 25 '15 at 10:47
  • 1
    `sum / 3` is an integer division. You might want to use `sum / 3.0` to make it a double division with rounding to a byte afterwards: `avg = (byte) (Math.round(sum / 3.0))`. Not sure whether this is your real problem, though. – Seelenvirtuose Jul 25 '15 at 10:53
  • Just added an edit in the question describing the usage. – Daniel Eineving Jul 25 '15 at 10:53
  • You still haven't told us what the exact problem is. Are you not getting a greyscale image? Are the byte outputs from `changePixelValues()` wrong? – Tim Biegeleisen Jul 25 '15 at 10:56
  • From the looks of it, I would assume that your averaging method is correct. Please provide some input- and output-data as [others have already suggested](http://stackoverflow.com/questions/31625608/average-of-byte-values#comment51199011_31625608). – Turing85 Jul 25 '15 at 11:01
  • 2
    No help for your problem, but see http://stackoverflow.com/questions/687261/converting-rgb-to-grayscale-intensity for the correct weighted average for greyscale conversion – Mark Schäfer Jul 25 '15 at 11:03
  • Your code does not show how you handle the byte array but if you got it from a `BufferedImage.getData()` call, note that it returns a copy of the image data, this means that changing the array contents does not change the BufferedImage. – EmirCalabuch Jul 25 '15 at 11:06
  • Grayscale images typically average out the pixels with some coefficients, not equally like what you do, because human eyes don't percept the 3 main colors similarly. For example in PAL it's calculated as `Y′ = 0.299 R′ + 0.587 G′ + 0.114 B′` [Why does greyscale work the way it does?](http://stackoverflow.com/q/5311774/995714) – phuclv Jul 25 '15 at 11:13
  • [RGB to monochrome conversion](http://stackoverflow.com/q/14330/995714) – phuclv Jul 25 '15 at 11:15

1 Answers1

1

First of all if you want convert image to greyscale you method should return only one byte value not byte array. If you return one byte you could assign that value to each RGB channel and you get grayscale image or set that value to 8-bit image.

You need to remember that byte in java is signed (range -128 to 127) so if you have for example R-channel value equal to 200 (channel values could be in range 0 to 255) and you cast it to byte, value is equal to -56. So if you calculate average (lets assume that G=B=100) you have average equals 48 (should be 133).

Springfield762
  • 221
  • 1
  • 11