Skip to content

Instantly share code, notes, and snippets.

@nasacj
Last active July 4, 2017 03:57
Show Gist options
  • Save nasacj/62c55c13963d3f4e67cd63e4f4d13761 to your computer and use it in GitHub Desktop.
Save nasacj/62c55c13963d3f4e67cd63e4f4d13761 to your computer and use it in GitHub Desktop.
Image Gradient in Java

Maven Dependency:

    <dependency>
      <groupId>com.jhlabs</groupId>
      <artifactId>filters</artifactId>
      <version>2.0.235</version>
    </dependency>

Java Code:

package net.nasacj.javalearn.ImageGradient;

import com.jhlabs.image.AbstractBufferedImageOp;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * prewitt operator
 * X-direction
 * -1, 0, 1
 * -1, 0, 1
 * -1, 0, 1
 * <p>
 * Y-direction
 * -1, -1, -1
 * 0,  0,  0
 * 1,  1,  1
 * <p>
 * sobel operator
 * X-direction
 * -1, 0, 1
 * -2, 0, 2
 * -1, 0, 1
 * <p>
 * Y-direction
 * -1, -2, -1
 * 0,  0,  0
 * 1,  2,  1
 */
public class GradientFilter extends AbstractBufferedImageOp {

    // prewitt operator
    public final static int[][] PREWITT_X = new int[][]{{-1, 0, 1}, {-1, 0, 1}, {-1, 0, 1}};
    public final static int[][] PREWITT_Y = new int[][]{{-1, -1, -1}, {0, 0, 0}, {1, 1, 1}};

    // sobel operator
    public final static int[][] SOBEL_X = new int[][]{{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
    public final static int[][] SOBEL_Y = new int[][]{{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};

    // direction parameter
    public final static int X_DIRECTION = 0;
    public final static int Y_DIRECTION = 2;
    public final static int XY_DIRECTION = 4;
    private int direction;
    private boolean isSobel;

    public GradientFilter() {
        direction = XY_DIRECTION;
        isSobel = true;
    }

    public static int clamp(int value) {
        return value < 0 ? 0 : (value > 255 ? 255 : value);
    }

    public static int getGray(Color pixel) {
        return (pixel.getRed() * 30 + pixel.getGreen() * 60 + pixel.getBlue() * 10) / 100;
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        new Thread(new Runnable() {
            public void run() {

            }
        }).start();

        BufferedImage img = null;
        try {
            img = ImageIO.read(new File("/Users/nasacj/Downloads/testImage.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        int w = img.getWidth(null);
        int h = img.getHeight(null);
        BufferedImage bi = new
                BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics g = bi.getGraphics();
        g.drawImage(img, 0, 0, null);

        BufferedImage destImg = null;
        GradientFilter gradientFilter = new GradientFilter();
        long timeinit = System.currentTimeMillis();
        destImg = gradientFilter.filter(img, destImg);
        System.out.println("Time cost: " + (System.currentTimeMillis() - timeinit) + " millis seconds");
        ImageIO.write(destImg, "jpeg", new File("/Users/nasacj/Downloads/testImageOut.jpg"));

        System.out.println();

    }

    public void setSoble(boolean sobel) {
        this.isSobel = sobel;
    }

    public int getDirection() {
        return direction;
    }

    public void setDirection(int direction) {
        this.direction = direction;
    }

    public BufferedImage filter(BufferedImage src, BufferedImage dest) {
        int width = src.getWidth();
        int height = src.getHeight();

        if (dest == null)
            dest = createCompatibleDestImage(src, null);

        int[] inPixels = new int[width * height];
        int[] outPixels = new int[width * height];
        getRGB(src, 0, 0, width, height, inPixels);
        int index = 0, index2 = 0;
        double xred = 0, xgreen = 0, xblue = 0;
        double yred = 0, ygreen = 0, yblue = 0;
        int newRow, newCol;
        for (int row = 0; row < height; row++) {
            int ta = 255, tr = 0, tg = 0, tb = 0;
            for (int col = 0; col < width; col++) {
                index = row * width + col;
                for (int subrow = -1; subrow <= 1; subrow++) {
                    for (int subcol = -1; subcol <= 1; subcol++) {
                        newRow = row + subrow;
                        newCol = col + subcol;
                        if (newRow < 0 || newRow >= height) {
                            newRow = row;
                        }
                        if (newCol < 0 || newCol >= width) {
                            newCol = col;
                        }
                        index2 = newRow * width + newCol;
                        int originPixel = inPixels[index2];
                        Color color = new Color(originPixel);
                        int gray = getGray(color);
                        int newPixel = new Color(gray, gray, gray).getRGB();
//                        tr = (inPixels[index2] >> 16) & 0xff;
//                        tg = (inPixels[index2] >> 8) & 0xff;
//                        tb = inPixels[index2] & 0xff;
                        tr = (newPixel >> 16) & 0xff;
                        tg = (newPixel >> 8) & 0xff;
                        tb = newPixel & 0xff;

                        if (isSobel) {
                            xred += (SOBEL_X[subrow + 1][subcol + 1] * tr);
                            xgreen += (SOBEL_X[subrow + 1][subcol + 1] * tg);
                            xblue += (SOBEL_X[subrow + 1][subcol + 1] * tb);

                            yred += (SOBEL_Y[subrow + 1][subcol + 1] * tr);
                            ygreen += (SOBEL_Y[subrow + 1][subcol + 1] * tg);
                            yblue += (SOBEL_Y[subrow + 1][subcol + 1] * tb);
                        } else {
                            xred += (PREWITT_X[subrow + 1][subcol + 1] * tr);
                            xgreen += (PREWITT_X[subrow + 1][subcol + 1] * tg);
                            xblue += (PREWITT_X[subrow + 1][subcol + 1] * tb);

                            yred += (PREWITT_Y[subrow + 1][subcol + 1] * tr);
                            ygreen += (PREWITT_Y[subrow + 1][subcol + 1] * tg);
                            yblue += (PREWITT_Y[subrow + 1][subcol + 1] * tb);
                        }
                    }
                }

                double mred = Math.sqrt(xred * xred + yred * yred);
                double mgreen = Math.sqrt(xgreen * xgreen + ygreen * ygreen);
                double mblue = Math.sqrt(xblue * xblue + yblue * yblue);
                if (XY_DIRECTION == direction) {
                    outPixels[index] = (ta << 24) | (clamp((int) mred) << 16) | (clamp((int) mgreen) << 8) | clamp((int) mblue);
                } else if (X_DIRECTION == direction) {
                    outPixels[index] = (ta << 24) | (clamp((int) yred) << 16) | (clamp((int) ygreen) << 8) | clamp((int) yblue);
                } else if (Y_DIRECTION == direction) {
                    outPixels[index] = (ta << 24) | (clamp((int) xred) << 16) | (clamp((int) xgreen) << 8) | clamp((int) xblue);
                } else {
                    // as default, always XY gradient
                    outPixels[index] = (ta << 24) | (clamp((int) mred) << 16) | (clamp((int) mgreen) << 8) | clamp((int) mblue);
                }

                // cleanup for next loop
                newRow = newCol = 0;
                xred = xgreen = xblue = 0;
                yred = ygreen = yblue = 0;

            }
        }
        setRGB(dest, 0, 0, width, height, outPixels);
        return dest;
    }

}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment