how to make outer glow effect around a bitmap? - android

I created glow effect for my bitmap imageview. Its working but I have porblem with my outer glow color.
This is my expected design outer glow color:
http://www.flashcomponents.net/component/professional-3d-carousel-as2-and-as3.html please see the link
but my glow effect not looking good please help me how make expected glow effect?
This is my code:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int margin = 24;
int halfMargin = margin / 2;
// the glow radius
int glowRadius = 16;
// the glow color
int glowColor = Color.rgb(0, 192, 255);
// The original image to use
Bitmap src = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
// extract the alpha from the source image
Bitmap alpha = src.extractAlpha();
// The output bitmap (with the icon + glow)
Bitmap bmp = Bitmap.createBitmap(src.getWidth() + margin,
src.getHeight() + margin, Bitmap.Config.ARGB_8888);
// The canvas to paint on the image
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
paint.setColor(glowColor);
// outer glow
paint.setMaskFilter(new BlurMaskFilter(glowRadius, Blur.OUTER));
canvas.drawBitmap(alpha, halfMargin, halfMargin, paint);
// original icon
canvas.drawBitmap(src, halfMargin, halfMargin, null);
((ImageView) findViewById(R.id.bmpImg)).setImageBitmap(bmp);
}
}
I am new for android i need programmatically only.....
expected glow in my backside of the imageview please see my expected screen shot:

Related

Android imageView with checkeredBackground and different size images ontop

Background
I have an ImageView which is used to display previews of a file.
I would like to have the ImageView with a checkerboard background, so that when a file with transparency is rendered on top (such as PNG and SVG files) the checkerboard shows through on the transparent parts.
I have found lots of questions on StackOverflow on how to create the checkered background and this question is not entirely specific to that.
I am currently doing it in code. I create a 2 by 2 bitmap (top left/bottom right are one colour, top right, bottom left are the other colour) where the size of each box is specified. Then i create the main bitmap by drawing this small bitmap repeatedly.
int checkeredBackgroundSquareSize= 16;
private static Bitmap getCheckeredBitmap(int size) {
size = (size > 0) ? size : DEFAULT_SQUARE_SIZE;
int colorOne = ContentApplication.appCtx().getColor(R.color.checkerboard_background_color_one);
int colorTwo = ContentApplication.appCtx().getColor(R.color.checkerboard_background_color_two);
// width/height is twice the size of the individual squares
Bitmap squareBitmap = Bitmap.createBitmap(size*2, size*2, Bitmap.Config.ARGB_8888);
Paint bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bitmapPaint.setStyle(Paint.Style.FILL);
Canvas canvas = new Canvas(squareBitmap);
// draw 2 rectangles on 2 rows
// top left and bottom right are the first colour
// top right and bottom left are the second colour
// set colour for top left/bottom right squares
bitmapPaint.setColor(colorOne);
// Square 1 : top left
Rect rect = new Rect(0, 0, size, size);
canvas.drawRect(rect, bitmapPaint);
// Square 2 : bottom right
rect.offset(size, size);
canvas.drawRect(rect, bitmapPaint);
// change colour for top right/bottom left squares
bitmapPaint.setColor(colorTwo);
// Square 3 : top right
rect.offset(-size, 0);
canvas.drawRect(rect, bitmapPaint);
// Square 4: bottom left
rect.offset(size, -size);
canvas.drawRect(rect, bitmapPaint);
return squareBitmap;
}
I then create a Bitmap the size of my preview image, and use the checkered background bitmap to repeatedly draw on the canvas before the preview image is added on top.
// Create a Bitmap to render our SVG to
Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
// Create a Canvas to use for rendering
Canvas canvas = new Canvas(bitmap);
// If we don't specify a viewport box, then AndroidSVG will use the bounds of the Canvas
// as the viewport. So a scale of 1.0 corresponds to that size
canvas.scale(scaling,scaling );
// create the checkered background, indicating transparency
Bitmap square = getCheckeredBitmap(checkeredBackgroundSquareSize);
BitmapShader shader = new BitmapShader(square, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
Paint paint = new Paint();
paint.setShader(shader);
// in your draw method
canvas.drawRect(0, 0, bitmapWidth, bitmapHeight, paint);
The issue
My previews can be different sizes, for example 100x100, 6000x2000 etc As i am creating the initial bitmap on these sizes, the final image for the files all render looking like the squares on the checkered background are different sizes.
I need to have the checkerboard look exactly the same regardless of the overlaid image's size.
Is there a way to set a background image for an ImageView to be an image. I can only see how to set it to a drawable and I can not see how to define a checkboard as an xml drawable.
Mike M gave the answer that solved my issue. See Mike's comments to the first post
Create your own Drawable that renders the checkerboard
public class CheckerboardDrawable extends Drawable {
// I inadvertently ran the example image with Paint.ANTI_ALIAS_FLAG, but
// we actually don't want that 'cause we're looking for crisp, clean lines.
private final Paint paint = new Paint();
private int checkeredBackgroundSquareSize = 16;
private int colorOne = Color.LTGRAY;
private int colorTwo = Color.WHITE;
#Override
public void draw(#NonNull Canvas canvas) {
final Rect bounds = getBounds();
final int squareSize = checkeredBackgroundSquareSize;
final int columns = bounds.width() / squareSize + 1;
final int rows = bounds.height() / squareSize + 1;
canvas.translate(bounds.left, bounds.top);
for (int c = 0; c < columns; c++) {
for (int r = 0; r < rows; r++) {
paint.setColor((c + r) % 2 == 0 ? colorOne : colorTwo);
final int x = c * squareSize;
final int y = r * squareSize;
canvas.drawRect(x, y, x + squareSize, y + squareSize, paint);
}
}
canvas.translate(-bounds.left, -bounds.top);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public void setAlpha(int alpha) {}
#Override
public void setColorFilter(#Nullable ColorFilter colorFilter) {}
}
Then add the drawable to the ImageView
final ImageView imageView = findViewById(R.id.image);
imageView.setBackground(new CheckerboardDrawable());

Android how to apply mask on ImageView?

So I tried the code from here: Creating an ImageView with a mask. I'm using the following images as original and mask:
However, the result I get is this:
Note that the window background is not black, but holo light (which on the galaxy nexus looks like a very pale gray, not completely white). The second image is the result I get when an item is selected on a list view.
If instead I create a new Bitmap using the same algorithm and then pass it to the image view instead of overriding onDraw(), it draws correctly:
Canvas canvas = new Canvas();
Bitmap mainImage = //get original image
Bitmap maskImage = //get mask image
Bitmap result = Bitmap.createBitmap(mainImage.getWidth(), mainImage.getHeight(), Bitmap.Config.ARGB_8888);
canvas.setBitmap(result);
Paint paint = new Paint();
paint.setFilterBitmap(false);
canvas.drawBitmap(mainImage, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(maskImage, 0, 0, paint);
paint.setXfermode(null);
imageView.setImageBitmap(result);
I get the expected result:
Note the fade is correctly applied. This is more evident when a selection is made.
So what's going on on ImageView's onDraw method to create this black backdrop instead of letting the window background show through? What's interesting is that if the original image itself has some transparency, that transparency is respected, for example:
I can't figure it out by myself. I'd rather be able to do it on onDraw instead of pre-creating the bitmap because it only works for bitmaps as source and mask. I want to be able to do it with other drawables like gradients and solid colours but on those cases the width and height are not set.
I have found the perfect combination for creating masking without black border after researching through all the stackoverflow posts. It suits my purpose quite well.
Currently I'm creating a draggable view using one normal image and a masking image (a png with transparency), so I'll need to override the onDraw function.
private Bitmap mImage = ...;
private Bitmap mMask = ...; // png mask with transparency
private int mPosX = 0;
private int mPosY = 0;
private final Paint maskPaint;
private final Paint imagePaint;
public CustomView (final Context context) {
maskPaint = new Paint();
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
imagePaint = new Paint();
imagePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
}
/* TODO
if you have more constructors, make sure you initialize maskPaint and imagePaint
Declaring these as final means that all your constructors have to initialize them.
Failure to do so = your code won't compile.
*/
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.drawBitmap(mMask, 0, 0, maskPaint);
canvas.drawBitmap(mImage, mPosX, mPosY, imagePaint);
canvas.restore();
}
Answering my own question. The Xfermode was working as intended. The paint was making the resulting are of the canvas transparent (which was the canvas used by the window activity). Since the canvas itself was being set transparent, the window was showing what was behind it: the black background.
To do it properly, indeed a new Bitmap has to be created to hold the result of the alpha mask. I updated the code to take into account drawables of all types.
In this Code Apply:
mask_over = BitmapFactory.decodeResource(
getResources(), mask_over1[0]);
icon = Bitmap.createScaledBitmap(icon, screenwidth, screenwidth, false);
mask_over = Bitmap.createScaledBitmap(mask_over, screenwidth, screenwidth, false);
back_img=createBitmap_ScriptIntrinsicBlur(Bitmap.createScaledBitmap(cropview.croppedImage, screenwidth, screenwidth, false),25.0f);
LinearLayout.LayoutParams layoutParams111 = new LinearLayout.LayoutParams(screenwidth, screenwidth);

how to hide glow effect?

Glow effect is working fine. my doubt is how to hide glow effect? if i click my imageview, that time only i wish to show my glow effect please how to hide and show glow effect while on click.
code:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// An added margin to the initial image
int margin = 24;
int halfMargin = margin / 2;
// the glow radius
int glowRadius = 16;
// the glow color
int glowColor = Color.rgb(0, 192, 255);
// The original image to use
Bitmap src = BitmapFactory.decodeResource(getResources(),
R.drawable.test);
// extract the alpha from the source image
Bitmap alpha = src.extractAlpha();
// The output bitmap (with the icon + glow)
Bitmap bmp = Bitmap.createBitmap(src.getWidth() + margin,
src.getHeight() + margin, Bitmap.Config.ARGB_8888);
// The canvas to paint on the image
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
paint.setColor(glowColor);
// outer glow
paint.setMaskFilter(new BlurMaskFilter(glowRadius, Blur.OUTER));
canvas.drawBitmap(alpha, halfMargin, halfMargin, paint);
// original icon
canvas.drawBitmap(src, halfMargin, halfMargin, null);
setContentView(R.layout.activity_main);
((ImageView) findViewById(R.id.bmpImg)).setImageBitmap(bmp);
}
}
present screen shot:
set onclicklistener and implement this code:
.setOnClickListener(clicklistener);
private OnClickListener backListener = new OnClickListener() {
public void onClick(View v) {
// An added margin to the initial image
int margin = 24;
int halfMargin = margin / 2;
// the glow radius
int glowRadius = 16;
// the glow color
int glowColor = Color.rgb(0, 192, 255);
// The original image to use
Bitmap src = BitmapFactory.decodeResource(getResources(),
R.drawable.test);
// extract the alpha from the source image
Bitmap alpha = src.extractAlpha();
// The output bitmap (with the icon + glow)
Bitmap bmp = Bitmap.createBitmap(src.getWidth() + margin,
src.getHeight() + margin, Bitmap.Config.ARGB_8888);
// The canvas to paint on the image
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
paint.setColor(glowColor);
// outer glow
paint.setMaskFilter(new BlurMaskFilter(glowRadius, Blur.OUTER));
canvas.drawBitmap(alpha, halfMargin, halfMargin, paint);
// original icon
canvas.drawBitmap(src, halfMargin, halfMargin, null);
}}
you can set null for setMaskFilter() like this way
paint.setMaskFilter(null);
and you need just set paint.setMaskFilter(new BlurMaskFilter(glowRadius, Blur.OUTER));
for this you need keep paint object for application scope so this paint object can accessing out in another class or activity wherever you want or you can set flag for true then show glow effect and false the flag set nothing (as default)
An easier way to do this would be to use StateListDrawable.
Create two images - one for normal state and one for pressed state (with glow). Use this in the res/drawable/button_drawable.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="#drawable/image_normal"
android:state_enabled="true"/>
<item
android:drawable="#drawable/image_pressed"
android:state_pressed="true"/>
</selector>
and use it as the buttom drawable:
((ImageView) findViewById(R.id.bmpImg)).setImageDrawable(getResources().getDrawable(R.drawable.button_drawable));

how to add alpha channel to bitmap

My code is below. It is exactly the same code as found in the solution for this question: Make certain area of bitmap transparent on touch
And as many others I am having the same problem with this code: the circle comes out black.
I am using a PNG file as my overlay, and this file does not have any transparent areas. But as soon as I add an arbitrary transparent area to the PNG in the Photoshop, the code starts working and the circle is displayed as transparent.
Apparently, there is something with the image and how its transparency is set, but I do not know what. I need to use a PNG without any transparent areas as my overlay.
any advice?
EDIT: good code must not depend on whether the overlay image has transparency or not, I am looking for a way to handle any kind of image as my overlay, be it JPG, PNG, or something else.
EDIT 2: if I use Config.ARGB_4444 when copying my bitmap, alpha channel gets created but this format reduces the image quality. There is API Bitmap.setHasAlpha() for API level 11 and above but I am using level 10 so far.
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new TouchView(this));
}
class TouchView extends View {
Bitmap bgr;
Bitmap overlayDefault;
Bitmap overlay;
Paint pTouch;
int X = 100;
int Y = 100;
Canvas c2;
public TouchView(Context context) {
super(context);
bgr = BitmapFactory.decodeResource(
getResources(),
R.drawable.background);
overlay = BitmapFactory.decodeResource(
getResources(),
R.drawable.foreground)
.copy(Config.ARGB_8888, true);
c2 = new Canvas(overlay);
pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);
pTouch.setXfermode(
new PorterDuffXfermode(Mode.SRC_OUT));
pTouch.setColor(Color.TRANSPARENT);
}
#Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
//draw background
canvas.drawBitmap(bgr, 0, 0, null);
//copy the default overlay
// into temporary overlay and punch a hole in it
//c2.drawBitmap(overlayDefault, 0, 0, null);
c2.drawCircle(X, Y, 80, pTouch);
//draw the overlay over the background
canvas.drawBitmap(overlay, 0, 0, null);
}
}
}
From http://blog.uncommons.org/2011/01/12/adjusting-the-opacity-of-an-android-bitmap/
**
* #param bitmap The source bitmap.
* #param opacity a value between 0 (completely transparent) and 255 (completely opaque).
* #return The opacity-adjusted bitmap. If the source bitmap is mutable it will be
* adjusted and returned, otherwise a new bitmap is created.
*/
private Bitmap adjustOpacity(Bitmap bitmap, int opacity)
{
Bitmap mutableBitmap = bitmap.isMutable()
? bitmap
: bitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
int colour = (opacity & 0xFF) << 24;
canvas.drawColor(colour, PorterDuff.Mode.DST_IN);
return mutableBitmap;
}
Note that the Bitmap.Config documentation for ARGB_4444 says:
This field was deprecated in API level 13. Because of the poor quality
of this configuration, it is advised to use ARGB_8888 instead.

Android Circular Gradient Alpha Mask

Is there a way to draw a circular gradient mask on a bitmap in Android? Trying to produce something similar to a foggy window. Click the window and a transparent circle shows up revealing whats behind the window. Prefferably using a gradient so the center of the circle is completely transparent and the further out from the center the less transparent. Is this possible?
I'm new to Android so any code samples would be appreciated.
Thanks.
private void drawFoggyWindowWithTransparentCircle(Canvas canvas,
float circleX, float circleY, float radius) {
// Get the "foggy window" bitmap
BitmapDrawable foggyWindow =
(BitmapDrawable) getResources().getDrawable(R.drawable.foggy_window);
Bitmap foggyWindowBmp = foggyWindow.getBitmap();
// Create a temporary bitmap
Bitmap tempBitmap = Bitmap.createBitmap(
foggyWindowBmp.getWidth(),
foggyWindowBmp.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas tempCanvas = new Canvas(tempBitmap);
// Copy foggyWindowBmp into tempBitmap
tempCanvas.drawBitmap(foggyWindowBmp, 0, 0, null);
// Create a radial gradient
RadialGradient gradient = new android.graphics.RadialGradient(
circleX, circleY,
radius, 0xFF000000, 0x00000000,
android.graphics.Shader.TileMode.CLAMP);
// Draw transparent circle into tempBitmap
Paint p = new Paint();
p.setShader(gradient);
p.setColor(0xFF000000);
p.setXfermode(new PorterDuffXfermode(Mode.DST_OUT));
tempCanvas.drawCircle(circleX, circleY, radius, p);
// Draw tempBitmap onto the screen (over what's already there)
canvas.drawBitmap(tempBitmap, 0, 0, null);
}

Categories

Resources