How do I put 2 images, one on top of the other, that will blend both of them?
Background
I have 2 imageViews, one on top of the other, that have animation together. I need them to blend in with each other using the "Multiply" effect during this animation.
Something similar to this question , which is about colors, but with images (VectorDrawable in my case, but I can use PNG instead of if needed).
Here's a sketch to demonstrate what I would like to do:
Note that some of the images that overlap are darker than the original color of the arrows.
Problem
I cannot find a way to do this yet. I know, of course, how to put a view on top of another, but changing the color of a part of a bitmap based on another is something I cannot find.
What i found
I tried using:
imageView.getDrawable().setColorFilter(..., PorterDuff.Mode.MULTIPLY)
for both ImageViews, but it doesn't work. What this does is actually change the entire color of the imageView to blend in with the color I provide as a parameter.
This makes sense because it is just a colorFilter, similar to a tint.
I've also tried alpha for each of the ImageViews, but that also means that the part of the ImageViews (the parts that don't overlap) will have a semi-transparent color.
I could theoretically get a bitmap of each of them and then filter on the result, but this is impractical since I need to show it while animating between them.
Question
How can I mix 2 images?
source to share
OK, it seems like this is not possible using 2 views because of the way they work on Android, so instead I want to show you how to do it using LayerDrawable:
public class LD extends LayerDrawable {
private Paint p = new Paint();
public LD(Drawable[] layers) {
super(layers);
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
int count = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
for (int i = 0, numberOfLayers = getNumberOfLayers(); i < numberOfLayers; ++i) {
this.getDrawable(i).draw(canvas);
canvas.saveLayer(null, p, Canvas.ALL_SAVE_FLAG);
}
canvas.restoreToCount(count);
//original code:
//int count = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
//this.getDrawable(0).draw(canvas);
//canvas.saveLayer(null, p, Canvas.ALL_SAVE_FLAG);
//this.getDrawable(1).draw(canvas);
//canvas.restoreToCount(count);
}
}
Using:
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Drawable drawable1 = AppCompatResources.getDrawable(this, R.drawable....);
Drawable drawable2 = AppCompatResources.getDrawable(this, R.drawable....);
Drawable drawable3 = AppCompatResources.getDrawable(this, R.drawable....);
LD layerDrawable = new LD(new Drawable[]{
drawable1,
drawable2,
drawable3
});
imageView.setImageDrawable(layerDrawable);
source to share
Since you are using VectorDrawable, did you consider the animation to be drawable and not view?
https://developer.android.com/reference/android/graphics/drawable/AnimatedVectorDrawable.html
source to share
try this:
public Bitmap combineImages(Bitmap frame, Bitmap image) {
Bitmap cs = null;
Bitmap rs = null;
rs = Bitmap.createScaledBitmap(frame, image.getWidth(),
image.getHeight(), true);
cs = Bitmap.createBitmap(rs.getWidth(), rs.getHeight(),
Bitmap.Config.RGB_565);
Canvas comboImage = new Canvas(cs);
comboImage.drawBitmap(image, 0, 0, null);
comboImage.drawBitmap(rs, 0, 0, null);
if (rs != null) {
rs.recycle();
rs = null;
}
Runtime.getRuntime().gc();
return cs;
}
source to share