Package magick4j.effects

Source Code of magick4j.effects.BlurEffect

package magick4j.effects;

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import magick4j.MagickImage;
import magick4j.exceptions.OptionException;

import static java.lang.Math.exp;
import static magick4j.Constants.KernelRank;
import static magick4j.Constants.MagickSQ2PI;
import static magick4j.Constants.magickSigma;
import static magick4j.Constants.OpaqueOpacity;
import static magick4j.Quantum.roundToQuantum;

/**
*
* @author serabe
*/
public class BlurEffect extends BasicEffect{

    private double radius;
    private double sigma;

    public BlurEffect(double radius, double sigma){
        this.radius = radius;
        this.sigma = sigma;
    }

    @Override
    protected MagickImage effect(MagickImage image) throws OptionException {
        int width = this.getOptimalKernelWidth1D(this.radius, this.sigma);
        int halfWidth = width/2;
        int h = image.getHeight(), w = image.getWidth();
        int pw = (w+2*halfWidth), ph = (h+2*halfWidth);
        int base,i,x,y;
        double bias = 0.0;
        double[] kernel = this.getBlurKernel(width);
        double[] p = new double[pw*4];
        double[] q = new double[w*4];
        double[] pixel = new double[4];

        MagickImage blur = image.createCompatible();
        BufferedImage conv = image.expandBorders(0, halfWidth, 0, halfWidth);

        WritableRaster o = conv.getRaster();
        WritableRaster d = blur.getImage().getRaster();

        /*
         * Blur Rows.
         */

        for(y = 0; y < h; y++){

            p = o.getPixels(0, y, pw, 1, p);

            for(x = 0; x < w; x++){
                pixel[0] = pixel[1] = pixel[2] = 0;
                pixel[3] = OpaqueOpacity;

                //TODO Implement Channels.
                for(i = 0; i < width; i++){
                    base = 4*(x+i);
                    pixel[0] += kernel[i]*p[base+0];
                    pixel[1] += kernel[i]*p[base+1];
                    pixel[2] += kernel[i]*p[base+2];
                }

                base = 4*x;

                q[base+0] = roundToQuantum(pixel[0]+bias);
                q[base+1] = roundToQuantum(pixel[1]+bias);
                q[base+2] = roundToQuantum(pixel[2]+bias);
                q[base+3] = 255.0;
            }

            d.setPixels(0, y, w, 1, q);
        }

        /*
         * Blur columns.
         */

        p = new double[ph*4];
        q = new double[h*4];

        o = null;
        conv = null;

        conv = blur.expandBorders(halfWidth, 0, halfWidth, 0);
        o = conv.getRaster();
       
        for(x = 0; x < w; x++){
           
            p = o.getPixels(x, 0, 1, ph, p);
           
            for(y = 0; y < h; y++){
                pixel[0] = pixel[1] = pixel[2] = 0;
                pixel[3] = OpaqueOpacity;

                //TODO Implement Channels.
                for(i = 0; i < width; i++){
                    base = 4*(y+i);
                    pixel[0] += kernel[i]*p[base+0];
                    pixel[1] += kernel[i]*p[base+1];
                    pixel[2] += kernel[i]*p[base+2];
                }

                base = 4*y;

                q[base+0] = roundToQuantum(pixel[0]+bias);
                q[base+1] = roundToQuantum(pixel[1]+bias);
                q[base+2] = roundToQuantum(pixel[2]+bias);
                q[base+3] = 255.0;
            }
           
            d.setPixels(x, 0, 1, h, q);
        }

        return blur;
    }

    public double[] getBlurKernel(int width){
        double[] kernel = new double[width];
        double alpha, normalize;
        double ms = magickSigma(this.sigma);
        double div  = 2.0*KernelRank*KernelRank*ms*ms;
        double div2 = MagickSQ2PI*this.sigma;
       
        int i;

        long bias   =  KernelRank* ((long) width/2);

        for(i = (int) -bias; i <= bias; i++){
            alpha = exp( (-(double) i*i)/((double) div));
            kernel[(int) (((int) (i+bias))/KernelRank)] += alpha/div2;
        }

        normalize = 0.0;

        for(i = 0; i < width; i++)
            normalize += kernel[i];

        for(i = 0; i < width; i++)
            kernel[i] /= normalize;

        return kernel;
    }
}
TOP

Related Classes of magick4j.effects.BlurEffect

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.