Draw Bitmap on another Bitmap with same width and height - android

there I want to overlay an Bitmap onto my another Bitmap. You can say, I want to draw a Bitmap on another bitmap.
Suppose that I have a Bitmap as:
And I want to draw another bitmap onto this bitmap "KEEP CALM AND CHECK YOUR WORK"! This will be Bitmap 1
The Bitmap I want to place on this bitmap is like an effect overlay as:
This will be Bitmap 2
The Problem
I want to overlay Bitmap 2 onto Bitmap 1 say Bitmap 2 should come above Bitmap 1.
The Bitmap 2 Should get the width and height of the Bitmap 1 to cover it all.
The Bitmap 1 will be of any width and height but, I want the Bitmap 2 should get the width and height of the Bitmap 1 in any case.
My code problem is that it crops the Bitmap 1 and overlay Bitmap 2 onto it then. I mean the code is getting the Bitmap 2 width and height!
What I have done
public Bitmap overlay123(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp2.getWidth(), bmp2.getHeight(), bmp1.getConfig());
float left =(bmp2.getWidth() - (bmp1.getWidth()*((float)bmp2.getHeight()/(float)bmp1.getHeight())))/(float)2.0;
float bmp1newW = bmp1.getWidth()*((float)bmp2.getHeight()/(float)bmp1.getHeight());
Bitmap bmp1new = getResizedBitmap(bmp1, bmp2.getHeight(), (int)bmp1newW);
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1new, left ,0 , null);
canvas.drawBitmap(bmp2, new Matrix(), null);
return bmOverlay;
}
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;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
Problem with the above code is that it crops or resizes bitmap 1 width and height!
Try 2
private Bitmap overlayer(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, new Matrix(), null);
canvas.drawBitmap(bmp2, new Matrix(), null);
return bmOverlay;
}
Problem with code is that It always show the Bitmap 2 in the top left corner with a smaller size!
I just need to know how can I place the Bitmap 2 onto Bitmap 1 getting width and height same as of Bitmap 1.
I am newbie to Bitmap Codes so I have no idea about it
Thanks in advace!
The final image should look like:

MainActivity Output.
public class MainActivity extends Activity {
private ImageView Img;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
Img = (ImageView) findViewById(R.id.imageView);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.top);
Bitmap bmt = BitmapFactory.decodeResource(getResources(), R.drawable.back);
Img.setImageBitmap(overlayer(bm, bmt));
}
});
}
private Bitmap overlayer(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, new Matrix(), null);
canvas.drawBitmap(bmp2, new Matrix(), null);
return bmOverlay;
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
Output:
Output result see here.

First of all, i advice you to use your Try2 as basis for further work.
But i would slightly modify the code to that:
private Bitmap overlayer(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getWidth(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, null, new Rect(0,0,bmp1.getWidth(),bmp1.getHeight()), new Paint());
canvas.drawBitmap(bmp2, null, new Rect(0,0,bmp1.getWidth(),bmp1.getHeight()), new Paint());
return bmOverlay;
}
I have used the constructor mentioned on the android developer reference for drawing bitmaps. You define a new Recatangle, that servers as shape for scaling/drawing the bitmaps to the canvas. In your case, i am defining the rectangle with same size as your bitmap1. If you hand this recangle box over to the method, which is drawing the canvas, the canvas will scale the bitmap to that box size and draw it on the canvas.

Related

Combine Images in Canvas and then view it through ImageView using Android Studio

I want to combine images by putting them on top of eachother in Canvas and then view the combination using ImageView. What I know is if you set the first Bitmap into the Canvas everything else you do will be added to that first Bitmap. I only get the error:
PointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
ImageView mainImage = (ImageView) view.findViewById(R.id.mainImage);
Bitmap bottomImage = BitmapFactory.decodeFile("image1.png");
Bitmap topImage = BitmapFactory.decodeFile("image2.png");
Bitmap tempBitmap = Bitmap.createBitmap(bottomImage.getWidth(), bottomImage.getHeight(), Bitmap.Config.RGB_565);
Canvas tempCanvas = new Canvas(tempBitmap);
tempCanvas.drawBitmap(bottomImage, 0, 0, null);
tempCanvas.drawBitmap(topImage, 0, 0, null);
mainImage.setImageBitmap(bitmap);
Try Below Code
public Bitmap drawImageOnImage(Bitmap background, Bitmap pic, int x_to_draw, int y_to_draw, int width, int height)
{
try
{
Canvas newCanvas = new Canvas(background);
Bitmap img_bitmap = Bitmap.createScaledBitmap(pic, width, height, true);
newCanvas.drawBitmap(img_bitmap, x_to_draw, y_to_draw,new Paint());
}catch (Exception e)
{
System.out.println("Error Occured=>");
e.printStackTrace();
}
return background;
}
Here function takes 2 input bitmaps, Background bitmap and another image bitmap to draw over background bitmap. You will get combined bitmap to set for ImageView. X and Y are the co-rdinates where top image bitmap start paint. Same for height and width
After some experiments this code worked perfectly. And I added multiple top images.
private void drawAndView(ImageView imgView, Bitmap bottomImage, Bitmap[] topImages){
Bitmap tempBitmap = Bitmap.createBitmap(bottomImage.getWidth(), bottomImage.getHeight(), Bitmap.Config.RGB_565);
Canvas tempCanvas = new Canvas(tempBitmap);
tempCanvas.drawBitmap(bottomImage, 0, 0, null);
for (Bitmap bitmap : topImages){
tempCanvas.drawBitmap(bitmap, 0, 0, null);
}
imgView.setImageBitmap(tempBitmap);
}

Using matrix.postRotate() to rotate a bitmap and add it to a canvas

I am trying to rotate a bitmap and add it to a canvas. The code seems straightforward, however the image is not being rotated. I can't use canvas.rotate() since I am layering images and do not want the first image to be rotated. I have verified that the rotation degree is correct with tattoo.getRotation(), and I have also tried this with a hard coded degree but that doesn't work either.
public static Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
Matrix matrix1 = new Matrix();
matrix1.setScale(imageView.getScaleX(), imageView.getScaleY());
matrix1.setTranslate(imageView.getX(), imageView.getY());
canvas.drawBitmap(bmp1, matrix1, null);
Matrix matrix2 = new Matrix();
matrix2.setTranslate(tattoo.getX(), tattoo.getY());
matrix2.postRotate(tattoo.getRotation());
matrix2.setScale(tattoo.getScaleX(), tattoo.getScaleY());
canvas.drawBitmap(bmp2, matrix2, null);
return bmOverlay;
}

Overlay 2 bitmaps of different sizes, into one the size of the screen

I have 2 bitmaps, one is: width 720 x 404 height. the other is 1280x550
I used this function:
public Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Bitmap bmp2new = getResizedBitmap(bmp2, bmp1.getHeight(), bmp1.getWidth(), bmp2.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, new Matrix(), null);
canvas.drawBitmap(bmp2new, 0, 0, null);
return bmOverlay;
}
Now it shows me both. overlayed. Now the first one, is a screen capture from a video, and the second is the canvas i draw on. The problem is that if i draw something on something thats on the margin of the screen, it will be overlayed incorrectly (an offset) because, my video is stretched to be the same as the seconc picture.
What can i do, to put both pictures, but the screen capture to start with an offset of a couple of pixels, so it will be correctly placed?
I tried:
int left = (int)((bmp2.getWidth() - (bmp1.getWidth()*(bmp2.getHeight()/bmp1.getHeight())))/2.0);
Bitmap bmp1new = getResizedBitmap(bmp1, bmp2.getHeight(), ((bmp2.getWidth() - (bmp1.getWidth()*(bmp2.getHeight()/bmp1.getHeight())) , bmp1.getConfig());
Bitmap bmptest = Bitmap.createBitmap(bmp1new, left, 0,bmp1new.getWidth() - left, bmp1new.getHeight());
But had no luck, and now I'm even more confused
it worked with this:
public Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp2.getWidth(), bmp2.getHeight(), bmp1.getConfig());
float left =(bmp2.getWidth() - (bmp1.getWidth()*((float)bmp2.getHeight()/(float)bmp1.getHeight())))/(float)2.0;
float bmp1newW = bmp1.getWidth()*((float)bmp2.getHeight()/(float)bmp1.getHeight());
Bitmap bmp1new = getResizedBitmap(bmp1, bmp2.getHeight(), (int)bmp1newW , bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1new, left ,0 , null);
canvas.drawBitmap(bmp2, new Matrix(), null);
return bmOverlay;
}

capturing image from camera and overlaying another bitmap before we save it

here tempdata is the data captured from camera, savephoto(Bitmap) is a method am using to save the image taken from camera, and it is executing accurately ,,
BUt on [2]
i am overlaying another bitmap ,, and when i am calling the savephoto(p)
it is creating an empty file in the memorycard ...
not saving any image.
how can i overlay the two bitmap on top of each other
[1]File Imgname = Environment.getExternalStorageDirectory();
Bitmap bmp = BitmapFactory.decodeByteArray(tempdata,0,tempdata.length);
imv.setImageBitmap(bmp);
savePhoto(bmp);
[2]Bitmap bmp2 = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
Bitmap b = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(b);
canvas.drawBitmap(bmp, 0,0, null);
canvas.drawBitmap(bmp2, 50, 50, null);
savePhoto(b);
any help will be greatly appreciated
thanx
you can do like this after getting after getting bitmap from camera (assume bitmap1) and your bitmap to overlay on top of bitmap1 (assume bitmap2)
call this overlayMark() with your bitmaps it will return overlay bitmap that is your required bitmap . you can save that bitmap..
private Bitmap overlayMark(Bitmap bmp1, Bitmap bmp2) {
int bh = originalBitmap.getHeight();
int bw = originalBitmap.getWidth();
Bitmap bmOverlay = Bitmap.createBitmap(bw,bh,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, 0, 0, null);
canvas.drawBitmap(bmp2, 0,0, null);
return bmOverlay;
}

(android) set homescreen wallpaper with the correct dimensions

i'm currently building an app and i want to change the wallpaper. So here is my code.
When the user sets the wallpaper i save the path to Shared Preferences.
Display display = getWindowManager().getDefaultDisplay();
SharedPreferences prefs = getBaseContext().getSharedPreferences(PREFS_NAME,0);
if (prefs.contains(d)) {
Bitmap bitmapOrg = BitmapFactory.decodeFile(prefs.getString(d, ""));
int newWidth = display.getWidth();
int newHeight = display.getHeight();
Bitmap resizedBitmap =Bitmap.createScaledBitmap(bitmapOrg, newWidth, newHeight, true);
myWallpaperManager.setBitmap(resizedBitmap);
}
and with that code i got something like this while i want to show the pictures like this
any idea how to do this?
Ok i found out how to do this.
First i create a new bitmap
newBmp = Bitmap.createBitmap(display.getWidth(), display.getHeight(), Bitmap.Config.ARGB_8888);
then the original bitmap resized:
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmapOrg, scaleWidth, scaleHeight, false);
then i call overlay to draw both images together. The first image has the dimensions of the display and the second is the image.
vate Bitmap overlay(Bitmap bmp1, Bitmap bmp2, int left, int imgsize) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, new Matrix(), null);
canvas.drawBitmap(bmp2, left-(imgsize/2), 15, null);
return bmOverlay;
}
and finally:
myWallpaperManager.setBitmap(newB);

Categories

Resources