I would like to create an animation similar to Instagram Tilt Shift ( Radial/Linear), I am trying to create a blurred bitmap from the existing image and change the imageView source on animation start and stop. But its slow and not smooth.
public class BlurMaskHandler extends AsyncTask<Integer,Integer,Bitmap> {
#Override
protected Bitmap doInBackground(Integer... drawable) {
Bitmap bitmapMaster = BitmapFactory.decodeResource(getResources(), drawable[0]);
int w = bitmapMaster.getWidth();
int h = bitmapMaster.getHeight();
RectF rectF = new RectF(0,0,w,h);
float blurRadius = 500.0f;
Bitmap bitmapResult = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvasResult = new Canvas(bitmapResult);
Paint blurPaintOuter = new Paint();
blurPaintOuter.setColor(0xFFffffff);
blurPaintOuter.setMaskFilter(new
BlurMaskFilter(blurRadius, BlurMaskFilter.Blur.INNER));
canvasResult.drawBitmap(bitmapMaster, 0, 0, blurPaintOuter);
Paint blurPaintInner = new Paint();
blurPaintInner.setColor(0x80ffffff);
blurPaintInner.setMaskFilter(new
BlurMaskFilter(blurRadius, BlurMaskFilter.Blur.INNER));
canvasResult.drawRect(rectF, blurPaintInner);
return bitmapResult;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
bitmapView = bitmap;
}
}
Related
How to add multiple points over an image view.
this is what i am trying
myView = (ImageView) findViewById(R.id.my_view);
View view = LayoutInflater.from(ZoomTouchActivity.this).inflate(R.layout.layout_custom_view, null);
CircularImageView imgView = view.findViewById(R.id.site_image);
TextView siteName = view.findViewById(R.id.site_text);
imgView.setImageResource(R.drawable.ic_launcher_background);
siteName.setText("est");
Bitmap bitmap = getBitmapFromView(view);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
// canvas.drawCircle(50, 50, 10, paint);
canvas.drawBitmap(bitmap, 50, 50, paint);
myView.setImageBitmap(bitmap);
You can draw on an ImageView by simply putting the image's Bitmap inside a canvas, draw on the canvas and set the drawn canvas to the imageview. You can check this answer for more details. For more details on how to draw, you can check the android documentation here.
Try this:
BitmapFactory.Options myOptions;
Canvas canvas;
Bitmap mutableBitmap;
Bitmap workingBitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_open= findViewById(R.id.btn_open);
image2= findViewById(R.id.imageView);
myOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.image000880,myOptions);
paint= new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
workingBitmap = Bitmap.createBitmap(bitmap);
mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
canvas = new Canvas(mutableBitmap);
private void drawpoint(ImageView imageView,float x,float y, int raduis){
myOptions.inDither = true;
myOptions.inScaled = false;
myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// important
myOptions.inPurgeable = true;
// ArrayList<Point> list= new ArrayList<>();
canvas.drawCircle(x,y, raduis, paint);
imageView = (ImageView)findViewById(R.id.imageView);
imageView.setAdjustViewBounds(true);
imageView.setImageBitmap(mutableBitmap);
}
I am fetching a Bitmap with Parse on my Android application.
final WeakReference<ImageView> weakImageView = new WeakReference<>(imageViewToMask);
fetchFromParse(getContext(), new Success() {
#Override
public void success(Bitmap image) {
if (weakImageView.get() != null) {
// Here how to make this image a MaskDrawable to mask it?
// MaskedDrawable d = new MaskedDrawable(bitmap, context, [canvas here]?)
// weakImageView.get().setImageDrawable(d);
weakImageView.get().setImageDrawable(image);
}
}
});
Now I want to mask this bitmap with another image, I found this answer in this thread:
public class MaskedDrawable extends Drawable {
public void draw(Bitmap original, Context context, Canvas canvas) {
Bitmap mask = BitmapFactory.decodeResource(context.getResources(), R.drawable.mask_image);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Config.ARGB_8888);
Canvas tempCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
tempCanvas.drawBitmap(original, 0, 0, null);
tempCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
// How do I create this canvas user here?
canvas.drawBitmap(result, 0, 0, new Paint());
}
}
I already have the original bitmap and the context object, but I don't know how to use canvas. What to do?
Thanks for your help!
How to add text watermark on imageview in android,Using this code but not working
public Bitmap waterMark(Bitmap src, String watermark, Point location, int color, int alpha, int size, boolean underline) {
int w = src.getWidth();
int h = src.getHeight();
Bitmap result = Bitmap.createBitmap(w, h, src.getConfig());
Canvas canvas = new Canvas(result);
canvas.drawBitmap(src, 0, 0, null);
Paint paint = new Paint();
paint.setColor(color);
paint.setAlpha(alpha);
paint.setTextSize(size);
paint.setAntiAlias(true);
paint.setUnderlineText(underline);
canvas.drawText(watermark, location.x, location.y, paint);
return result;
}
And the code is called like this:
Bitmap b=waterMark(BitmapFactory.decodeResource(getResources(), R.drawable.setting),
R.drawable.image,p, Color.GREEN,90,80,true);
imView.setImageBitmap(b);
new Thread(new Runnable() {
#Override
public void run() {
Bitmap b=waterMark(BitmapFactory.decodeResource(getResources(), R.drawable.setting),
R.drawable.image,p, Color.GREEN,90,80,true);
imView.post(new Runnable() {
#Override
public void run() {
imView.setImageBitmap(b);
}
});
}
}).start();
I'm using the code below to apply a round mask to a bitmap using Square's Picasso library. It works great on devices with android version 3.0 and higher, but it fails to work on gingerbread. There are no errors or exceptions displayed during runtime, instead, the mask simply does not seem to be applied to the original image.
public class CircleTransformation implements Transformation {
#Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
Bitmap finalBitmap = Bitmap.createBitmap(size, size, source.getConfig());
Canvas canvas = new Canvas(finalBitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
float radius = size / 2f;
canvas.drawCircle(radius, radius, radius, paint);
source.recycle();
return finalBitmap;
}
#Override
public String key() {
return "circle";
}
}
All of the methods I'm using seem to be available since API level 1 so I'm kinda stuck. Any idea what could be the issue?
pd. this code was based on: https://gist.github.com/julianshen/5829333
I still don't know why this code doesn't work in gingerbread, but I was able to get it to work by using a round mask image:
public class PreHoneycombCircleTransformation implements Transformation {
#Override
public Bitmap transform(Bitmap source) {
int dim = Constants.BUBBLE_WIDTH;
Canvas canvas = new Canvas();
// placeholder for final image
Bitmap result = Bitmap.createBitmap(dim, dim, Bitmap.Config.ARGB_8888);
canvas.setBitmap(result);
Paint paint = new Paint();
paint.setFilterBitmap(false);
// resize image fills the whole canvas
canvas.drawBitmap(source, null, new Rect(0, 0, dim, dim), paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(Util.getMaskImage(), 0, 0, paint);
paint.setXfermode(null);
if(result != source) {
source.recycle();
}
return result;
}
#Override
public String key() {
return "pre_circle";
}
}
The class below is another alternative, works both in Gingerbread and ICS. The code in the CircleTransformation doesn't work in ICS for me.
public class CircleTransform implements Transformation {
#Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
float radius = size / 2f;
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
canvas.drawCircle(radius, radius, radius, paint);
if (source != output) {
source.recycle();
}
return output;
}
#Override
public String key() {
return "circle";
}
}
I create the Layout programatically in onCreate:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
myView = new MyView(SketchActivity.this, layout.getWidth(), layout.getHeight());
layout2.addView(myView);
layout2.bringToFront();
}
}, 50);
The View where i create the (mutable?) bitmap:
public MyView(Context c, int width, int height) {
super(c);
WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int w = display.getWidth(); // deprecated
int h = display.getHeight();
setFocusable(true);
setBackgroundResource(R.drawable.download);
// setting paint
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setAntiAlias(true);
// getting image from resources
Resources r = this.getContext().getResources();
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.smoke);
// converting image bitmap into mutable bitmap
bitmap = bm.createBitmap(w, h, Config.ARGB_8888);
mCanvas = new Canvas();
mCanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
mCanvas.drawBitmap(bm, 0, 0, null);
}
My onDraw function:
#Override
protected void onDraw(Canvas canvas) {
mCanvas.drawCircle(x, y, r, mPaint);
canvas.drawBitmap(bitmap, 0, 0, null);
super.onDraw(canvas);
}
OnTouchEvent:
#Override
public boolean onTouchEvent(MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
r = 20;
// Atlast invalidate canvas
invalidate();
return true;
}
No LogCat Errors
The problem is in myView. when i create the bitmap bitmap = bm.createBitmap(w, h, Config.ARGB_8888); If i put instead of w,h(width and height of screen) a small number Example: bitmap = bm.createBitmap(20, 20, Config.ARGB_8888); it creates a tiny picture. But if I put w and h, then instead of drawing on all the layout, it only draws on a small part. (even if i try: bitmap = bm.createBitmap(800, 1080, Config.ARGB_8888); it still draws on a small part, instead of all the screen. What should i do?
This solved it:
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// RECREATE THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
public MyView(Context c, int width, int height) {
super(c);
WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int w = display.getWidth(); // deprecated
int h = display.getHeight();
setFocusable(true);
setBackgroundResource(R.drawable.download);
// setting paint
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setAntiAlias(true);
mPaint.setMaskFilter(new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL));
// getting image from resources
Resources r = this.getContext().getResources();
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.smoke);
Bitmap bm2 = getResizedBitmap(bm, h, w);
// converting image bitmap into mutable bitmap
bitmap = bm2.createBitmap(w, h, Config.ARGB_8888);
mCanvas = new Canvas();
mCanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
mCanvas.drawBitmap(bm2, 0, 0, null);
}
Looks like you're recycling your Bitmap somwhere in the code. There is a problem.
Yes, you should recycle it, but it's always a bit risky.
EDIT
Looks like you're drawing onto Bitmap. If it's not what you're trying to do, then you shouldn't call onDraw manually. Instead call invalidate() when you want to redraw your view.
You need to add an Options data like this:
Options options = new Options();
options.isMutable = true; // works from api 11
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.smoke, options);