I'm trying to merge up to around 200 images. I'm using the following code but on attempting to merge the 3rd image, the first 2 go away and all that I'm shown is only the 3rd image. In reality, when I'm merging the 50th image, I'm really only dealing w/ 2 images: the one that has 49 images merged and the new image to merge. Here is an excert from my hello world project:
InputStream inputStream = getAssets().open(filename);
Bitmap newBitmap = BitmapFactory.decodeStream(inputStream);
Drawable drawable = imageButtonFrameView.getDrawable();
boolean isBitmapDrawable = (drawable instanceof BitmapDrawable);
if (isBitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Bitmap existingBitmap = bitmapDrawable.getBitmap();
Paint paint = new Paint();
paint.setAlpha(95);
Bitmap bmOverlay = Bitmap.createBitmap(existingBitmap.getWidth(), existingBitmap.getHeight(), existingBitmap.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(existingBitmap, new Matrix(), paint);
canvas.drawBitmap(newBitmap, 0,0,paint);
newBitmap = bmOverlay;
}
imageButtonFrameView.setImageBitmap(newBitmap);
Related
I am developing an Android application for image processing. In that, I first need to generate an ortho image by stitching 100+ images together. I have tried it in Android using Bitmap and Canvas. I first did it for 3 images. Is it the right way to generate an ortho or is there any better solution for this? Here is the code that I have used for stitching 3 images:
private void joinImages(File first, File second , File third) throws IOException
{
Bitmap bmp1, bmp2, bmp3;
bmp1 = BitmapFactory.decodeFile(first.getPath());
bmp2 = BitmapFactory.decodeFile(second.getPath());
bmp3 = BitmapFactory.decodeFile(third.getPath());
int height = bmp1.getHeight()+bmp2.getHeight()+bmp3.getHeight();
String height1 = height+"";
Log.d(height1,"heght");
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, 0, 0, null);
canvas.drawBitmap(bmp2, bmp1.getHeight(), 0, null);
canvas.drawBitmap(bmp3,bmp1.getHeight()+bmp2.getHeight() , 0, null);
FileOutputStream out = new FileOutputStream("/storage/emulated/0/DCIM/final.jpg");
bmOverlay.compress(Bitmap.CompressFormat.JPEG, 80, out);
out.close();
}
As I am new to Android as well as image processing, I also want to know the difference between image stitching and 2D-orthomosaic generation. Kindly help me with this issue.
I am creating an app with ListView like that of Google Hangout. The list item consists of Imageview on the left and some text on the right. See the image below.
I don't know how to show these images. When there is single person i want to show only one circular. However, if there are more persons I want to show images as per above photograph. Please help me out. How can I do this?
I solved this problem myself.
There are two ways to solve this problem.
Use canvas to generate a Bitmap will be a combined bitmap of all the images. Below is the code for generating Bitmap of four people (four circles).
public static Bitmap customImageFour(Context context, Bitmap[] bitmaps, int size) {
Bitmap bmp1 = Bitmap.createScaledBitmap(bitmaps[0], size/2, size/2, false);
Bitmap bmp2 = Bitmap.createScaledBitmap(bitmaps[1], size/2, size/2, false);
Bitmap bmp3 = Bitmap.createScaledBitmap(bitmaps[2], size/2, size/2, false);
Bitmap bmp4 = Bitmap.createScaledBitmap(bitmaps[3], size/2, size/2, false);
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bitmap1 = Bitmap.createBitmap(bmp1);
bitmap1 = getRoundedCornerBitmap(bitmap1, bitmap1.getWidth()/2);
Bitmap bitmap2 = Bitmap.createBitmap(bmp2);
bitmap2 = getRoundedCornerBitmap(bitmap2, bitmap2.getWidth()/2);
Bitmap bitmap3 = Bitmap.createBitmap(bmp3);
bitmap3 = getRoundedCornerBitmap(bitmap3, bitmap3.getWidth()/2);
Bitmap bitmap4 = Bitmap.createBitmap(bmp4);
bitmap4 = getRoundedCornerBitmap(bitmap4, bitmap4.getWidth()/2);
Bitmap finalBitmap = Bitmap.createBitmap(size, size, conf);
Canvas canvas = new Canvas(finalBitmap);
canvas.drawBitmap(bitmap1, 0f, 0f, null);
canvas.drawBitmap(bitmap2, bitmap1.getWidth(), 0f, null);
canvas.drawBitmap(bitmap3, 0f, bitmap1.getHeight(), null);
canvas.drawBitmap(bitmap4, bitmap1.getWidth(), bitmap1.getHeight(), null);
return finalBitmap;
}
Another way is, instead of using single ImageView you can use a RelativeLayout and add ImageViews in it through code. If there are two people then create two ImageViews and add them in the layout, if there are four people then create four ImageViews and add them in the layout.
int x = 10;
int y = 10;
int r = 4;
Paint mPaint = new Paint();
mPaint.setColor(0xFF0000);
Canvas mCanvas = new Canvas();
mCanvas.drawCircle(x,y,r,mPaint);
Is there any way to convert mCanvas to a Drawable? My goal is to generate drawables with a certain shape and color.
Thanks
For simple shapes like your circle, I'd think a Shape Drawable would be easier. For more complicated things, just create a Bitmap for your Canvas to use, then create the Canvas and draw into it, then create a Drawable from your Bitmap. Something like:
int x = 10;
int y = 10;
int r = 4;
Paint mPaint = new Paint();
mPaint.setColor(0xFF0000);
Bitmap bitmap = Bitmap.createBitmap(/* read the docs*/);
Canvas mCanvas = new Canvas(bitmap);
mCanvas.drawCircle(x,y,r,mPaint);
BitmapDrawable drawable = new BitmapDrawable(getResources(), bitmap);
To be perhaps somewhat pedantic (and hopefully increase your understanding), a Canvas just hosts the "draw" calls and draws into a Bitmap that you specify. This means:
Your example code doesn't do much, since you didn't construct your Canvas with a Bitmap or call setBitmap() on it.
You're not converting your Canvas to a Drawable, you're constructing a Drawable from the Bitmap your Canvas calls draw into.
Taken from another post, here is the psuedo code to do this.
Image on canvas to JPEG file
ByteArrayOutputStream baos = new ByteArrayOutputStream()
Bitmap bitmap = Bitmap.createBitmap( view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
// This converts the bitmap to a drawable
BitmapDrawable mDrawable = new BitmapDrawable(getResources(),bitmap);
Alternately, you could use getDrawingCache() as outlined in another answer of that thread.
Hy, I tried to search this but not very much luck
the most similar is this one
http://ketankantilal.blogspot.com/2011/03/how-to-combine-images-and-store-to.html
Anyhow, I'm developing for android.
The question is I have images in png format (or jpg as bmp is quite large for my app).
How can I combine three images from top to bottom.
I do not need to save them on sd just to display them.
Thanks, and sorry if a similar question with answer exists.
You could use a Canvas and then draw each Bitmap (assuming each image is loaded into a Bitmap object) using appropriate top and left offsets.
You would increase the top offset of the next bitmap by the total size of the previously drawn Bitmaps.
Check out http://developer.android.com/reference/android/graphics/Canvas.html
example:
public void stackImages(Context ctx)
{
// base image, if new images have transparency or don't fill all pixels
// whatever is drawn here will show.
Bitmap result = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
// b1 will be on top
Bitmap b1 = Bitmap.createBitmap(400, 200, Bitmap.Config.ARGB_8888);
// b2 will be below b1
Bitmap b2 = Bitmap.createBitmap(400, 200, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(result);
c.drawBitmap(b1, 0f, 0f, null);
// notice the top offset
c.drawBitmap(b2, 0f, 200f, null);
// result can now be used in any ImageView
ImageView iv = new ImageView(ctx);
iv.setImageBitmap(result);
// or save to file as png
// note: this may not be the best way to accomplish the save
try {
FileOutputStream out = new FileOutputStream(new File("some/file/name.png"));
result.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
}
I want to merge two images and then save them on the Android SDCard.One is from the camera and one from the resources folder. The problem is that i get this error: Caused by: java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor. Thanks.
Bitmap bottomImage = BitmapFactory.decodeResource(getResources(),R.drawable.blink);
Bitmap topImage = (Bitmap) data.getExtras().get("data");
// As described by Steve Pomeroy in a previous comment,
// use the canvas to combine them.
// Start with the first in the constructor..
Canvas comboImage = new Canvas(bottomImage);
// Then draw the second on top of that
comboImage.drawBitmap(topImage, 0f, 0f, null);
// bottomImage is now a composite of the two.
// To write the file out to the SDCard:
OutputStream os = null;
try {
os = new FileOutputStream("/sdcard/DCIM/Camera/" + "myNewFileName.png");
bottomImage.compress(CompressFormat.PNG, 50, os);
//Bitmap image.compress(CompressFormat.PNG, 50, os);
} catch(IOException e) {
Log.v("error saving","error saving");
e.printStackTrace();
}
Managed to fix it by simply doing this change:
int w = bottomImage.getWidth();
int h = bottomImage.getHeight();
Bitmap new_image = Bitmap.createBitmap(w, h ,bottomImage.getConfig());
The problem now is that it doesn't saves the image. Do you know why?
This will help you =)
Edit: (embed answer from link)
the only static "constructor" for Bitmap returning a mutable one is:
(Class: Bitmap) public static Bitmap createBitmap(int width, int
height, boolean hasAlpha)
Returns: a mutable bitmap with the specified width and height.
So you could work with getPixels/setPixels or like this:
Bitmap bitmapResult = bm.createBitmap(widthOfOld, heightOfOld, hasAlpha);
Canvas c = new Canvas();
c.setDevice(bitmapResult); // drawXY will result on that Bitmap
c.drawBitmap(bitmapOld, left, top, paint);
how to get the drawable from Bitmap: by using the BitmapDrawable-Subclass which extends Drawable, like this:
Bitmap myBitmap = BitmapFactory.decode(path);
Drawable bd = new BitmapDrawable(myBitmap);
The bitmap you are retrieving is immutable, meaning it can't be modified. Although it doesn't specify on the Canvas page that the constructor needs a mutable bitmap, it does.
To create a mutable bitmap, you can use this method.