Hey im trying to create a program which uses Floyd-Steinberg's dithering algorithm to produce a dithered version of a image.
the code for my program is below.
but I believe I am getting an error with with the rounding in the "calculateErr" multiplication with the diviser. the image I am using to test is this cat one: Cat Image
and for some reason it ends up looking like this Dithered cat image
any solutions to what I am doing wrong would be greatly appreciated.
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Dithering extends Canvas {
public BufferedImage ditheredIMG = new BufferedImage(481,480,
BufferedImage.TYPE_BYTE_GRAY);
public void paint(Graphics g) {
BufferedImage i = null;
try {
i = displayImage(g);
} catch (IOException e) {
throw new RuntimeException(e);
}
getPixels(g, i);
g.drawImage(ditheredIMG,480,0,this);
}
public static void main(String[] args) {
Dithering d = new Dithering();
JFrame f =new JFrame();
f.add(d);
f.setSize( 960,481);
f.setVisible(true);
}
public BufferedImage displayImage(Graphics g) throws IOException {
final File file = new File("Cat.jpg");
final BufferedImage i = ImageIO.read(file);
g.drawImage(i, 0,0,this);
return i;
}
public void getPixels(Graphics g, BufferedImage i) {
for (int y = 1; y < i.getHeight()-1; y++){
for (int x = 1; x < i.getWidth()-1; x++) {
int pixelValue = i.getRGB(x, y);
int red = (pixelValue & 0x00ff0000) >> 16;
int green = (pixelValue & 0x0000ff00) >> 8;
int blue = pixelValue & 0x000000ff;
int newRed = quantisePixel(red);
int newGreen = quantisePixel(green);
int newBlue = quantisePixel(blue);
int newPixel = (newRed << 16) | (newGreen << 8) | newBlue;
ditheredIMG.setRGB(x+1,y, (int) (calculateErr(pixelValue, newPixel) * (7/16.0)));
ditheredIMG.setRGB(x-1,y+1, (int) (calculateErr(pixelValue, newPixel) * (3/16.0)));
ditheredIMG.setRGB(x,y+1, (int) (calculateErr(pixelValue, newPixel) * (5/16.0)));
ditheredIMG.setRGB(x+1,y+1, (int) (calculateErr(pixelValue, newPixel)* (1/16.0)));
}
}
}
public int calculateErr(int oldVal, int newVal){
return oldVal-newVal;
}
public static int quantisePixel(int val){
if(val > 127){
return 255;
} else{
return 0;
}
}
}