Drawing a Bitmap to a Canvas with an alpha gradient - java

I'd like to draw a Bitmap on a Canvas, with a (linear) alpha gradient applied. The important point is that I don't want to overlay the image with any other color; the background (coming from the Views behind the View that I'd be drawing this Canvas to) should just "shine through". To illustrate, my goal would be something like this (the checkerboard pattern represents the View behind)
One would think that I could do something like this:
Bitmap bitmap = ...;
Paint paint = new Paint();
paint.setShader(new LinearGradient(0, 0, 100, 0, FROM, TO, Shader.TileMode.CLAMP));
canvas.drawBitmap(bitmap, 0, 0, paint);
but LinearGradient's FROM and TO arguments here would need to be colors, not alpha values; so there's no way that I see to specify that e.g. FROM should be fully transparent and TO should be fully opaque (without applying any color overlay).

use a ComposeShader, like this:
class V extends View {
Bitmap bitmap;
Paint paint = new Paint();
public V(Context context) {
super(context);
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.chrome);
Shader shaderA = new LinearGradient(0, 0, bitmap.getWidth(), 0, 0xffffffff, 0x00ffffff, Shader.TileMode.CLAMP);
Shader shaderB = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(new ComposeShader(shaderA, shaderB, PorterDuff.Mode.SRC_IN));
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
}
}

Based on this answer about masking, I was able to do this using a secondary off-screen canvas:
Bitmap backing = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
{
Canvas offscreen = new Canvas(backing);
offscreen.drawBitmap(bitmap, 0, 0, null);
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
paint.setShader(new LinearGradient(0, 0, 100, 0, 0x00000000, 0xFF000000, Shader.TileMode.CLAMP));
offscreen.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
}
canvas.drawBitmap(backing, 0, 0, null);

Related

Android studio - Center non-transparent part of picture

I'm making an app that can freehand crop a picture using a canvas in android studio. My problem is that after cropping the picture, the cropped part stays in the same exact position as it was originally, whereas i want it to get centered and enlargened. Is there any way to take the non-transparent part and center it, or maybe remove the transparent part all-together?
Screenshot of my app where i want the banana to be centered
https://i.stack.imgur.com/8OKNT.png
Bitmap bitmap;
Path path = new Path();
Paint paint;
int width;
int height;
Rect src;
Rect dest;
public CutImage(Context context, Bitmap bitmap2) {
super(context);
bitmap = bitmap2;
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);
paint.setStrokeWidth(5f);
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();
src = new Rect(0, 0, bitmap.getWidth() - 1, bitmap.getHeight() - 1);
dest = new Rect(0, 0, width - 1, height - 1);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.getHeight();
canvas.drawBitmap(bitmap,src,dest, null);
canvas.drawPath(path, paint);
}
private void crop() {
Bitmap croppedBitmap =
Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),bitmap.getConfig());
Canvas cropCanvas = new Canvas(croppedBitmap);
Paint paint = new Paint();
cropCanvas.drawPath(path,paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
cropCanvas.drawBitmap(bitmap,src,dest,paint);
bitmap = croppedBitmap;
showImage2(bitmap);
}
} ```

android circular image view, adding a border

I have this code, which draws a circular image of the artist currently playing in my android app.
package com.myradio.aacplay;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Paint.Style;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class ImageViewRounded extends ImageView {
public ImageViewRounded(Context context) {
super(context);
}
public ImageViewRounded(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ImageViewRounded(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
BitmapDrawable drawable = (BitmapDrawable) getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap fullSizeBitmap = drawable.getBitmap();
int scaledWidth = getMeasuredWidth();
int scaledHeight = getMeasuredHeight();
Bitmap mScaledBitmap;
if (scaledWidth == fullSizeBitmap.getWidth()
&& scaledHeight == fullSizeBitmap.getHeight()) {
mScaledBitmap = fullSizeBitmap;
} else {
mScaledBitmap = Bitmap.createScaledBitmap(fullSizeBitmap,
scaledWidth, scaledHeight, true /* filter */);
}
// Bitmap roundBitmap = getRoundedCornerBitmap(mScaledBitmap);
// Bitmap roundBitmap = getRoundedCornerBitmap(getContext(),
// mScaledBitmap, 10, scaledWidth, scaledHeight, false, false,
// false, false);
// canvas.drawBitmap(roundBitmap, 0, 0, null);
Bitmap circleBitmap = getCircledBitmap(mScaledBitmap);
canvas.drawBitmap(circleBitmap, 0, 0, null);
}
public Bitmap getRoundedCornerBitmap(Context context, Bitmap input,
int pixels, int w, int h, boolean squareTL, boolean squareTR,
boolean squareBL, boolean squareBR) {
Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final float densityMultiplier = context.getResources()
.getDisplayMetrics().density;
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, w, h);
final RectF rectF = new RectF(rect);
// make sure that our rounded corner is scaled appropriately
final float roundPx = pixels * densityMultiplier;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
// draw rectangles over the corners we want to be square
if (squareTL) {
canvas.drawRect(0, 0, w / 2, h / 2, paint);
}
if (squareTR) {
canvas.drawRect(w / 2, 0, w, h / 2, paint);
}
if (squareBL) {
canvas.drawRect(0, h / 2, w / 2, h, paint);
}
if (squareBR) {
canvas.drawRect(w / 2, h / 2, w, h, paint);
}
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(input, 0, 0, paint);
return output;
}
Bitmap getCircledBitmap(Bitmap bitmap) {
Bitmap result = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
int color = Color.BLUE;
Paint paint = new Paint();
Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
canvas.drawCircle(bitmap.getWidth()/2, bitmap.getHeight()/2, bitmap.getHeight()/2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return result;
}
}
and my xml view code:
<com.radio.myradio.ImageViewRounded
android:id="#+id/imagine"
android:src="#drawable/zupi"
android:layout_width="280dp"
android:layout_height="265dp"
android:layout_gravity="center"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:gravity="center"
android:visibility="gone"/>
It works fine, but my problem is that i can't/don't know how to add a white border to the circular view.
You can try using this CircularImageView I made. It's easy to use and supports custom borders.
Dude here is the solution..
https://github.com/MostafaGazar/CustomShapeImageView
For more detail
https://coderwall.com/p/hmzf4w
Use this library u will find the circular shape in this library and also easy use.
U can also make your custom shape to this library like cloud etc.
this library supports SVG file format and they made the SVG file of Rounded corner Imageview.
Just use and let me know if there is any problem
I faced a similar problem with rounded image , i tried adding background to imageview and giving it padding but it didn't work , so i ended up using RoundedImageView. The usage is pretty simple and it works perfectly
Try to draw circle behinde your Bitmap?
#Override
protected void onDraw(Canvas canvas) {
canvas.drawCircle(0, 0, imageRadius+borderSize, paint);
BitmapDrawable drawable = (BitmapDrawable) getDrawable();
if (drawable == null) {
return;
}
...

How to change buffered image and graphics in android?

I would need to change the Java code to Android.
I'm having the Java code with BufferedImage and Graphics. How should I change the following Java code to Android.
My code is,
public static BufferedImage buff(BufferedImage bi){
if (isGray(bi)){
return bi;
}
BufferedImage gray = new BufferedImage(bi.getWidth(), bi.getHeight(), 10);
Graphics gr = gray.getGraphics();
gr.drawImage(bi, 0, 0, null);
gr.dispose();
return gray;
}
Thanks in advance.
javax.imageio isn't in the Android SDK, but the Bitmap class can be used, if you want convert to gray, you can use this:
public static Bitmap toGrayscale(Bitmap bm) {
Bitmap bmpGrayscale = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bm, 0, 0, paint);
return bmpGrayscale;
}

Android - Custom View Border

I have a simple class, BoundedView that extends View. I'm doing this primarily to mess with the onTouchEvent callback function.
Is there a way to draw a border around each instance of this view, from the class itself? If not, what is the easiest way to implement this?
Implementation:
public class BoundedView extends View
{
public String cellName = "no name";
// constructors are here.
#Override
public void onDraw( Canvas canvas )
{
// maybe here? Right now it's invisible, used only for touch detection
}
#Override
public boolean onTouchEvent( MotionEvent event )
{
Intent i = new Intent( getContext(), TabCellDetails.class );
i.putExtra( "cellName", this.cellName );
getContext().startActivity( i );
return false;
}
}
Using:
<com.lifecoderdev.android.drawing1.BoundedView
android:id="#+id/boundedView1"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="78dp"
android:layout_marginRight="96dp"
android:tag="Smooth Endoplasmic Reticulum"/>
EDIT: This gets me close:
public void onDraw( Canvas canvas )
{
int[] colors = { 0xFF000000, 0xCC000000 };
float[] radii = { 5, 5, 5, 5, 5, 5, 5, 5 };
GradientDrawable drawable = new GradientDrawable( GradientDrawable.Orientation.TOP_BOTTOM, colors );
drawable.setCornerRadii( radii );
drawable.setStroke( 1, 0xFF000000 );
this.setBackgroundDrawable( drawable );
}
However, it is drawing a fully filled in black box, not a transparent one with a black border.
EDIT 2: Got it:
Paint paint = new Paint();
paint.setColor( Color.RED );
paint.setStrokeWidth( 1.0f );
canvas.drawRect( 0, 0, getWidth(), 1.0f, paint );
canvas.drawRect( 0, 0, 1.0f, getHeight(), paint );
canvas.drawRect( 0, getHeight()-1.0f, getWidth(), getHeight(), paint );
canvas.drawRect( getWidth()-1.0f, 0, getHeight(), getWidth(), paint );
EDIT 3: Andreas and Warren's solution was much nicer:
#Override
public void onDraw( Canvas canvas )
{
Paint paint = new Paint();
paint.setColor( Color.RED );
paint.setStrokeWidth( 1.5f );
paint.setStyle( Style.STROKE );
canvas.drawRect( 0, 0, getWidth(), getHeight(), paint );
}
Yes inside your onDraw() is the right place.
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
That should work. If you set the paint variable correctly (stroke width, color) you should see your border.

rounded border around to bitmap

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 am trying use this code for rounding bitmap, but I don't what is Mode.SRC_in and Config.ARGB_8888. I have error with them. What should I do here?
For PorterDuffXfermode, you have to write import android.graphics.PorterDuffXfermode;
For Config.ARGB_8888, you have to write import android.graphics.Bitmap.Config;
Otherwise Direct press CTRL + SHIFT + O to organize imports.
made a oval shape xml name it to round_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<stroke
android:width="1dp"
android:color="#bebebe" />
</shape>
Set this xml to background of image view like below
<ImageView
android:id="#+id/img_profile"
android:layout_width="120dp"
android:layout_height="120dp"
android:padding="2dp"
android:scaleType="fitXY"
android:background="#drawable/round_shape"/>
Now you have round the bitmap and set as imagebitmap resource like this img_profile.setImageBitmap(roundBit(selected_Pic_Bitmap)); , For rounding image bitmap use below code
public Bitmap roundBit(Bitmap bm) {
Bitmap circleBitmap = Bitmap.createBitmap(bm.getWidth(),
bm.getHeight(), Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader(bm, TileMode.CLAMP,
TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(shader);
paint.setAntiAlias(true);
Canvas c = new Canvas(circleBitmap);
c.drawCircle(bm.getWidth() / 2, bm.getHeight() / 2, bm.getWidth() / 2,
paint);
return circleBitmap;
}

Categories

Resources