Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
m-romanuik
Posts: 114
Registered: ‎04-28-2010
My Device: Storm 9530
My Carrier: Telus

Solution to Create Shadows and Blurring Images

Hi Everyone,

 

I've recently been using Graphics.drawFilledPath to produced a background shadow effect. Although this function works flawlessly within JDE5 it does not provide the developer with the ability to apply a linear gradient with an Alpha Channel.

 

After doing some research and several hours of programming I've managed to produced a set of functions that provides a Gaussian Distribution Blur Filter. The function provided allows the user to blur an image with a given radius. It also allows the user to produce shadows.

 

 

/****************************************************************************************
*
* File Name: ImageTools.java
*
* Purpose: Collection of Bitmap Image Processing Tools
*
* Created By: Mitchell Romanuik.
* Date Created: Wednesday December 22, 2010.
* Last Modified: Thursday January 05, 2011.
*
****************************************************************************************/
package program;
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;

/*************************************************************************************
*
* Required by blur() function to process images. This function merely builds a suitable
* data kernel which is in the form of a Gaussian Distribution. This kernel can be
* changed which will result in a different type of blur produced.
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !!!!! THIS IS NOT THREAD SAFE !!!!!!!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* @param radius Radius of Blur
* @return void
*
***************************************************************************************/
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;
}


/*************************************************************************************
*
* Blurs a Given Bitmap with the Option of Alpha Channel PreProcessing
* ** It is recommended that the AlphaChannel is Processed Before Blurring the Image
*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !!!!! THIS IS NOT THREAD SAFE !!!!!!!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* @param image Source Bitmap
* @param left,top Start Position of Blur
* @param width,height Amount of Blur to Produce
* @param isAlpha This is an added feature which blurs only the edges of an
* image. Typically the boundary parameters are the entire
* image (not required).
* @return The Blurred Bitmap in a New Object.
*
***************************************************************************************/
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;
}
}

 

^^ code looks ugly :smileysad:

 

How to Blur an image.

 

 

ImageTools.buildKernel(5);
Bitmap _target = Bitmap.getBitmapResource("firefox.png");
_target = ImageTools.blur(_target, 0, 0, 50, 50, false);

 How to create Shadow.

 

 

// Create Bitmap and Alpha Channel
Bitmap _target = new Bitmap(50, 50);
_target.createAlpha(Bitmap.ALPHA_BITDEPTH_8BPP);
        
// Initialize Alpha Channel
int[] data = new int[50*50];
for(int i=0; i<50*50; i++)
    data[i] = 0x00000000;
        
// Insert Bitmap Data
_target.setARGB(data, 0, 50, 0, 0, 50, 50);
      
// Prepare Drawing Canvas
Graphics canvas = Graphics.create(_target);
 
// Shape Properties
canvas.setColor(0x000000);
canvas.setGlobalAlpha(255);
canvas.fillRoundRect(10, 10, 30, 30, 8, 8);

ImageTools.buildKernel(5);
_target = ImageTools.blur(_target, 0, 0, 50, 50, true);

 

Blur.png

 

*Known Issues: Bitmap.createAlpha() creates funky colors.

 

 

Have fun!

 

Mitchell Romanuik.

Please use plain text.
Developer
peter_strange
Posts: 19,595
Registered: ‎07-14-2008
My Device: Not Specified

Re: Solution to Create Shadows and Blurring Images

Awesome.  Don't have a use for this immediately but thanks for making it available to us!

Please use plain text.
Regular Contributor
jkoorts
Posts: 71
Registered: ‎03-18-2009
My Device: Not Specified

Re: Solution to Create Shadows and Blurring Images

cool! am I free to use it?

Please use plain text.
Developer
m-romanuik
Posts: 114
Registered: ‎04-28-2010
My Device: Storm 9530
My Carrier: Telus

Re: Solution to Create Shadows and Blurring Images

definitely. let me know if anything werid pops up when using it.

Please use plain text.
Contributor
jayachandrap
Posts: 18
Registered: ‎11-10-2010
My Device: Not Specified

Re: Solution to Create Shadows and Blurring Images

Can u plz tell me how to get original image from blurred image??????????????

Please use plain text.
Contributor
jayachandrap
Posts: 18
Registered: ‎11-10-2010
My Device: Not Specified

Re: Solution to Create Shadows and Blurring Images

Can u plz give me the solution for  how to make image sharpwn????????????????

Please use plain text.
Developer
mapleleafs90
Posts: 374
Registered: ‎02-12-2011
My Device: Bold 9780
My Carrier: Wind Mobile

Re: Solution to Create Shadows and Blurring Images

 

Is it possible to use it in conjuction with something like this?
ImageTools.buildKernel(5);
Bitmap _target = ImageTools.createRadialGradientBitmap(Display.getWidth(), Display.getHeight(), 1249564, 3355978, ImageTools.RadialGradientSQRTSqaureDistanceFromBottom, false);
_target = ImageTools.blur(_target, 0, 0, vfm1.getWidth(), vfm1.getHeight(), false);
Background bg = BackgroundFactory.createBitmapBackground(_target);
vfm1.setBackground(bg);

 

 

I am having no luck blurring my background bitmap created from this function.
http://supportforums.blackberry.com/t5/Java-Development/Gradient-Poor-Quality/m-p/780701#M143496

 

It produces this output

 

BLURRED

 

non blurred.png

 

NON BLURRED

blurred.png

 

Basically I want to recreate a similar background to App World.

 

If this doesn't work I am going to have to make seperate png's for all different screen resolutions which sucks.

Please use plain text.
Contributor
jayachandrap
Posts: 18
Registered: ‎11-10-2010
My Device: Not Specified

Re: Solution to Create Shadows and Blurring Images

Can u plz give me solution to how make image sharpen????? plzzzzzzzzzzzzzz

Please use plain text.