We can easily make a background transparent & colored element with Shape like this :
Color bleue : Solid color
white/gray square : transparent
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners
android:radius="20dp"/>
<solid
android:color="#1f93ed" />
</shape>
But how can i do a view background with colored back and transparent element like this :
as if the background color was holed by form...
Any idea?
You can draw yourself colored area with override of onDraw in custom drawable or view.
For exemple, in this code i draw four "corner outline" :
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
drawCorner(cornerSizeInPixel, canvas, Color.GREEN));
}
private void drawCorner(int size, Canvas canvas, int color)
{
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(color);
paint.setStyle(Style.FILL);
// top left
Path p = new Path();
p.moveTo(0, 0);
p.lineTo(size, 0);
p.arcTo(new RectF(0, 0, size, size), 180, 90, true);
p.lineTo(0, 0);
canvas.drawPath(p, paint);
// bottom left
int h = canvas.getHeight();
p = new Path();
p.moveTo(0, h);
p.lineTo(size, h);
p.arcTo(new RectF(0, h - size, size, h), 90, 90, true);
p.lineTo(0, h);
canvas.drawPath(p, paint);
// top right
int w = canvas.getWidth();
p = new Path();
p.moveTo(w, 0);
p.lineTo(w - size, 0);
p.arcTo(new RectF(w - size, 0, w, size), 270, 90, true);
p.lineTo(w, 0);
canvas.drawPath(p, paint);
// bottom right
p = new Path();
p.moveTo(w, h);
p.lineTo(w - size, h);
p.arcTo(new RectF(w - size, h - size, w, h), 0, 90, true);
p.lineTo(w, h);
canvas.drawPath(p, paint);
}
Result: 4 green form in every corner of the image, which together draw a rounded rectangle really transparent
option 1: use normal .png file
option 2: create a custom Drawable by extending ShapeDrawable class
Replace android:color="#1f93ed" with android:color="#android:color/transparent and set the background to the Blue colour
Related
I want to apply a gradient to a bitmap. So far I'm using this technique.
here is my code in the onCreate method of MainActivity.class.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
double angle = Math.toRadians(135);
double length = 100;
int x = (int) (Math.cos(angle) * length);
int y = (int) (Math.sin(angle) * length);
int[] colors = new int[3];
colors[0] = Color.parseColor("#FF4081");
colors[1] = Color.parseColor("#3F51B5");
Bitmap bitmap = Bitmap.createBitmap(1080, 1080, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
LinearGradient linearGradient =
new LinearGradient(0, 0, x, y, colors[1], colors[0], Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setDither(true);
paint.setShader(linearGradient);
canvas.drawRect(new RectF(0, 0, 1080, 1080), paint);
ImageView imageView = findViewById(R.id.iv);
imageView.setImageBitmap(bitmap);
}
}
which results in this
but I want to get an effect like this
image 2 results were achieved by simply creating a drawable XML file with the following code
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="45"
android:endColor="#color/colorPrimary"
android:startColor="#color/colorAccent" />
</shape>
and setting it as a background for an ImageView, but I want this effect on the bitmap because I want to save that bitmap locally as an Image. I have tried creating a GradientDrawable instance in the MainActivity and calling onDraw(canvas) on the GradientDrawable as mentioned in the post
As I see, you calculated the angle incorrect.
Instead of this
LinearGradient linearGradient =
new LinearGradient(0, 0, x, y, colors[1], colors[0], Shader.TileMode.CLAMP);
Use this
LinearGradient linearGradient =
new LinearGradient(1080, 0, 0, 1080, colors[1], colors[0], Shader.TileMode.CLAMP);
x0 is gradient start X, y0 is gradient start Y, x1 is gradient end X and y1 is gradient end Y.
Hope I helped you.
I have set a rounded image view Rounded image view and i don't know how to set a background color for it .I had tried set background method to fill the color in the image.
public Bitmap roundCornerImage(Bitmap raw, float round) {
int width = raw.getWidth();
int height = raw.getHeight();
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
canvas.drawARGB(0, 0, 0, 0);
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.parseColor("#000000"));
final Rect rect = new Rect(0, 0, width, height);
final RectF rectF = new RectF(rect);
canvas.drawRoundRect(rectF, round, round, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(raw, rect, rect, paint);
return result;
}
canvas.drawARGB(0, 0, 0, 0)
This line will draw a canvas of black color. If you just want to change the color, change the rgb values. For e.g
canvas.drawARGB(255, 0, 0, 0)
will draw a red color bitmap canvas.
ImageView imageView = (ImageView) findViewById(imageViewId);
// Set the background for the ImageView
imageView.setBackgroundResource(R.drawable.yourdrawableImage);
// set background color
backgroundImg.setBackgroundColor(Color.parseColor("#FFFFFF"));
setBackgroundColor(Color.rgb(100, 100, 50));
Or else change the background color of parent layout.
Pulling my hear out over this one. I have a background bitmap that I want to overlay another bitmap on top of that has transparent cutouts. I have no problem doing that if the cutout is a basic shape, but I need the cutout to be the intersection of two circles (sort of a leaf shape). I tried making a third bitmap to produce the a cutout template but I can't even get a clean representation of the cutout let alone get it to work as a cutout template.
Anyone know how to do something like this? Here is my (simplified) attempt:
#Override
public void draw(Canvas canvas) {
float w = canvas.getWidth();
float h = canvas.getHeight();
// just used to set some proportions
float off = 300f;
Paint paint = new Paint();
// make a background bitmap with a yellow to green gradient
Bitmap bitmapBkg = Bitmap.createBitmap((int) w, (int) h, Bitmap.Config.ARGB_8888);
Canvas canvasBkg = new Canvas(bitmapBkg);
paint.reset();
paint.setShader(new LinearGradient(0, h/2 - off, 0, h/2 + off, Color.YELLOW, Color.GREEN, Shader.TileMode.CLAMP));
canvasBkg.drawRect(new RectF(0, 0, w, h), paint);
// make an overlay bitmap with a red to magenta gradient which will have the cutouts
Bitmap bitmapOver = Bitmap.createBitmap((int) w, (int) h, Bitmap.Config.ARGB_8888);
Canvas canvasOver = new Canvas(bitmapOver);
paint.reset();
paint.setShader(new LinearGradient(0, h/2 - off, 0, h/2 + off, Color.RED, Color.MAGENTA, Shader.TileMode.CLAMP));
canvasOver.drawRect(new RectF(0, 0, w, h), paint);
// make a bitmap of intersecting circles to be used as the cutout shape
Bitmap bitmapCut = Bitmap.createBitmap((int) w, (int) h, Bitmap.Config.ARGB_8888);
Canvas canvasCut = new Canvas(bitmapCut);
paint.reset();
paint.setColor(Color.BLACK);
//paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
canvasCut.drawCircle(w / 2 - (off / 2 ), h / 2, off, paint);
paint.reset();
paint.setColor(Color.BLACK);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
canvasCut.drawCircle(w / 2 + (off / 2), h / 2, off, paint);
// apply cutout to overlay
paint.reset();
paint.setColor(Color.BLACK);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
canvasOver.drawBitmap(bitmapCut, 0, 0, paint);
// draw background and overlay onto main canvas
paint.reset();
paint.setColor(Color.BLACK);
canvas.drawBitmap(bitmapBkg, 0, 0, paint);
canvas.drawBitmap(bitmapOver, 0, 0, paint);
}
Here is an image of what I am getting:
What I am trying to get would have the outside portion also red-magenta; only the eye-shape in the middle should be yellow-green.
Turns out the trick was adding yet another layer.
// make a secondary overlay that cuts out the whole circles
Bitmap bitmapOver2 = Bitmap.createBitmap((int) w, (int) h, Bitmap.Config.ARGB_8888);
Canvas canvasOver2 = new Canvas(bitmapOver2);
paint.reset();
paint.setShader(new LinearGradient(0, h / 2 - off, 0, h / 2 + off, Color.RED, Color.MAGENTA, Shader.TileMode.CLAMP));
canvasOver2.drawRect(new RectF(0, 0, w, h), paint);
paint.reset();
paint.setColor(Color.BLACK);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvasOver2.drawCircle(w / 2 - (off / 2), h / 2, off, paint);
canvasOver2.drawCircle(w / 2 + (off / 2), h / 2, off, paint);
Applying it like so:
// draw background and overlay onto main canvas
paint.reset();
paint.setColor(Color.BLACK);
canvas.drawBitmap(bitmapBkg, 0, 0, paint);
canvas.drawBitmap(bitmapOver2, 0, 0, paint);
canvas.drawBitmap(bitmapOver, 0, 0, paint);
Basically it is a bit of a trick. It draws the mid-tier backdrop twice, once with a full circle cutouts and the other with the eye-shape cutout. The two fit together just right to pull off the desired effect.
Of course #Rotwang, you are probably right. Using Path and arcTo() would be a much better solution. The only reason I avoided that approach is b/c arcTo() is an api 21+ feature. So far I've manged to keep the api to 17+. But if anyone else would like to provide an arcTo() solution for completeness that would be cool to compare.
I'm trying to draw a half circle inside the ImageView but i can't control where draw it. The idea is to draw it inside another circle with another color using drawcircle (50, 50, 20, paint). This is the code i'm using:
<ImageView android:id="#+id/circle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10sp" />
Bitmap bmp = Bitmap.createBitmap(100, 70, Bitmap.Config.RGB_565);
ImageView circle = (ImageView) findViewById (R.id.circle);
Paint paint = new Paint();
paint.setColor(Color.RED);
Canvas canvas = new Canvas (bmp);
RectF rectf = new RectF (0, 0, 40, 40);
canvas.drawArc(rectf, 0, 180, true, paint);
Thanks.
I think the problem you are having is: you do not understand the two different representations that is used by Circle and Arc.
For Circle, you need to give it the x, y position of the center, and the radius.
but for the Arc, you need the 4 edges of the container.
so it should look something like this:
//setting for Circle
paint.setColor(Color.RED);
int xPosition=50;
int yPosition=50;
int size = 40;
canvas.drawCircle(xPosition, yPosition, size/2, paint);
//setting for Arc
paint.setColor(Color.YELLOW);
size = size * 8 / 10; // make the Arc smaller
xPosition=xPosition-size/2;
yPosition=yPosition-size/2;
RectF rectf = new RectF (xPosition, yPosition, xPosition+size, yPosition+size);
canvas.drawArc(rectf, 0+45, 180, true, paint);
i am able to draw arc using Paint and passing some gradient color to it, my problem is that i need draw the arc using a gradient image.Is it possible to draw arc using an image?
If so how to do it?
this is my current code:
Paint nPaint = new Paint();
nPaint.setAntiAlias(true);
nPaint.setDither(true);
nPaint.setStrokeJoin(Paint.Join.ROUND);
nPaint.setStrokeCap(Paint.Cap.ROUND);
int gradientStart = getResources().getInteger(R.integer.gradient_start);
int gradientend = getResources().getInteger(R.integer.gradient_end);
nPaint.setShader(new RadialGradient(getWidth() / 2, getHeight() / 2, getWidth() / 2,
gradientStart, gradientend, Shader.TileMode.CLAMP));
Try this code i hope this will help you
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.CYAN);
Paint p = new Paint();
// smooths
p.setAntiAlias(true);
p.setColor(Color.RED);
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(5);
// opacity
//p.setAlpha(0x80); //
RectF rectF = new RectF(50, 20, 100, 80);
canvas.drawOval(rectF, p);
p.setColor(Color.BLACK);
canvas.drawArc (rectF, 90, 45, true, p);
}