I want to read an image and convert and output the original image, a greyscale version, and a sepia version. I am having trouble with the conversion, not very familiar with
You can create a filter interface for code reuse.
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class FilterApp {
public static ClassLoader loader = FilterApp.class.getClassLoader();
public static String outputDir = "build";
public static void main(String[] args) {
try {
BufferedImage srcImage = loadImage("lobster.jpg");
File dir = new File(outputDir);
if (!dir.exists()) {
dir.mkdirs();
}
for (FilterType filter : FilterType.values()) {
BufferedImage filteredImage = filter.applyFilter(srcImage);
String filename = String.format("%s/lobster_%s", outputDir, filter.name().toLowerCase());
writeImage(filteredImage, filename, "jpg");
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static BufferedImage loadImage(String filename) throws IOException {
return ImageIO.read(loader.getResourceAsStream("resources/" + filename));
}
private static void writeImage(BufferedImage image, String filename, String ext) throws IOException {
ImageIO.write(image, ext, new File(filename + '.' + ext));
}
}
import java.awt.image.BufferedImage;
import filter.GreyscaleFilter;
import filter.ImageFilter;
import filter.InvertFilter;
import filter.SepiaFilter;
public enum FilterType {
GREYSCALE(new GreyscaleFilter()),
INVERT(new InvertFilter()),
SEPIA_10(new SepiaFilter(10));
private ImageFilter filter;
public ImageFilter getFilter() { return filter; }
public BufferedImage applyFilter(BufferedImage img) {
return this.filter.apply(img);
}
private FilterType(ImageFilter filter) {
this.filter = filter;
}
}
package filter;
import java.awt.image.BufferedImage;
/** Common Interface for different filters. */
public interface ImageFilter {
public BufferedImage apply(BufferedImage img);
}
package filter;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
public class GreyscaleFilter implements ImageFilter {
@Override
public BufferedImage apply(BufferedImage img) {
BufferedImage result = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
op.filter(img, result);
return result;
}
}
package filter;
import java.awt.Color;
import java.awt.image.BufferedImage;
public class InvertFilter implements ImageFilter {
@Override
public BufferedImage apply(BufferedImage img) {
BufferedImage result = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
int rgb = img.getRGB(x, y);
Color color = new Color(rgb, true);
int r = 255 - color.getRed();
int g = 255 - color.getGreen();
int b = 255 - color.getBlue();
color = new Color(r, g, b, color.getAlpha());
result.setRGB(x, y, color.getRGB());
}
}
return result;
}
}
package filter;
import java.awt.Color;
import java.awt.image.BufferedImage;
// Algorithm obtained from http://stackoverflow.com/questions/21899824
public class SepiaFilter implements ImageFilter {
private int intensity;
public void setIntensity(int intensity) { this.intensity = intensity; }
public int getIntensity() { return intensity; }
public SepiaFilter(int intensity) {
this.intensity = intensity;
}
@Override
public BufferedImage apply(BufferedImage img) {
BufferedImage result = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
// Play around with this.
// 20 works well and was recommended by another developer.
// 0 produces black/white image
int sepiaDepth = 20;
int w = img.getWidth();
int h = img.getHeight();
// We need 3 integers (for R,G,B color values) per pixel.
int[] pixels = new int[w * h * 3];
img.getRaster().getPixels(0, 0, w, h, pixels);
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
int rgb = img.getRGB(x, y);
Color color = new Color(rgb, true);
int r = color.getRed();
int g = color.getGreen();
int b = color.getBlue();
int gry = (r + g + b) / 3;
r = g = b = gry;
r = r + (sepiaDepth * 2);
g = g + sepiaDepth;
if (r > 255) { r = 255; }
if (g > 255) { g = 255; }
if (b > 255) { b = 255; }
// Darken blue color to increase sepia effect
b -= this.intensity;
// normalize if out of bounds
if (b < 0) { b = 0; }
if (b > 255) { b = 255; }
color = new Color(r, g, b, color.getAlpha());
result.setRGB(x, y, color.getRGB());
}
}
return result;
}
}
Source Image
Generated Images