Java Graphics How to - Apply variable transparency to an image








Question

We would like to know how to apply variable transparency to an image.

Answer

code revised from http://stackoverflow.com/questions/23056090

User information: http://stackoverflow.com/users/3417524/cvogt8

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;
/*ww w.jav  a 2  s  .  co  m*/
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;
  }
}