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.