how to set contentview declaratively or use customview class - android

i'd like to load a picture from sdcard into my view then draw upon it. so far i can take the picture and display it in an imageview after i've drawn a circle on the bitmap but this is not how it should be done. I think that i need to create a custom view class and override it's onDraw(). Atm i have a relative layout with a surfaceview, after the surfaceview i have the imageview and buttons. My question is if i write a custom view class to handle the drawing, i would then pass that to my activity's setContent view, what is confusing me is if the layout is declared declaratively via the xml file, how can i set the activity's setContentView() to the custom view class that handles the drawing?
thanks mat
[edit]
here's the xml layout i'm using. this is not how i should do it using an imageview.
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content" android:gravity="fill">
<ImageView android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"></ImageView>
<com.tecmark.HorizontalSlider android:id="#+id/slider"
android:indeterminateOnly="false"
android:progressDrawable="#android:drawable/progress_horizontal"
android:indeterminateDrawable="#android:drawable/progress_indeterminate_horizontal"
android:minHeight="20dip"
android:maxHeight="20dip" android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
public class LoadPic extends Activity{
private static final String TAG = "Loadpic";
private ImageView imageview;
private File tempFile;
private byte[] imageArray;
private HorizontalSlider slider;
private Canvas canvas;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Log.e(TAG, " loadpic onCreate");
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.load2);
setProgressBarVisibility(true);
slider = (HorizontalSlider) this.findViewById(R.id.slider);
slider.setOnProgressChangeListener(changeListener);
imageview = (ImageView)findViewById(R.id.imageView1);
tempFile = new File(Environment.getExternalStorageDirectory().
getAbsolutePath() + "/"+"image.jpg");
imageArray = new byte[(int)tempFile.length()];
try{
InputStream is = new FileInputStream(tempFile);
BufferedInputStream bis = new BufferedInputStream(is);
DataInputStream dis = new DataInputStream(bis);
int i = 0;
while (dis.available() > 0) {
imageArray[i] = dis.readByte();
i++;
}
dis.close();
} catch (Exception e) {
e.printStackTrace();
}
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inSampleSize = 5;
Bitmap bm = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length, bfo);
Log.e(TAG, bm.toString());
//imageview.setImageBitmap(bm);
Bitmap bmOverlay = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig());
canvas = new Canvas(bmOverlay);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.STROKE);
canvas.drawBitmap(bm, new Matrix(), null);
canvas.drawCircle(50, 50, 25, paint);
imageview.setImageBitmap(bmOverlay);
}// end of onCreate
private OnProgressChangeListener changeListener = new OnProgressChangeListener() {
#Override
public void onProgressChanged(View v, int progress) {
// TODO Auto-generated method stub
setProgress(progress);
}
};
}//end of Activity
What i'm thinking of doing is creating a customview class that handles the drawing on the bitmap. But if i do this then how do i make setContentView() to point to my customView class when it point to the xml file. Sorry if i missing something here.

If you want to have a custom view for the bitmap and drawing then you can simply extend ImageView and override the paint method. Something like that:
public class MyImage extends ImageView {
...
#Override
public void paint(...){}
}
And in the xml layout change the ImageView to
<what.ever.package.MyImage ... />

Related

How to create MaskTransformation using Picasso? Both images from server side mask image and other image

I want mask image and other image getting from server
Picasso.with(getApplicationContext())
.load("http://s1.picswalls.com/wallpapers/2014/07/24/awesome-pattern-wallpaper_113041209_88.jpg")
.transform(new MaskTransformation(MainActivity.this,"http://s1.picswalls.com/wallpapers/2014/07/24/maskImage.jpg"))
.into(a);
after lots of try.I got answer for this problem
please change class MaskTransformation like below
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import com.squareup.picasso.Transformation;
public class MaskTransformation implements Transformation {
private static Paint mMaskingPaint = new Paint();
static {
mMaskingPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
}
private Drawable maskId;
/**
* #param maskId If you change the mask file, please also rename the mask file, or Glide will get
* the cache with the old mask. Because getId() return the same values if using the
* same make file name. If you have a good idea please tell us, thanks.
*/
public MaskTransformation(Drawable maskId) {
this.maskId = maskId;
}
#Override
public Bitmap transform(Bitmap source) {
int width = source.getWidth();
int height = source.getHeight();
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Drawable mask = this.maskId;
Canvas canvas = new Canvas(result);
mask.setBounds(0, 0, width, height);
mask.draw(canvas);
canvas.drawBitmap(source, 0, 0, mMaskingPaint);
source.recycle();
return result;
}
#Override
public String key() {
return "MaskTransformation(maskId=" + maskId
+ ")";
}
}
In activity write below code
public class MainActivity extends AppCompatActivity {
ImageView imageView;
Button btnMask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
Picasso.with(getApplicationContext())
.load("http://pixlab.xyz/images/eye_mask.png")
.into(imageView);
btnMask = findViewById(R.id.btnMask);
btnMask.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// if you want to get bitmap and drawable from imageview
// Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
// Drawable drawable = new BitmapDrawable(getResources(), bitmap);
Drawable drawable=imageView.getDrawable();
MaskTransformation maskTransformation = new MaskTransformation(drawable);
Picasso.with(getApplicationContext())
.load("http://s1.picswalls.com/wallpapers/2014/07/24/awesome-pattern-wallpaper_113041209_88.jpg")
.transform(maskTransformation)
.into(imageView);
}
});
}
}
MainActivity layout xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="#+id/btnMask"
android:text="submit"
/>
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
Note : Loading image from server take some time that why when you try before complete download image then exception occur

Android: Adding text to a View

I'm trying to add a text element to a view that's been created. I've found some answers online, but haven't been able to tailor them. I'm using the TouchPaint example code. Every-time I run the app with the text element, the app fails. Would appreciate some help.
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create and attach the view that is responsible for painting.
mView = new MyView(this);
setContentView(mView);
mView.requestFocus();
TextView tvX= (TextView)findViewById(R.id.pointSize);
tvX.setText("TestText");
// Restore the fading option if we are being thawed from a
// previously saved state. Note that we are not currently remembering
// the contents of the bitmap.
mFading = savedInstanceState != null ? savedInstanceState.getBoolean("fading", true) : true;
}
View class
public class MyView extends View {
private static final int FADE_ALPHA = 0x06;
private static final int MAX_FADE_STEPS = 256/FADE_ALPHA + 4;
private Bitmap mBitmap;k
private Canvas mCanvas;
private final Rect mRect = new Rect();
private final Paint mPaint;
private final Paint mFadePaint;
private boolean mCurDown;
private int mCurX;
private int mCurY;
private float mCurPressure;
private float mCurSize;
private int mCurWidth;
private int mFadeSteps = MAX_FADE_STEPS;
public MyView(Context c) {
super(c);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setARGB(255, 255, 255, 255);
mFadePaint = new Paint();
mFadePaint.setDither(true);
mFadePaint.setARGB(FADE_ALPHA, 0, 0, 0);
}
XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${packageName}.${activityClass}" >
<TextView
android:id="#+id/pointSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world"
android:textColor="#FF0000"
android:visibility="visible" />
</RelativeLayout>
Try this:
LinearLayout lv = new LinearLayout(this);
tvX.setText("TestText");
lv .addView(tvX);
setContentView(lv);

Array Of Drawable Images

Ok so first of I will take you through the basics of my App. So far you take picture using the camera which then gets saved into a folder. Once the picture has been took a new Activity opens and shows the picture on screen in a ImageView.
The effect I am trying to achive is something along the lines of being able to create png layers over the top of the picture in the ImageView with the onClick Event. So say I have 5 transparent png's I want to have five onClick events which with each touch of the screen a new png image will get displayed over the top of the picture in the ImageView so it would take 5 onClick (touch of screen) to show all the transparent png's over the top of the picture.
I think I am nearly there with the code below but I think I need to create an array of the images in the drawable folder that need to be displayed with each onClick event, I think the array should be nextBitmap but not to sure.
Update Sparkys answer
I have tried adding private Integer[] nextBitmap = { R.drawable.img1, R.drawable.img2 }; but I am getting the error The method getBitmapOverlay(Bitmap, Bitmap, int, int) in the type BeatEmUp is not applicable for the arguments (Bitmap, Integer[], int, int) anyone know what this could be do I need to add the private Integer[]...... outside the onCreate method?
public class Image extends Activity {
Bitmap myBitmap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.Image);
String myRef = this.getIntent().getStringExtra("filepath");
File imgFile = new File(myRef);
Log.e("No ref", myRef);
if(imgFile.exists()) {
final Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
final ImageView myImage = (ImageView) findViewById(R.id.beatemup);
myImage.setImageBitmap(myBitmap);
myImage.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
myBitmap = getBitmapOverlay(myBitmap, nextBitmap, 0, 0);
myImage.setImageBitmap(myBitmap);
}
});
}
}
public static Bitmap getBitmapOverlay(Bitmap bmp1, Bitmap bmp2, int left, int top) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, 0, 0, null);
canvas.drawBitmap(bmp2, left, top, null);
return bmOverlay;
}
}
Ok, I have made you a small working sample that might be what you are looking for.
I break my own rules here because I did code for you. As I know that you are a beginner, you should definitively understand the following code before you use it.
public class Image extends Activity {
Bitmap myBitmap;
Integer[] mBitmapIds = new Integer[] { R.drawable.ic_launcher, R.drawable.ic_launcher };
Random mRand = new Random();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
final ImageView myImage = (ImageView) findViewById(R.id.imageview);
myImage.setImageBitmap(myBitmap);
myImage.setOnClickListener(new OnClickListener() {
int i = 0;
public void onClick(View v) {
if (i >= mBitmapIds.length) {
i = 0;
}
myImage.setImageBitmap(getBitmapOverlay(myBitmap, BitmapFactory.decodeResource(getResources(), mBitmapIds[i]), 0, 0));
}
});
}
public Bitmap getBitmapOverlay(Bitmap bmp1, Bitmap bmp2, int left, int top) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(),
bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, 0, 0, null);
left += mRand.nextInt(20);
top += mRand.nextInt(20);
canvas.drawBitmap(bmp2, left, top, null);
return bmOverlay;
}
}
See the Hello, Views tutorial, GridView chapter for an example of an array of references to Drawables.

Cannot render an xml layout with LayoutInfalter. What I'm doing wrong?

I need to show a layout from xml file and draw some vector based image on top of that. If code below is executed then everything is shown but the layout. Why? What I'm doing wrong?
public class About extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.about);
setContentView(new GraphicsView(this));
}
public class GraphicsView extends View
{
public GraphicsView(Context context)
{
super(context);
}
#Override
protected void onDraw(Canvas canvas)
{
Context context;
context=getContext();
View aview;
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
aview = inflater.inflate(R.layout.about, null);
aview.draw(canvas);
Path circle = new Path();
Paint cPaint = new Paint();
cPaint.setColor(Color.LTGRAY);
circle.addCircle(150, 150, 100, Direction.CW);
canvas.drawPath(circle, cPaint);
cPaint.setColor(Color.RED);
canvas.drawTextOnPath("Some stupid text", circle, 0, 20, cPaint);
}
}
}
After inflating the View you need to measure it and lay it out to give it a size so it can be properly drawn. You should call aview.measure() and aview.layout() before calling aview.draw().
Note that you should NEVER inflate views from onDraw(). It is very expensive and wasteful. Similarly, you should NEVER create paints or paths inside onDraw().
There is an another answer from another forum:
FrameLayout:
public class About extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.about);
GraphicsView drawing = new GraphicsView(this);
FrameLayout container = (FrameLayout) findViewById(R.id.container);
container.addView(drawing);
}
public class GraphicsView extends View
{
public GraphicsView(Context context)
{
super(context);
}
#Override
protected void onDraw(Canvas canvas)
{
Path circle = new Path();
Paint cPaint = new Paint();
cPaint.setColor(Color.LTGRAY);
circle.addCircle(150, 150, 100, Direction.CW);
canvas.drawPath(circle, cPaint);
cPaint.setColor(Color.RED);
canvas.drawTextOnPath("Some stupid text", circle, 0, 20, cPaint);
}
}
}
And then here comes XML:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:id="#+id/container">
<TextView
android:id="#+id/about_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/about_text" />
</FrameLayout>

overlay two images in android to set an imageview

I am trying to overlay two images in my app, but they seem to crash at my canvas.setBitmap() line. What am I doing wrong?
private void test() {
Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.t);
Bitmap mBitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.tt);
Bitmap bmOverlay = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig());
Canvas canvas = new Canvas();
canvas.setBitmap(bmOverlay);
canvas.drawBitmap(mBitmap, new Matrix(), null);
canvas.drawBitmap(mBitmap2, new Matrix(), null);
testimage.setImageBitmap(bmOverlay);
}
You can skip the complex Canvas manipulation and do this entirely with Drawables, using LayerDrawable. You have one of two choices: You can either define it in XML then simply set the image, or you can configure a LayerDrawable dynamically in code.
Solution #1 (via XML):
Create a new Drawable XML file, let's call it layer.xml:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/t" />
<item android:drawable="#drawable/tt" />
</layer-list>
Now set the image using that Drawable:
testimage.setImageDrawable(getResources().getDrawable(R.layout.layer));
Solution #2 (dynamic):
Resources r = getResources();
Drawable[] layers = new Drawable[2];
layers[0] = r.getDrawable(R.drawable.t);
layers[1] = r.getDrawable(R.drawable.tt);
LayerDrawable layerDrawable = new LayerDrawable(layers);
testimage.setImageDrawable(layerDrawable);
(I haven't tested this code so there may be a mistake, but this general outline should work.)
ok just so you know there is a program out there that's called DroidDraw. It can help you draw objects and try them one on top of the other. I tried your solution but I had animation under the smaller image so that didn't work. But then I tried to place one image in a relative layout that's suppose to be under first and then on top of that I drew the other image that is suppose to overlay and everything worked great. So RelativeLayout, DroidDraw and you are good to go :) Simple, no any kind of jiggery pockery :) and here is a bit of code for ya:
The logo is going to be on top of shazam background image.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/widget30"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<ImageView
android:id="#+id/widget39"
android:layout_width="219px"
android:layout_height="225px"
android:src="#drawable/shazam_bkgd"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
>
</ImageView>
<ImageView
android:id="#+id/widget37"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/shazam_logo"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
>
</ImageView>
</RelativeLayout>
You can use the code below to solve the problem or download demo here
Create two functions to handle each.
First, the canvas is drawn and the images are drawn on top of each other from point (0,0)
On button click
public void buttonMerge(View view) {
Bitmap bigImage = BitmapFactory.decodeResource(getResources(), R.drawable.img1);
Bitmap smallImage = BitmapFactory.decodeResource(getResources(), R.drawable.img2);
Bitmap mergedImages = createSingleImageFromMultipleImages(bigImage, smallImage);
img.setImageBitmap(mergedImages);
}
Function to create an overlay.
private Bitmap createSingleImageFromMultipleImages(Bitmap firstImage, Bitmap secondImage){
Bitmap result = Bitmap.createBitmap(firstImage.getWidth(), firstImage.getHeight(), firstImage.getConfig());
Canvas canvas = new Canvas(result);
canvas.drawBitmap(firstImage, 0f, 0f, null);
canvas.drawBitmap(secondImage, 10, 10, null);
return result;
}
Read more
Its a bit late answer, but it covers merging images from urls using Picasso
MergeImageView
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import java.io.IOException;
import java.util.List;
public class MergeImageView extends ImageView {
private SparseArray<Bitmap> bitmaps = new SparseArray<>();
private Picasso picasso;
private final int DEFAULT_IMAGE_SIZE = 50;
private int MIN_IMAGE_SIZE = DEFAULT_IMAGE_SIZE;
private int MAX_WIDTH = DEFAULT_IMAGE_SIZE * 2, MAX_HEIGHT = DEFAULT_IMAGE_SIZE * 2;
private String picassoRequestTag = null;
public MergeImageView(Context context) {
super(context);
}
public MergeImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MergeImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public MergeImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public boolean isInEditMode() {
return true;
}
public void clearResources() {
if (bitmaps != null) {
for (int i = 0; i < bitmaps.size(); i++)
bitmaps.get(i).recycle();
bitmaps.clear();
}
// cancel picasso requests
if (picasso != null && AppUtils.ifNotNullEmpty(picassoRequestTag))
picasso.cancelTag(picassoRequestTag);
picasso = null;
bitmaps = null;
}
public void createMergedBitmap(Context context, List<String> imageUrls, String picassoTag) {
picasso = Picasso.with(context);
int count = imageUrls.size();
picassoRequestTag = picassoTag;
boolean isEven = count % 2 == 0;
// if url size are not even make MIN_IMAGE_SIZE even
MIN_IMAGE_SIZE = DEFAULT_IMAGE_SIZE + (isEven ? count / 2 : (count / 2) + 1);
// set MAX_WIDTH and MAX_HEIGHT to twice of MIN_IMAGE_SIZE
MAX_WIDTH = MAX_HEIGHT = MIN_IMAGE_SIZE * 2;
// in case of odd urls increase MAX_HEIGHT
if (!isEven) MAX_HEIGHT = MAX_WIDTH + MIN_IMAGE_SIZE;
// create default bitmap
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_wallpaper),
MIN_IMAGE_SIZE, MIN_IMAGE_SIZE, false);
// change default height (wrap_content) to MAX_HEIGHT
int height = Math.round(AppUtils.convertDpToPixel(MAX_HEIGHT, context));
setMinimumHeight(height * 2);
// start AsyncTask
for (int index = 0; index < count; index++) {
// put default bitmap as a place holder
bitmaps.put(index, bitmap);
new PicassoLoadImage(index, imageUrls.get(index)).execute();
// if you want parallel execution use
// new PicassoLoadImage(index, imageUrls.get(index)).(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
private class PicassoLoadImage extends AsyncTask<String, Void, Bitmap> {
private int index = 0;
private String url;
PicassoLoadImage(int index, String url) {
this.index = index;
this.url = url;
}
#Override
protected Bitmap doInBackground(String... params) {
try {
// synchronous picasso call
return picasso.load(url).resize(MIN_IMAGE_SIZE, MIN_IMAGE_SIZE).tag(picassoRequestTag).get();
} catch (IOException e) {
}
return null;
}
#Override
protected void onPostExecute(Bitmap output) {
super.onPostExecute(output);
if (output != null)
bitmaps.put(index, output);
// create canvas
Bitmap.Config conf = Bitmap.Config.RGB_565;
Bitmap canvasBitmap = Bitmap.createBitmap(MAX_WIDTH, MAX_HEIGHT, conf);
Canvas canvas = new Canvas(canvasBitmap);
canvas.drawColor(Color.WHITE);
// if height and width are equal we have even images
boolean isEven = MAX_HEIGHT == MAX_WIDTH;
int imageSize = bitmaps.size();
int count = imageSize;
// we have odd images
if (!isEven) count = imageSize - 1;
for (int i = 0; i < count; i++) {
Bitmap bitmap = bitmaps.get(i);
canvas.drawBitmap(bitmap, bitmap.getWidth() * (i % 2), bitmap.getHeight() * (i / 2), null);
}
// if images are not even set last image width to MAX_WIDTH
if (!isEven) {
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmaps.get(count), MAX_WIDTH, MIN_IMAGE_SIZE, false);
canvas.drawBitmap(scaledBitmap, scaledBitmap.getWidth() * (count % 2), scaledBitmap.getHeight() * (count / 2), null);
}
// set bitmap
setImageBitmap(canvasBitmap);
}
}
}
xml
<com.example.MergeImageView
android:id="#+id/iv_thumb"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Example
List<String> urls = new ArrayList<>();
String picassoTag = null;
// add your urls
((MergeImageView)findViewById(R.id.iv_thumb)).
createMergedBitmap(MainActivity.this, urls,picassoTag);
this is my solution:
public Bitmap Blend(Bitmap topImage1, Bitmap bottomImage1, PorterDuff.Mode Type) {
Bitmap workingBitmap = Bitmap.createBitmap(topImage1);
Bitmap topImage = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
Bitmap workingBitmap2 = Bitmap.createBitmap(bottomImage1);
Bitmap bottomImage = workingBitmap2.copy(Bitmap.Config.ARGB_8888, true);
Rect dest = new Rect(0, 0, bottomImage.getWidth(), bottomImage.getHeight());
new BitmapFactory.Options().inPreferredConfig = Bitmap.Config.ARGB_8888;
bottomImage.setHasAlpha(true);
Canvas canvas = new Canvas(bottomImage);
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(Type));
paint.setFilterBitmap(true);
canvas.drawBitmap(topImage, null, dest, paint);
return bottomImage;
}
usage :
imageView.setImageBitmap(Blend(topBitmap, bottomBitmap, PorterDuff.Mode.SCREEN));
or
imageView.setImageBitmap(Blend(topBitmap, bottomBitmap, PorterDuff.Mode.OVERLAY));
and the results :
Overlay mode :
Screen mode:

Categories

Resources