package com.swingsane.business.image;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import org.apache.log4j.Logger;
/**
* @author Roland Quast (roland@formreturn.com)
*
*/
public final class ImageBinarize {
public static BufferedImage binarizeImage(BufferedImage image, int luminanceCutOff,
boolean despeckle) {
BufferedImage newImg = new BufferedImage(image.getWidth(), image.getHeight(),
BufferedImage.TYPE_BYTE_BINARY);
// just copy the image if it is already a binary image.
if (image.getType() == BufferedImage.TYPE_BYTE_BINARY) {
Graphics2D g2d = newImg.createGraphics();
g2d.drawImage(image, 0, 0, null);
newImg.flush();
g2d.dispose();
return newImg;
}
WritableRaster raster = newImg.getRaster();
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
for (int y = 0; y < imageHeight; y++) {
for (int x = 0; x < imageWidth; x++) {
if (isBlack(image, x, y, luminanceCutOff)) {
raster.setSample(x, y, 0, 0);
} else {
raster.setSample(x, y, 0, 1);
}
if (despeckle) {
if ((x < 4) || (x >= (imageWidth - 4))) {
continue;
}
int sum = 0;
for (int offset = 0; offset < 5; offset++) {
if (offset == 2) {
continue;
}
int xpos = (x - offset);
sum += raster.getSample(xpos, y, 0);
}
int xpos = (x - 2);
if (xpos > 0) {
if (sum == 4) {
if (raster.getSample(xpos, y, 0) != WHITE) {
raster.setSample(xpos, y, 0, WHITE);
}
} else if (sum == 0) {
if (raster.getSample(xpos, y, 0) != BLACK) {
raster.setSample(xpos, y, 0, BLACK);
}
}
}
}
}
}
if (despeckle) {
int heightMax = imageHeight - 6;
for (int y = 6; y < heightMax; y++) {
for (int x = 0; x < imageWidth; x++) {
int sum = 0;
for (int offset = 0; offset < 7; offset++) {
if (offset == 3) {
continue;
}
int ypos = (y - offset);
sum += raster.getSample(x, ypos, 0);
}
int ypos = (y - 3);
if (ypos > 0) {
if (sum == 6) {
if (raster.getSample(x, ypos, 0) != WHITE) {
raster.setSample(x, ypos, 0, WHITE);
}
} else if (sum == 0) {
if (raster.getSample(x, ypos, 0) != BLACK) {
raster.setSample(x, ypos, 0, BLACK);
}
}
}
}
}
}
newImg.flush();
return newImg;
}
public static boolean isBlack(BufferedImage image, int x, int y, int luminanceCutOff) {
// return white on areas outside of image boundaries
if ((x < 0) || (y < 0) || (x > (image.getWidth() - 1)) || (y > (image.getHeight() - 1))) {
return false;
}
if (image.getType() == BufferedImage.TYPE_BYTE_BINARY) {
WritableRaster raster = image.getRaster();
int pixelRGBValue = raster.getSample(x, y, 0);
return pixelRGBValue == 0;
}
int pixelRGBValue;
int r;
int g;
int b;
double luminance = 0.0;
try {
pixelRGBValue = image.getRGB(x, y);
r = (pixelRGBValue >> 16) & 0xff;
g = (pixelRGBValue >> 8) & 0xff;
b = (pixelRGBValue >> 0) & 0xff;
luminance = (r * 0.299) + (g * 0.587) + (b * 0.114);
} catch (Exception e) {
LOG.error(e, e);
}
return (luminance < luminanceCutOff);
}
public static final int BLACK = 0;
public static final int WHITE = 1;
/**
* Log4J logger.
*/
private static final Logger LOG = Logger.getLogger(ImageBinarize.class);
private ImageBinarize() {
}
}