Xamarin Android Draw EditText on Bitmap - android

I have subclass of ImageView on which I can draw (pen, rect, elipse etc..) and add EditText subviews (draggable and can be rotated).
Problem is when I want to get final image I'm not sure how to merge those EditText into new image, because all the tools are drawing directly on canvas while I need to draw EditText texts at the end, since they need to be draggable and changable before user clicks Save.
After many different approaches, this one is most correct but it doesn't work if the text is rotated by some degree.
public Bitmap GetFinalBitmap()
{
this.DrawingCacheEnabled = false;
this.DrawingCacheEnabled = true;
var finalImage = Bitmap.CreateBitmap(GetDrawingCache(true));
foreach (var item in this.pathLists)
{
if (item.TextView != null)
{
item.TextView.BuildDrawingCache(true);
var txt = item.TextView.GetDrawingCache(true);
finalImage = Overlay(finalImage, txt, item.TextView.GetX(), item.TextView.GetY());
}
}
return finalImage;
}
public Bitmap Overlay(Bitmap bmp1, Bitmap bmp2, float x, float y)
{
Bitmap bmOverlay = Bitmap.CreateBitmap(bmp1.Width, bmp1.Height, bmp1.GetConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.DrawBitmap(bmp1, new Matrix(), null);
canvas.DrawBitmap(bmp2, x, y, null);
return bmOverlay;
}
Any help would be appreciated (update of solution or maybe new approach on how to draw EditText with correct coordinates on ImageView's bitmap).

Basically all I had to do was draw second bitmap (one of the EditText) using matrix. Here is updated code that works even for rotated EditText.
public Bitmap Overlay(Bitmap bmp1, Bitmap bmp2, float x, float y, float rotation)
{
Bitmap bmOverlay = Bitmap.CreateBitmap(bmp1.Width, bmp1.Height, bmp1.GetConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.DrawBitmap(bmp1, new Matrix(), null);
var matrix = new Matrix();
matrix.Reset();
if (rotation > 0)
matrix.PostRotate(rotation, bmp2.Width / 2, bmp2.Height / 2);
matrix.PostTranslate(x, y);
canvas.DrawBitmap(bmp2, matrix, null);
return bmOverlay;
}

Related

DrawBitmap placing bitmap in the wrong location

I want to place a bitmap on top of another bitmap, I have done that with the method below. The bitmap is the current bitmap that will have another bitmap placed on top. Marker bitmap is the bitmap that is to be placed on top of the current bitmap. x and y are the locations of the tap, these are correct to my knowledge because the on tap listener does recognize the location but displays the bitmap in the wrong location.
public Bitmap drawOnToCanvas(Bitmap bitmap){
float centerX = (x - (markerBitmap.getWidth()/2));
float centerY = (y + (markerBitmap.getHeight()/2));
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bitmap, new Matrix(), null);
canvas.drawBitmap(markerBitmap, centerX , centerY, null);
return bitmap;
}
I found the problem when you draw the bitmap for the current bitmap make sure you get the matrix and not just make a new matrix. Example fix is below:
public Bitmap drawOnToCanvas(Bitmap bitmap, Matrix currentMatrix){
float centerX = (x - (markerBitmap.getWidth()/2));
float centerY = (y + (markerBitmap.getHeight()/2));
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bitmap, currentMatrix, null);
canvas.drawBitmap(markerBitmap, centerX , centerY, null);
return bitmap;
}

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;
}

Draw Bitmap on another Bitmap with same width and height

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.

merge two images (one image is transparent without face , second image is only face which coming from sdcard)

I have a two image one image is containing body without face and one image contain with face only...
now I want to merge this two images.... the first image which contain only body without face is in that the face is transparent.....
So how can I detect that transparent area and place face over there in transparent area?
I am combining two images with below code.. but it is not proper way to place face over transparent area
My code is given below,
public Bitmap combineImages(Bitmap c, Bitmap s) {
Bitmap cs = null;
int width, height = 0;
if (c.getWidth() > s.getWidth()) {
width = c.getWidth() + s.getWidth();
height = c.getHeight();
} else {
width = s.getWidth() + s.getWidth();
height = c.getHeight();
}
cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(cs);
comboImage.drawBitmap(c, 0f, 0f, null);
comboImage.drawBitmap(s, 0f, 0f, null);
return cs;
}
Merge two or more images in android by using Canvas its simple to merge image by using below code,
first create bitmap for particular image which you want to merge it.
get X and Y axis position for which area you want to merge images.
mComboImage = new Canvas(mBackground);
mComboImage.drawBitmap(c, x-axis position in f, y-axis position in f, null);
mComboImage.drawBitmap(c, 0f, 0f, null);
mComboImage.drawBitmap(s, 200f, 200f, null);
mBitmapDrawable = new BitmapDrawable(mBackground);
Bitmap mNewSaving = ((BitmapDrawable)mBitmapDrawable).getBitmap();
set this new bitmap in imageview.
imageView.setImageBitmap(mNewSaving);
Here in this method two image bitmap combine in one bitmap which return bitmap of new merge image.Also save this image on sdcard.As below code
public Bitmap combineImages(Bitmap c, Bitmap s) {
Bitmap cs = null;
int width, height = 0;
if(c.getWidth() > s.getWidth()) {
width = c.getWidth();
height = c.getHeight() + s.getHeight();
} else {
width = s.getWidth();
height = c.getHeight() + s.getHeight();
}
cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(cs);
comboImage.drawBitmap(c, new Matrix(), null);
comboImage.drawBitmap(s, new Matrix(), null);
// this is an extra bit I added, just incase you want to save the new image somewhere and then return the location.
return cs;
}
}
Here is the proper way to merge two bitmaps:
public Bitmap combineImages(Bitmap topImage, Bitmap bottomImage) {
Bitmap overlay = Bitmap.createBitmap(bottomImage.getWidth(), bottomImage.getHeight(), bottomImage.getConfig());
Canvas canvas = new Canvas(overlay);
canvas.drawBitmap(bottomImage, new Matrix(), null);
canvas.drawBitmap(topImage, 0, 0, null);
return overlay;
}

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;
}

Categories

Resources