Search code examples
androidbitmapimageviewdrawableblur

android programmatically blur imageview drawable


I want to programmatically blur and unblur images in Android.

I hear that android flag "blur" is no longer supported after API 14 , but I wanted to use Java methods anyway. My main problem is manipulating the bitmap from an Imageview drawable.

How would I get the bitmap from an imageview and manipulate it (will probably use gaussian blur) and set it back to the imageview? I think the process involves extracting the drawable, converting the drawable to a bitmap, doing my blur method on that bitmap and then doing the reverse till it is set to the imageview again

but I would like that process spelled out, thank you


Solution

  • Following are the codes for implementing gaussian blur. May this can help you

    import android.graphics.Bitmap;
    import android.graphics.Matrix;
    
    /**
     * @author robert.hinds
     *
     * Wrapper class for the Android Bitmap - used by all filters
     *
     */
    public class AndroidImage {
    
        //original bitmap image
        private Bitmap image;
    
        //format of image (jpg/png)
        private String formatName;
    
        //dimensions of image
        private int width, height;
    
        // RGB Array Color
        protected int[] colourArray;
    
        public AndroidImage(Bitmap img){        
            this.image =  img;
            formatName = "jpg";
            width = img.getWidth();
            height = img.getHeight();
            updateColourArray();
        }
    
    
        /**
         * Method to reset the image to a solid colour
         * 
         * @param color - colour to rest the entire image to
         */
        public void clearImage(int color){
            for(int y=0; y<height; y++){
                for(int x=0; x<width; x++){
                    image.setPixel(x, y, color);
                }
            }
        }
    
    
        /**
         * Set colour array for image - called on initialisation
         * by constructor
         * 
         * @param bitmap
         */
        private void updateColourArray(){
            colourArray = new int[width * height];
            image.getPixels(colourArray, 0, width, 0, 0, width, height);
            int r, g, b;
            for (int y = 0; y < height; y++){
                for (int x = 0; x < width; x++){
                    int index = y * width + x;
                    r = (colourArray[index] >> 16) & 0xff;
                    g = (colourArray[index] >> 8) & 0xff;
                    b = colourArray[index] & 0xff;
                    colourArray[index] = 0xff000000 | (r << 16) | (g << 8) | b;
                }
            }
        }
    
    
        /**
         * Method to set the colour of a specific pixel
         * 
         * @param x
         * @param y
         * @param colour
         */
        public void setPixelColour(int x, int y, int colour){
            colourArray[((y*image.getWidth()+x))] = colour;
            image.setPixel(x, y, colour);
        }
    
        /**
         * Get the colour for a specified pixel
         * 
         * @param x
         * @param y
         * @return colour
         */
        public int getPixelColour(int x, int y){
            return colourArray[y*width+x];
        }
    
        /**
         * Set the colour of a specified pixel from an RGB combo
         * 
         * @param x
         * @param y
         * @param c0
         * @param c1
         * @param c2
         */
        public void setPixelColour(int x, int y, int c0, int c1, int c2){
            colourArray[((y*image.getWidth()+x))] = (255 << 24) + (c0 << 16) + (c1 << 8) + c2;
            image.setPixel(x, y, colourArray[((y*image.getWidth()+x))]);
        }
    
        /**
         * Method to get the RED colour for the specified 
         * pixel 
         * @param x
         * @param y
         * @return colour of R
         */
        public int getRComponent(int x, int y){
            return (getColourArray()[((y*width+x))]& 0x00FF0000) >>> 16;
        }
    
    
        /**
         * Method to get the GREEN colour for the specified 
         * pixel 
         * @param x
         * @param y
         * @return colour of G
         */
        public int getGComponent(int x, int y){
            return (getColourArray()[((y*width+x))]& 0x0000FF00) >>> 8;
        }
    
    
        /**
         * Method to get the BLUE colour for the specified 
         * pixel 
         * @param x
         * @param y
         * @return colour of B
         */
        public int getBComponent(int x, int y){
            return (getColourArray()[((y*width+x))] & 0x000000FF);
        }
    
    
    
        /**
         * Method to rotate an image by the specified number of degrees
         * 
         * @param rotateDegrees
         */
        public void rotate (int rotateDegrees){
            Matrix mtx = new Matrix();
            mtx.postRotate(rotateDegrees);
            image = Bitmap.createBitmap(image, 0, 0, width, height, mtx, true);
            width = image.getWidth();
            height = image.getHeight();
            updateColourArray();
        }
    
    
        /**
         * @return the image
         */
        public Bitmap getImage() {
            return image;
        }
    
    
        /**
         * @param image the image to set
         */
        public void setImage(Bitmap image) {
            this.image = image;
        }
    
    
        /**
         * @return the formatName
         */
        public String getFormatName() {
            return formatName;
        }
    
    
        /**
         * @param formatName the formatName to set
         */
        public void setFormatName(String formatName) {
            this.formatName = formatName;
        }
    
    
        /**
         * @return the width
         */
        public int getWidth() {
            return width;
        }
    
    
        /**
         * @param width the width to set
         */
        public void setWidth(int width) {
            this.width = width;
        }
    
    
        /**
         * @return the height
         */
        public int getHeight() {
            return height;
        }
    
    
        /**
         * @param height the height to set
         */
        public void setHeight(int height) {
            this.height = height;
        }
    
    
        /**
         * @return the colourArray
         */
        public int[] getColourArray() {
            return colourArray;
        }
    
    
        /**
         * @param colourArray the colourArray to set
         */
        public void setColourArray(int[] colourArray) {
            this.colourArray = colourArray;
        }
    
    }
    

    import com.bvise.fotoflipper.core.AndroidImage;
    
    
    
    
    public interface IAndroidFilter {
    
        public AndroidImage process(AndroidImage imageIn);
    }
    
    
    import android.graphics.Bitmap;
    import android.graphics.Color;
    
    public class ConvolutionMatrix
    {
        public static final int SIZE = 3;
    
        public double[][] Matrix;
        public double Factor = 1;
        public double Offset = 1;
    
        public ConvolutionMatrix(int size) {
            Matrix = new double[size][size];
        }
    
        public void setAll(double value) {
            for (int x = 0; x < SIZE; ++x) {
                for (int y = 0; y < SIZE; ++y) {
                    Matrix[x][y] = value;
                }
            }
        }
    
        public void applyConfig(double[][] config) {
            for(int x = 0; x < SIZE; ++x) {
                for(int y = 0; y < SIZE; ++y) {
                    Matrix[x][y] = config[x][y];
                }
            }
        }
    
        public static Bitmap computeConvolution3x3(Bitmap src, ConvolutionMatrix matrix) {
            int width = src.getWidth();
            int height = src.getHeight();
            Bitmap result = Bitmap.createBitmap(width, height, src.getConfig());
    
            int A, R, G, B;
            int sumR, sumG, sumB;
            int[][] pixels = new int[SIZE][SIZE];
    
            for(int y = 0; y < height - 2; ++y) {
                for(int x = 0; x < width - 2; ++x) {
    
                    // get pixel matrix
                    for(int i = 0; i < SIZE; ++i) {
                        for(int j = 0; j < SIZE; ++j) {
                            pixels[i][j] = src.getPixel(x + i, y + j);
                        }
                    }
    
                    // get alpha of center pixel
                    A = Color.alpha(pixels[1][1]);
    
                    // init color sum
                    sumR = sumG = sumB = 0;
    
                    // get sum of RGB on matrix
                    for(int i = 0; i < SIZE; ++i) {
                        for(int j = 0; j < SIZE; ++j) {
                            sumR += (Color.red(pixels[i][j]) * matrix.Matrix[i][j]);
                            sumG += (Color.green(pixels[i][j]) * matrix.Matrix[i][j]);
                            sumB += (Color.blue(pixels[i][j]) * matrix.Matrix[i][j]);
                        }
                    }
    
                    // get final Red
                    R = (int)(sumR / matrix.Factor + matrix.Offset);
                    if(R < 0) { R = 0; }
                    else if(R > 255) { R = 255; }
    
                    // get final Green
                    G = (int)(sumG / matrix.Factor + matrix.Offset);
                    if(G < 0) { G = 0; }
                    else if(G > 255) { G = 255; }
    
                    // get final Blue
                    B = (int)(sumB / matrix.Factor + matrix.Offset);
                    if(B < 0) { B = 0; }
                    else if(B > 255) { B = 255; }
    
                    // apply new pixel
                    result.setPixel(x + 1, y + 1, Color.argb(A, R, G, B));
                }
            }
    
            // final image
            return result;
        }
    }
    

    import android.graphics.Bitmap;
    
    import com.bvise.fotoflipper.core.AndroidImage;
    import com.bvise.fotoflipper.core.ConvolutionMatrix;
    import com.bvise.fotoflipper.filters.IAndroidFilter;
    
    public class GaussianBlur implements IAndroidFilter{
    
        @Override
        public AndroidImage process(AndroidImage imageIn) {
            // TODO Auto-generated method stub
            Bitmap src=imageIn.getImage();
            double[][] GaussianBlurConfig = new double[][] {
                    { 1, 2, 1 },
                    { 2, 4, 2 },
                    { 1, 2, 1 }
                };
                ConvolutionMatrix convMatrix = new ConvolutionMatrix(3);
                convMatrix.applyConfig(GaussianBlurConfig);
                convMatrix.Factor = 200;
                convMatrix.Offset = 0;
                return new AndroidImage(ConvolutionMatrix.computeConvolution3x3(src, convMatrix));
        }
    
    
    }