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