private static BufferedImage alterBufferedImage(BufferedImage bi, BufferedImage smaskImage, BufferedImage maskImage, int[] maskMinRGB, int[] maskMaxRGB) {
        Raster smaskRaster = null;
        int smaskWidth = 0;
        int smaskHeight = 0;

        int width = bi.getWidth();
        int height = bi.getHeight();

        if (smaskImage != null) {
            smaskRaster = smaskImage.getRaster();
            smaskWidth = smaskRaster.getWidth();
            smaskHeight = smaskRaster.getHeight();
            // scale the image to match the image mask.
            if (width < smaskWidth || height < smaskHeight) {
                // calculate scale factors.
                double scaleX = smaskWidth / (double) width;
                double scaleY = smaskHeight / (double) height;
                // scale the mask to match the base image.
                AffineTransform tx = new AffineTransform();
                tx.scale(scaleX, scaleY);
                AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
                BufferedImage bim = op.filter(bi, null);
                bi.flush();
                bi = bim;
            }
            width = bi.getWidth();
            height = bi.getHeight();
        }

        Raster maskRaster = null;
        int maskWidth = 0;
        int maskHeight = 0;
        if (maskImage != null) {
            maskRaster = maskImage.getRaster();
            maskWidth = maskRaster.getWidth();
            maskHeight = maskRaster.getHeight();
        }

        int maskMinRed = 0xFF;
        int maskMinGreen = 0xFF;
        int maskMinBlue = 0xFF;
        int maskMaxRed = 0x00;
        int maskMaxGreen = 0x00;
        int maskMaxBlue = 0x00;
        if (maskMinRGB != null && maskMaxRGB != null) {
            maskMinRed = maskMinRGB[0];
            maskMinGreen = maskMinRGB[1];
            maskMinBlue = maskMinRGB[2];
            maskMaxRed = maskMaxRGB[0];
            maskMaxGreen = maskMaxRGB[1];
            maskMaxBlue = maskMaxRGB[2];
        }

        if (smaskRaster == null && maskRaster == null &&
                (maskMinRGB == null || maskMaxRGB == null)) {
            return null;
        }

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                boolean gotARBG = false;
                int argb = 0;
                int alpha = 0xFF;
                if (y < smaskHeight && x < smaskWidth && smaskRaster != null) {
                    // Alpha equals greyscale value of smask
                    alpha = (smaskRaster.getSample(x, y, 0) & 0xFF);
                } else if (y < maskHeight && x < maskWidth && maskRaster != null) {
                    // When making an ImageMask, the alpha channnel is setup so that
                    //  it both works correctly for the ImageMask being painted,
                    //  and also for when it's used here, to determine the alpha
                    //  of an image that it's masking
                    alpha = (maskImage.getRGB(x, y) >>> 24) & 0xFF; // Extract Alpha from ARGB
                } else {
                    gotARBG = true;
                    argb = bi.getRGB(x, y);
                    int red = ((argb >> 16) & 0xFF);
                    int green = ((argb >> 8) & 0xFF);
                    int blue = (argb & 0xFF);
                    if (blue >= maskMinBlue && blue <= maskMaxBlue &&
                            green >= maskMinGreen && green <= maskMaxGreen &&
                            red >= maskMinRed && red <= maskMaxRed) {
                        alpha = 0x00;
                    }
                }
                if (alpha != 0xFF) {
                    if (!gotARBG)
                        argb = bi.getRGB(x, y);
                    argb &= 0x00FFFFFF;
                    argb |= ((alpha << 24) & 0xFF000000);
                    bi.setRGB(x, y, argb);
                }
            }
        }
        // apply the soft mask.
        BufferedImage tmpImage = bi;
        if (smaskImage != null) {
            BufferedImage argbImage = new BufferedImage(width,
                    height, BufferedImage.TYPE_INT_ARGB);
            int[] srcBand = new int[width];
            int[] sMaskBand = new int[width];
            // iterate over each band to apply the mask
            for (int i = 0; i < height; i++) {
                tmpImage.getRGB(0, i, width, 1, srcBand, 0, width);
                smaskImage.getRGB(0, i, width, 1, sMaskBand, 0, width);
                // apply the soft mask blending
                for (int j = 0; j < width; j++) {
                    sMaskBand[j] = ((sMaskBand[j] & 0xff) << 24)
                            | (srcBand[j] & ~0xff000000);
                }
                argbImage.setRGB(0, i, width, 1, sMaskBand, 0, width);
            }
            tmpImage.flush();
            tmpImage = argbImage;
        }
        return tmpImage;
    }