Is there a way to put a gradient to a bitmap object in android 2.1? The image must look like this:
I need the gradient only on top of the bitmap. DrawableGradient or LinearGradient are only from android 2.2 so these objects doesn't help me at all. Thanks
Do you need this from XML or from code? In code, try this:
/* Create a 200 x 200 bitmap and fill it with black. */
Bitmap b = Bitmap.createBitmap(200, 200, Config.ARGB_8888);
Canvas c = new Canvas(b);
c.drawColor(Color.BLACK);
/* Create your gradient. */
LinearGradient grad = new LinearGradient(0, 0, 0, 50, Color.GRAY, Color.BLACK, TileMode.CLAMP);
/* Draw your gradient to the top of your bitmap. */
Paint p = new Paint();
p.setStyle(Style.FILL);
p.setShader(grad);
c.drawRect(0, 0, 200, 50, p);
In XML, just make two separate views in a vertical linear layout. The top view should have a gradient drawable background, the bottom, taller view should have a solid background.
Related
I need to apply dynamically a gradient color to a bitmap (it looks like a scratch with some transparent parts) that will be draw over another bitmap: this is the result i need.
This is my code:
Bitmap bitmapbackground = bitmaporiginal.copy(bitmaporiginal.getConfig(), true);
Bitmap bitmaptocolor = BitmapFactory.decodeResource(activity.getResources(), R.drawable.scratch);
LinearGradient gradient = new LinearGradient(0, 0, 0, bitmaptocolor.getHeight(), Color.parseColor("#D81B60"), Color.parseColor("#F48FB1"), Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(gradient);
Canvas canvas = new Canvas(bitmapbackground);
canvas.drawBitmap(bitmaptocolor, 0, 0, paint);
But in this way it does not apply the gradient color to the scratch (it remains always black). What am i doing wrong ?
Make sure bitmaptocolor.getHeight() is actually returning height.
Use hexadecimal equivalent for color.
LinearGradient gradient = new LinearGradient(0, 0, 0, bitmaptocolor.getHeight(), 0xD81B60, 0xD81B60, Shader.TileMode.CLAMP);
So I have the following image to be used as a mask:
Now I want to apply this mask to images so that the image will fill the inner white space but will not fill the borders, keeping it as it is. However, when I use the code below, the image takes the inner white space plus the border.
public static Bitmap applyMask(Bitmap scaledBitmap, Bitmap mask) {
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(scaledBitmap, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
return result;
}
So is there any way to make the image fill only the white space? How can I keep the mask borders intact?
Thanks in advance.
I had to download your image to see the transparent areas. They are on the outside of your shape (which is why DST_IN is the mode that works for this).
What the DST_IN mode does is erases any pixels already on the canvas where the pixels in the mask are transparent. So whether it's the dark border or the white inside, those pixels all have alpha > 0, so they mask the canvas just the same. Those pixels outside the shape have alpha == 0, so they erase the canvas pixels.
Since the final bitmap is the size of your mask, as I see it you have two options:
OPTION 1: If you can put the background color in the mask image:
Change your mask image so that the transparent pixels are inside the shape, and the pixels outside the shape are your background color. Then use SRC_OVER as your xfer mode. The background color outside the border, plus the black border will overwrite the existing pixels in this mode, and since the inner pixels are transparent, the middle part of the image will come through the way you want.
OPTION 2: If you have to specify the background color in the app so you can't put it in the mask image:
For this you'll need two mask images, the one you have and a copy with the inside pixels transparent as well, so you are left with the border. Draw with your mask image the way you are doing right now using DST_IN, then draw the image with just the border using SRC_OVER to draw the border on top of your masked image.
Here you have an example of what you want and you can adapt it to your case:
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = 12;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
I've found it here. Hope it helps! :)
For days I tried to implement a simple Imagebutton in Android, using a dynamic LinearGradient as background. I want the base design from android.R.drawable.btn_default, which is colored starting from the left edge of the button to a value given in percent from v = 0-100%(right edge). The edge between the left and right part of the button should be sharp (like an equalizer). For any suggestions without NullException errors I would be very thankful!
EDIT 29.07.14
Here is the code snippet, working without errors:
Drawable dr = getResources().getDrawable(android.R.drawable.btn_default);
Bitmap bitmap = Bitmap.createBitmap(dr.getIntrinsicWidth(), dr.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
dr.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
dr.draw(canvas);
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY));
paint.setShader(new LinearGradient(0, 0, canvas.getWidth()*7*vol, 0, new int[] { Color.GREEN, Color.TRANSPARENT }, new float[] { 0, 1 }, Shader.TileMode.CLAMP));
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);
mButtonSpeech.setBackground(new BitmapDrawable(getResources(), bitmap));
But even without the middle part of my code, adding the gradient to the canvas, the button background does not look like I expect it (it is to small and in the center not colored like the other buttons, where I set the backgrund by:
mButtonDraw.setBackgroundResource(android.R.drawable.btn_default);
If I also draw the Paint into Canvas, I would expect the default button background, colored in the left part, like I could do it with setColorFilter().
I need to overlay two images in live wallpaper. The overlay images is the jpg which needs to be set to "additive" overlay. it adds the pixel value rather than calculating the transparency. how can i achieve this in android ?
You can make use of Android's Bitmap and Drawable classes mixed with Canvas, and try something like in this snippet:
public static Drawable mergeImage(Drawable orig, Drawable over, int left, int top) {
Bitmap original = ((BitmapDrawable)orig).getBitmap();
Bitmap overlay = ((BitmapDrawable)over).getBitmap();
Bitmap result = Bitmap.createBitmap(original.getWidth(), original.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setAntiAlias(true);
canvas.drawBitmap(original, 0, 0, paint);
canvas.drawBitmap(overlay, left, top, paint);
return new BitmapDrawable(result);
}
I've coded a photo image gridview overlayered with "online status" using the above lines. Hope that it works for you too.
A more general approach may be to create a PorterDuffXfermode with your wanted PorterDuffMode and then set it on the Paint object that you use with your canvas, as referenced in mthama's answer but substituting some lines. This allows you to use other Porter-Duff modes as wanted/needed.
Paint paint = new Paint();
paint.setAntiAlias(true);
canvas.drawBitmap(original, 0, 0, paint);
paint.setXferMode(new PorterDuffXferMode(PorterDuff.Mode.OVERLAY));
canvas.drawBitmap(overlay, left, top, paint);
Mind you, I haven't tried this, so go with mthama's answer. :)
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);
}