Skip to main content
Typo fix
Source Link
janos
  • 111.7k
  • 15
  • 152
  • 391
public interface BlackAndWhiteConverter {
    BufferedImage toBlackAndWhite(BufferedImage image);
    void setThreshold(int threshold);
}  
public interface BlackAndWhiteConverter {
    BufferedImage toBlackAndWhite(BufferedImage image)
    void setThreshold(int threshold);
}  
public interface BlackAndWhiteConverter {
    BufferedImage toBlackAndWhite(BufferedImage image);
    void setThreshold(int threshold);
}  
Source Link
Heslacher
  • 50.4k
  • 5
  • 81
  • 175

Colored image will become black and white

For a project of mine, which is targeting java 6, I had been in the need to have different algorithms/methods to change a BufferdImage with a ColorSpace.TYPE_RGB to a plain ole black and white one.

To test these implementations I therefore created an interface

public interface BlackAndWhiteConverter {
    BufferedImage toBlackAndWhite(BufferedImage image)
    void setThreshold(int threshold);
}  

and the, for me, most successful implementation is up for review

import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;

public class BlackAndWhiteRedThresholdConverter implements BlackAndWhiteConverter {

    @Override
    public BufferedImage toBlackAndWhite(final BufferedImage image) {
        
        final int imageType = image.getColorModel().getColorSpace().getType();

        if (imageType != ColorSpace.TYPE_RGB) {
            throw new IllegalArgumentException();
        }

        final int width = image.getWidth();
        final int height = image.getHeight();
        final int upperLimit = width * height;

        final DataBuffer buffer = image.getRaster().getDataBuffer();
        final int[] source = ((DataBufferInt) buffer).getData();

        byte[] destination = new byte[upperLimit];
        
        for (int i = 0; i < upperLimit; i++) {
            
            int red = (source[i] >> 16) & 0x000000FF;
            
            if (red > threshold) {
                destination[i] = -1;
            }
        }

        WritableRaster raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, width, height, 1, 2, null);
        raster.setDataElements(0, 0, width, height, destination);

        BufferedImage destinationImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
        destinationImage.setData(raster);
        return destinationImage;
    }
    
    private int threshold = 110;

    @Override
    public void setThreshold(int threshold) {
        this.threshold = threshold;
    }

    
}

Please comment on anything that springs into your face. No matter what, I can't use a java version higher than 6.