Main.java Source code

Java tutorial

Introduction

Here is the source code for Main.java

Source

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Main {
    public static void main(String[] args) throws Exception {
        JFrame Main = new JFrame("Gradient Mask");
        JLabel imageLayer = new JLabel();
        JLabel maskLayer = new JLabel();
        BufferedImage image = ImageIO.read(new URL("http://www.java2s.com/style/download.png"));
        BufferedImage gradientMask = new GradientImage(image.getWidth(), image.getHeight(),
                new Color[] { new Color(255, 255, 255, 125), Color.BLACK }, GradientImage.RADIAL_FROM_CENTER)
                        .getImage();
        Main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Main.setBounds(100, 50, image.getWidth(), image.getHeight());
        imageLayer.setBounds(0, 0, Main.getWidth(), Main.getHeight());
        maskLayer.setBounds(0, 0, Main.getWidth(), Main.getHeight());
        imageLayer.setIcon(new ImageIcon((Image) image));
        maskLayer.setIcon(new ImageIcon((Image) gradientMask));
        Main.getContentPane().add(imageLayer);
        imageLayer.add(maskLayer);
        Main.setVisible(true);
    }
}

class GradientImage {
    public final static int LINEAR_LEFT_TO_RIGHT = 1;
    public final static int LINEAR_RIGHT_TO_LEFT = 2;
    public final static int LINEAR_TOP_TO_BOTTOM = 3;
    public final static int LINEAR_BOTTOM_TO_TOP = 4;
    public final static int LINEAR_DIAGONAL_UP = 5;
    public final static int LINEAR_DIAGONAL_DOWN = 6;
    public final static int RADIAL_FROM_TOP_LEFT_CORNER = 7;
    public final static int RADIAL_FROM_BOTTOM_LEFT_CORNER = 8;
    public final static int RADIAL_FROM_TOP_RIGHT_CORNER = 9;
    public final static int RADIAL_FROM_BOTTOM_RIGHT_CORNER = 10;
    public final static int RADIAL_FROM_CENTER = 11;
    public final static int RADIAL_FROM_CORNERS = 12;
    public final static int PATH_FROM_CENTER = 13;
    public final static int PATH_FROM_TOP_LEFT_CORNER = 14;
    public final static int PATH_FROM_TOP_RIGHT_CORNER = 15;
    public final static int PATH_FROM_BOTTOM_LEFT_CORNER = 16;
    public final static int PATH_FROM_BOTTOM_RIGHT_CORNER = 17;
    public final static int LINEAR_FROM_TOP_RIGHT_CORNER = 18;
    public final static int LINEAR_FROM_TOP_LEFT_CORNER = 19;
    public final static int LINEAR_FROM_BOTTOM_RIGHT_CORNER = 20;
    public final static int LINEAR_FROM_BOTTOM_LEFT_CORNER = 21;
    public final static int LINEAR_FROM_CENTER = 22;
    public final static int LINEAR_FROM_CORNERS = 23;
    public final static int PATH_FROM_CORNERS = 24;
    private BufferedImage image = null;
    private BufferedImage circleImage = null;
    private int[] pixels;
    private int[] circlePixels;
    private int[] positions;
    private Color[] colors;
    private int[] rgbs;
    private int alignment;
    private int width;
    private int height;

    public GradientImage(int width, int height, Color[] colors, int alignment) {
        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
        this.alignment = alignment;
        this.width = width;
        this.height = height;
        this.colors = colors;
        rgbs = new int[colors.length];
        for (int i = 0; i < rgbs.length; i++) {
            rgbs[i] = colors[i].getRGB();
        }
        try {
            renderImage();
        } catch (Exception error) {
            error.printStackTrace();
        }
    }

    public GradientImage(int width, int height, Color[] colors, int[] positions, int alignment) {
        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
        this.alignment = alignment;
        this.width = width;
        this.height = height;
        this.colors = colors;
        this.positions = positions;
        rgbs = new int[colors.length];
        for (int i = 0; i < rgbs.length; i++) {
            rgbs[i] = colors[i].getRGB();
        }
        try {
            renderImage();
        } catch (Exception error) {
            error.printStackTrace();
        }
    }

    public BufferedImage getImage() {
        return image;
    }

    public BufferedImage getImageAsCircle() {
        if (circleImage == null) {
            circleImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            circlePixels = ((DataBufferInt) circleImage.getRaster().getDataBuffer()).getData();
            int radius = Math.min(width, height) >> 1;
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    if (Math.sqrt((Math.max(width >> 1, x) - Math.min(width >> 1, x))
                            * (Math.max(width >> 1, x) - Math.min(width >> 1, x))
                            + (Math.max(height >> 1, y) - Math.min(height >> 1, y))
                                    * (Math.max(height >> 1, y) - Math.min(height >> 1, y))) <= radius) {
                        circlePixels[x + y * width] = pixels[x + y * width];
                    }
                }
            }
        }
        return circleImage;
    }

    private void renderImage() throws Exception {
        if (alignment == LINEAR_LEFT_TO_RIGHT) {
            int[] rgbRange = loadRGBRange(width, rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[x + y * width] = rgbRange[x];
                }
            }
        } else if (alignment == LINEAR_RIGHT_TO_LEFT) {
            int[] rgbRange = loadRGBRange(width, rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[x + y * width] = rgbRange[width - x - 1];
                }
            }
        } else if (alignment == LINEAR_BOTTOM_TO_TOP) {
            int[] rgbRange = loadRGBRange(height, rgbs, positions);
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    pixels[x + y * width] = rgbRange[height - y - 1];
                }
            }
        } else if (alignment == LINEAR_TOP_TO_BOTTOM) {
            int[] rgbRange = loadRGBRange(height, rgbs, positions);
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    pixels[x + y * width] = rgbRange[y];
                }
            }
        } else if (alignment == RADIAL_FROM_TOP_LEFT_CORNER) {
            int[] rgbRange = loadRGBRange((int) Math.sqrt((width - 1) * (width - 1) + (height - 1) * (height - 1)),
                    rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[x + y * width] = rgbRange[(int) Math.sqrt((x - 1) * (x - 1) + (y - 1) * (y - 1))];
                }
            }
        } else if (alignment == RADIAL_FROM_BOTTOM_LEFT_CORNER) {
            int[] rgbRange = loadRGBRange((int) Math.sqrt((width - 1) * (width - 1) + (height - 1) * (height - 1)),
                    rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[x + (height - y - 1) * width] = rgbRange[(int) Math
                            .sqrt((x - 1) * (x - 1) + (y - 1) * (y - 1))];
                }
            }
        } else if (alignment == RADIAL_FROM_TOP_RIGHT_CORNER) {
            int[] rgbRange = loadRGBRange((int) Math.sqrt((width - 1) * (width - 1) + (height - 1) * (height - 1)),
                    rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[(width - x - 1)
                            + y * width] = rgbRange[(int) Math.sqrt((x - 1) * (x - 1) + (y - 1) * (y - 1))];
                }
            }
        } else if (alignment == RADIAL_FROM_BOTTOM_RIGHT_CORNER) {
            int[] rgbRange = loadRGBRange((int) Math.sqrt((width - 1) * (width - 1) + (height - 1) * (height - 1)),
                    rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[(width - x - 1) + (height - y - 1) * width] = rgbRange[(int) Math
                            .sqrt((x - 1) * (x - 1) + (y - 1) * (y - 1))];
                }
            }
        } else if (alignment == RADIAL_FROM_CENTER) {
            int[] divArray = divideArray(positions, 2);
            BufferedImage quad1 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.RADIAL_FROM_BOTTOM_RIGHT_CORNER).getImage();
            BufferedImage quad2 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.RADIAL_FROM_BOTTOM_LEFT_CORNER).getImage();
            BufferedImage quad3 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.RADIAL_FROM_TOP_RIGHT_CORNER).getImage();
            BufferedImage quad4 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.RADIAL_FROM_TOP_LEFT_CORNER).getImage();
            Graphics2D g = image.createGraphics();
            g.drawImage(quad1, 0, 0, null);
            g.drawImage(quad2, width >> 1, 0, null);
            g.drawImage(quad3, 0, height >> 1, null);
            g.drawImage(quad4, width >> 1, height >> 1, null);
            g.dispose();
        } else if (alignment == RADIAL_FROM_CORNERS) {
            int[] divArray = divideArray(positions, 2);
            BufferedImage quad1 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.RADIAL_FROM_TOP_LEFT_CORNER).getImage();
            BufferedImage quad2 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.RADIAL_FROM_TOP_RIGHT_CORNER).getImage();
            BufferedImage quad3 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.RADIAL_FROM_BOTTOM_LEFT_CORNER).getImage();
            BufferedImage quad4 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.RADIAL_FROM_BOTTOM_RIGHT_CORNER).getImage();
            Graphics2D g = image.createGraphics();
            g.drawImage(quad1, 0, 0, null);
            g.drawImage(quad2, width >> 1, 0, null);
            g.drawImage(quad3, 0, height >> 1, null);
            g.drawImage(quad4, width >> 1, height >> 1, null);
            g.dispose();
        } else if (alignment == LINEAR_DIAGONAL_UP) {
            int[] rgbRange = loadRGBRange((int) Math.sqrt((width - 1) * (width - 1) + (height - 1) * (height - 1)),
                    rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[x + (height - y - 1) * width] = rgbRange[Math.max(y - x, x - y)];
                }
            }
        } else if (alignment == LINEAR_DIAGONAL_DOWN) {
            int[] rgbRange = loadRGBRange((int) Math.sqrt((width - 1) * (width - 1) + (height - 1) * (height - 1)),
                    rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[x + y * width] = rgbRange[Math.max(y - x, x - y)];
                }
            }
        } else if (alignment == LINEAR_FROM_TOP_RIGHT_CORNER) {
            int[] rgbRange = loadRGBRange((width + height) >> 1, rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[x + (height - y - 1) * width] = rgbRange[rgbRange.length - ((x + y) >> 1) - 1];
                }
            }
        } else if (alignment == LINEAR_FROM_TOP_LEFT_CORNER) {
            int[] rgbRange = loadRGBRange((width + height) >> 1, rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[(width - x - 1) + (height - y - 1) * width] = rgbRange[rgbRange.length - ((x + y) >> 1)
                            - 1];
                }
            }
        } else if (alignment == LINEAR_FROM_BOTTOM_RIGHT_CORNER) {
            int[] rgbRange = loadRGBRange((width + height) >> 1, rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[x + y * width] = rgbRange[rgbRange.length - ((x + y) >> 1) - 1];
                }
            }
        } else if (alignment == LINEAR_FROM_BOTTOM_LEFT_CORNER) {
            int[] rgbRange = loadRGBRange((width + height) >> 1, rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[(width - x - 1) + y * width] = rgbRange[rgbRange.length - ((x + y) >> 1) - 1];
                }
            }
        } else if (alignment == LINEAR_FROM_CENTER) {
            int[] divArray = divideArray(positions, 2);
            BufferedImage quad1 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.LINEAR_FROM_BOTTOM_RIGHT_CORNER).getImage();
            BufferedImage quad2 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.LINEAR_FROM_BOTTOM_LEFT_CORNER).getImage();
            BufferedImage quad3 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.LINEAR_FROM_TOP_RIGHT_CORNER).getImage();
            BufferedImage quad4 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.LINEAR_FROM_TOP_LEFT_CORNER).getImage();
            Graphics2D g = image.createGraphics();
            g.drawImage(quad1, 0, 0, null);
            g.drawImage(quad2, width >> 1, 0, null);
            g.drawImage(quad3, 0, height >> 1, null);
            g.drawImage(quad4, width >> 1, height >> 1, null);
            g.dispose();
        } else if (alignment == LINEAR_FROM_CORNERS) {
            int[] divArray = divideArray(positions, 2);
            BufferedImage quad1 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.LINEAR_FROM_TOP_LEFT_CORNER).getImage();
            BufferedImage quad2 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.LINEAR_FROM_TOP_RIGHT_CORNER).getImage();
            BufferedImage quad3 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.LINEAR_FROM_BOTTOM_LEFT_CORNER).getImage();
            BufferedImage quad4 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.LINEAR_FROM_BOTTOM_RIGHT_CORNER).getImage();
            Graphics2D g = image.createGraphics();
            g.drawImage(quad1, 0, 0, null);
            g.drawImage(quad2, width >> 1, 0, null);
            g.drawImage(quad3, 0, height >> 1, null);
            g.drawImage(quad4, width >> 1, height >> 1, null);
            g.dispose();
        } else if (alignment == PATH_FROM_TOP_LEFT_CORNER) {
            int[] rgbRange = loadRGBRange(Math.max(width, height), rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[x + y * width] = rgbRange[Math.max(x, y)];
                }
            }
        } else if (alignment == PATH_FROM_TOP_RIGHT_CORNER) {
            int[] rgbRange = loadRGBRange(Math.max(width, height), rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[(width - x - 1) + y * width] = rgbRange[Math.max(x, y)];
                }
            }
        } else if (alignment == PATH_FROM_BOTTOM_LEFT_CORNER) {
            int[] rgbRange = loadRGBRange(Math.max(width, height), rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[x + (height - y - 1) * width] = rgbRange[Math.max(x, y)];
                }
            }
        } else if (alignment == PATH_FROM_BOTTOM_RIGHT_CORNER) {
            int[] rgbRange = loadRGBRange(Math.max(width, height), rgbs, positions);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    pixels[(width - x - 1) + (height - y - 1) * width] = rgbRange[Math.max(x, y)];
                }
            }
        } else if (alignment == PATH_FROM_CENTER) {
            int[] divArray = divideArray(positions, 2);
            BufferedImage quad1 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.PATH_FROM_BOTTOM_RIGHT_CORNER).getImage();
            BufferedImage quad2 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.PATH_FROM_BOTTOM_LEFT_CORNER).getImage();
            BufferedImage quad3 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.PATH_FROM_TOP_RIGHT_CORNER).getImage();
            BufferedImage quad4 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.PATH_FROM_TOP_LEFT_CORNER).getImage();
            Graphics2D g = image.createGraphics();
            g.drawImage(quad1, 0, 0, null);
            g.drawImage(quad2, width >> 1, 0, null);
            g.drawImage(quad3, 0, height >> 1, null);
            g.drawImage(quad4, width >> 1, height >> 1, null);
            g.dispose();
        } else if (alignment == PATH_FROM_CORNERS) {
            int[] divArray = divideArray(positions, 2);
            BufferedImage quad1 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.PATH_FROM_TOP_LEFT_CORNER).getImage();
            BufferedImage quad2 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.PATH_FROM_TOP_RIGHT_CORNER).getImage();
            BufferedImage quad3 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.PATH_FROM_BOTTOM_LEFT_CORNER).getImage();
            BufferedImage quad4 = new GradientImage(width >> 1, height >> 1, colors, divArray,
                    GradientImage.PATH_FROM_BOTTOM_RIGHT_CORNER).getImage();
            Graphics2D g = image.createGraphics();
            g.drawImage(quad1, 0, 0, null);
            g.drawImage(quad2, width >> 1, 0, null);
            g.drawImage(quad3, 0, height >> 1, null);
            g.drawImage(quad4, width >> 1, height >> 1, null);
            g.dispose();
        }
    }

    public int[] divideArray(int[] array, int div) {
        if (array == null) {
            return null;
        }
        int[] arr = new int[array.length];
        if (div == 2) {
            for (int i = 0; i < arr.length; i++) {
                arr[i] = array[i] >> 1;
            }
        } else {
            for (int i = 0; i < arr.length; i++) {
                arr[i] = array[i] / div;
            }
        }
        return arr;
    }

    public int[] loadRGBRange(int length, int[] rgbs) throws Exception {
        if (rgbs == null) {
            throw new Exception("RGB[]'s cannot be null");
        }
        if (length == 0) {
            throw new Exception("Length cannot be 0");
        }
        if (rgbs.length == 0) {
            throw new Exception("RGB[]'s length cannot be 0");
        }
        int[] rgbRange = new int[length];
        if (rgbs.length == 1) {
            for (int i = 0; i < rgbRange.length; i++) {
                rgbRange[i] = rgbs[0];
            }
            return rgbRange;
        }
        int[] positions = new int[rgbs.length];
        double pos = 0;
        double block = (double) length / (rgbs.length - 1);
        for (int i = 0; i < positions.length; i++) {
            positions[i] = (int) pos;
            pos += block;
        }
        int[] as = new int[rgbs.length];
        int[] rs = new int[rgbs.length];
        int[] gs = new int[rgbs.length];
        int[] bs = new int[rgbs.length];
        for (int i = 0; i < rgbs.length; i++) {
            as[i] = (rgbs[i] >> 24) & 0xff;
            rs[i] = (rgbs[i] >> 16) & 0xff;
            gs[i] = (rgbs[i] >> 8) & 0xff;
            bs[i] = (rgbs[i]) & 0xff;
        }
        int[] adifs = new int[rgbs.length - 1];
        int[] rdifs = new int[rgbs.length - 1];
        int[] gdifs = new int[rgbs.length - 1];
        int[] bdifs = new int[rgbs.length - 1];
        for (int i = 0; i < rgbs.length - 1; i++) {
            adifs[i] = as[i] - as[i + 1];
            rdifs[i] = rs[i] - rs[i + 1];
            gdifs[i] = gs[i] - gs[i + 1];
            bdifs[i] = bs[i] - bs[i + 1];
        }
        double[] ab = new double[rgbs.length - 1];
        double[] rb = new double[rgbs.length - 1];
        double[] gb = new double[rgbs.length - 1];
        double[] bb = new double[rgbs.length - 1];
        for (int i = 0; i < rgbs.length - 1; i++) {
            int l = positions[i + 1] - positions[i];
            ab[i] = (double) adifs[i] / l;
            rb[i] = (double) rdifs[i] / l;
            gb[i] = (double) gdifs[i] / l;
            bb[i] = (double) bdifs[i] / l;
        }
        double a = as[0];
        double r = rs[0];
        double g = gs[0];
        double b = bs[0];
        int color = 0;
        for (int i = 0; i < rgbRange.length; i++) {
            rgbRange[i] = ((int) a << 24) | ((int) r << 16) | ((int) g << 8) | ((int) b);
            if (i + 1 > positions[0] && i + 1 < positions[positions.length - 1]) {
                if (i == positions[color + 1]) {
                    color++;
                    a = as[color];
                    r = rs[color];
                    g = gs[color];
                    b = bs[color];
                } else {
                    a -= ab[color];
                    r -= rb[color];
                    g -= gb[color];
                    b -= bb[color];
                }
            }
        }
        return rgbRange;
    }

    public int[] loadRGBRange(int length, int[] rgbs, int[] positions) throws Exception {
        if (positions == null) {
            return loadRGBRange(length, rgbs);
        }
        if (rgbs == null) {
            throw new Exception("RGB[]'s cannot be null");
        }
        if (length == 0) {
            throw new Exception("Length cannot be 0");
        }
        if (rgbs.length == 0 || positions.length == 0) {
            return null;
        }
        if (positions.length != rgbs.length) {
            throw new Exception("The length of Positions[] must equals the length of RGB[]'s");
        }
        for (int i = 0; i < positions.length; i++) {
            if (positions[i] > length) {
                throw new Exception("Any positions cannot be greater than the length");
            }
        }
        int[] rgbRange = new int[length];
        if (rgbs.length == 1) {
            for (int i = 0; i < rgbRange.length; i++) {
                rgbRange[i] = rgbs[0];
            }
            return rgbRange;
        }
        int[] as = new int[rgbs.length];
        int[] rs = new int[rgbs.length];
        int[] gs = new int[rgbs.length];
        int[] bs = new int[rgbs.length];
        for (int i = 0; i < rgbs.length; i++) {
            as[i] = (rgbs[i] >> 24) & 0xff;
            rs[i] = (rgbs[i] >> 16) & 0xff;
            gs[i] = (rgbs[i] >> 8) & 0xff;
            bs[i] = (rgbs[i]) & 0xff;
        }
        int[] adifs = new int[rgbs.length - 1];
        int[] rdifs = new int[rgbs.length - 1];
        int[] gdifs = new int[rgbs.length - 1];
        int[] bdifs = new int[rgbs.length - 1];
        for (int i = 0; i < rgbs.length - 1; i++) {
            adifs[i] = as[i] - as[i + 1];
            rdifs[i] = rs[i] - rs[i + 1];
            gdifs[i] = gs[i] - gs[i + 1];
            bdifs[i] = bs[i] - bs[i + 1];
        }
        double[] ab = new double[rgbs.length - 1];
        double[] rb = new double[rgbs.length - 1];
        double[] gb = new double[rgbs.length - 1];
        double[] bb = new double[rgbs.length - 1];
        for (int i = 0; i < rgbs.length - 1; i++) {
            int l = positions[i + 1] - positions[i];
            ab[i] = (double) adifs[i] / l;
            rb[i] = (double) rdifs[i] / l;
            gb[i] = (double) gdifs[i] / l;
            bb[i] = (double) bdifs[i] / l;
        }
        double a = as[0];
        double r = rs[0];
        double g = gs[0];
        double b = bs[0];
        int color = 0;
        for (int i = 0; i < rgbRange.length; i++) {
            rgbRange[i] = ((int) a << 24) | ((int) r << 16) | ((int) g << 8) | ((int) b);
            if (i + 1 > positions[0] && i + 1 < positions[positions.length - 1]) {
                if (i == positions[color + 1]) {
                    color++;
                    a = as[color];
                    r = rs[color];
                    g = gs[color];
                    b = bs[color];
                } else {
                    a -= ab[color];
                    r -= rb[color];
                    g -= gb[color];
                    b -= bb[color];
                }
            }
        }
        return rgbRange;
    }
}