Monday, January 21, 2013

BlackBerry Blurr a given image


package mypackage;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Graphics;

public class ImageTools
{
    // Variables and Fields
    private static int _radius;
    private static int _kernelSize;
    private static int[] _kernel;
    private static int[][] _productTable;

 
    public static void buildKernel(int radius){
        // Determine if Radius Selected is Valid (Values 64, 128, and 256 are Valid Maxima Values for Radius)
        radius = Math.min(64, Math.max(1, radius));
       
        // Initialize Global Variables
        _radius = radius;
        _kernelSize = 1 + 2*radius;    // This is the range for Pixel Selection
        _kernel= new int[_kernelSize]; // This is a Gaussian Distribution Dictionary
       
        // This is an added Optimization for Embedded Devices (Reduces CPU Stress)
        _productTable = new int[_kernelSize][256];

        // Augment Values of Gaussian Curve Excluding Radius Pixel
        for(int i=1; i<radius; i++){
            // Initialize Temp Variables
            int increment = radius - i;
           
            // Gaussian Curve is Symmetric
            _kernel[radius+i] = _kernel[increment] = increment*increment;
           
            // Produce Product Table for 'each' Pixel Color 0-255
            for(int j=0; j<256; j++)
                _productTable[radius+i][j] = _productTable[increment][j] = _kernel[increment]*j;
        }
       
        // Augment Values of Gaussian Curve for Radius Pixel
        _kernel[radius] = radius*radius;
        for(int j=0; j<256; j++)
            _productTable[radius][j] = _kernel[radius]*j;
    }


 
    public static Bitmap blur(Bitmap image, int left, int top, int width, int height, boolean isAlpha){
        // Determine Bitmap Properties
        int imgWidth = image.getWidth();
        int imgHeight = image.getHeight();
        int numPixels = width*height; // Only select the Region Size (Optimization)
       
        // Check Image if Alpha Channel Exists
        if(!image.hasAlpha() && isAlpha)
            isAlpha = false;
       
        // Determine Region to Blur on 'image'
        int topYAxis = 0;
        top = Math.min(imgHeight, Math.max(0, top));
        left = Math.min(imgWidth, Math.max(0, left));
        width = Math.min(imgWidth, Math.max(0, width));
        height = Math.min(imgHeight, Math.max(0, height));
       
        // Obtain Bitmap Pixels in ARGB from that Region
        int[] data = new int[numPixels];
        image.getARGB(data, 0, width, top, left, width, height); // Obtain pixel data from 'image' only the Region Specified
       
        // Separate Color Channels
        int a[] = new int[numPixels];
        int r[] = new int[numPixels];
        int g[] = new int[numPixels];
        int b[] = new int[numPixels];
        for(int i=0; i<numPixels; i++){
            // Initialize Temp Variables
            int pixel = data[i];
            if(isAlpha)
                a[i] = Math.abs((pixel&0xFF000000)>>24);
            r[i] = (pixel&0x00FF0000)>>16;
            g[i] = (pixel&0x0000FF00)>>8;
            b[i] = (pixel&0x000000FF);
        }

        // Clone Array(s) of Color Channels
        int a2[] = new int[numPixels];
        int r2[] = new int[numPixels];
        int g2[] = new int[numPixels];
        int b2[] = new int[numPixels];

        // Produce Clone of Bitmap with Horizontal Blurring
        for(int y=0; y<height; y++){
            for(int x=0; x<width; x++){
                // Initialize Temp Variables
                int alphaChannel=0, redChannel=0, greenChannel=0, blueChannel=0, summation=0;
                int pixel = x - _radius;

                // Collect RGB Data from the range [radius-x, radius+x]
                for(int i=0; i<_kernelSize; i++){
                    // Initialize Temp Variables
                    int tmpPixel = pixel + i;
                   
                    // Determine if Selected Pixel is within Boundary
                    if(tmpPixel >= 0 && tmpPixel < width){
                        // Collect RGB or Alpha Data over Radius
                        tmpPixel += topYAxis;
                        if(!isAlpha){
                            redChannel += _productTable[i][r[tmpPixel]];
                            greenChannel += _productTable[i][g[tmpPixel]];
                            blueChannel += _productTable[i][b[tmpPixel]];
                        }
                        else
                            if(a[tmpPixel] != 0)
                                alphaChannel += _productTable[i][255];

                        // Increase Color Average
                        summation += _kernel[i];
                    }
                }
                // Store Processed Data into Clone Array(s)
                if(isAlpha)
                    a2[x+topYAxis] = alphaChannel/summation;
                else{
                    r2[x+topYAxis] = redChannel/summation;
                    g2[x+topYAxis] = greenChannel/summation;
                    b2[x+topYAxis] = blueChannel/summation;
                }
            }  
            // Set New Data Position for Pixel Array
            topYAxis += width;
        }

        // Produce Clone of Bitmap with Vertical Blurring
        for(int x=0; x<width; x++){
            for(int y=0; y<height; y++){
                // Initialize Temp Variables
                int alphaChannel=0, redChannel=0, greenChannel=0, blueChannel=0, summation=0;
                int pixel = y - _radius;

                // Collect RGB Data from the range [radius-y, radius+y]
                for(int i=0; i<_kernelSize; i++){
                    // Initialize Temp Variables
                    int tmpPixel = (pixel + i)*width + x;
                   
                    // Determine if Selected Pixel is within Boundary
                    if(tmpPixel < numPixels && tmpPixel >= 0){
                        // Collect RGB or Alpha Data over Radius
                        if(!isAlpha){
                            redChannel += _productTable[i][r2[tmpPixel]];
                            greenChannel += _productTable[i][g2[tmpPixel]];
                            blueChannel += _productTable[i][b2[tmpPixel]];
                        }
                        else
                            if(a[tmpPixel] != 0)
                                alphaChannel += _productTable[i][a2[tmpPixel]];
                               
                        // Increase Color Average
                        summation += _kernel[i];
                    }
                }
                // Recombine Color Channels with Full Opacity
                if(isAlpha)
                    data[x+y*width] =  (alphaChannel/summation)<<24 | r[x+y*width]<<16 | g[x+y*width]<<8 | b[x+y*width];
                else
                    data[x+y*width] =  0xFF000000 | (redChannel/summation)<<16 | (greenChannel/summation)<<8 | (blueChannel/summation);
            }
        }
       
        // Replace 'image' Data with PreProcessed Data
        image.setARGB(data, 0, width, top, left, width, height);
        return image;
    }
}


the above given class can be used as follows

Bitmap _target = Bitmap.getBitmapResource("icon.png");
_target = ImageTools.blur(_target, 0, 0, 50, 50, true);

BitmapField bftemp111 = new BitmapField(_target,
BitmapField.NON_FOCUSABLE | BitmapField.FIELD_HCENTER
| BitmapField.FIELD_VCENTER);
add(bftemp111);

No comments:

Post a Comment