Hello There I am coding a Camera App using Android Camera API!
It has the following functions:
- The app has an image view over the camera preview
- The user can drag and drop that image view on the camera preview
- The drop event catch the position of the image view where it dropped
- The user captures an image and the image view is being added on the photo on the user's desired drag then dropped location
Here is the code that is used for the image view drag and drop:
@Override
public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
xloc=X;
yloc=Y;
Toast.makeText(getContext(), "Location==="+Integer.toString(xloc)+"==="+Integer.toString(yloc), Toast.LENGTH_SHORT).show();
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
view.setLayoutParams(layoutParams);
break;
}
mRrootLayout.invalidate();
return true;
}
The xloc and yloc contains the postion where the user will drop that image view!
This is the code I am using to determine the device orientation. It is being done by the sensor because the activity is set to portrait in manifest.xml by default
@Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
if (x < 5 && x > -5 && y > 5){
//portrait UP ↑↑↑
cam_orientation = 0;
image_watermark.setRotation(0); //rotating the water mark with screen orientation
}
else if (x<-5 && y<5 && y>-5) {
//landscape RIGHT →→→
cam_orientation = 3;
image_watermark.setRotation(270);
}
else if (x<5 && x>-5 && y<-5) {
//Portrait DOWN ↓↓↓
cam_orientation = 4;
image_watermark.setRotation(0);
}
else if (x>5 && y<5 && y>-5){
//Landscape LEFT ←←←
cam_orientation = 1;
image_watermark.setRotation(90);
}
}
Here is the code for capturing the image
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(1);
if (pictureFile == null){
Log.i("#LOGTAG pic","Exception");
return;
}
try {
//rotate the image view as expected
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
if(cam_orientation==0){
//portrait UP ↑↑↑
if(cam_id==1){
//this is front camera id=1
mBitmap= rotate(mBitmap, 270);
mBitmap=flip(mBitmap);
}
if(cam_id==0){
mBitmap= rotate(mBitmap, 90);
}
}
if(cam_orientation==1){
//Landscape LEFT ←←←
if(cam_id==1){
//this is front camera id=1
mBitmap= rotate(mBitmap, 0);
mBitmap=flip(mBitmap);
}
if(cam_id==0){
//this is back camera id=0
mBitmap= rotate(mBitmap, 0);
}
}
if(cam_orientation==3){
//landscape RIGHT →→→
if(cam_id==1){
//this is front camera id=1
mBitmap= rotate(mBitmap, 180);
mBitmap=flip(mBitmap);
}
if(cam_id==0){
//this is back camera id=0
mBitmap= rotate(mBitmap, 180);
}
}
if(cam_orientation==4){
//Portrait DOWN ↓↓↓
if(cam_id==1){
//this is front camera id=1
mBitmap= rotate(mBitmap, 90);
mBitmap=flip(mBitmap);
}
if(cam_id==0){
//this is back camera id=0
mBitmap= rotate(mBitmap, 270);
}
}
//add the water mark to the camera photo bitmap here
Bitmap mutableBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true);
image_watermark.buildDrawingCache();
Bitmap bmap = image_watermark.getDrawingCache();
Bitmap final_image=Bitmap.createScaledBitmap(bmap,(image_watermark.getMeasuredWidth())*2,(image_watermark.getMeasuredWidth())*2,false);
Canvas canvas = new Canvas(mutableBitmap);
if(cam_id==1){
canvas.drawBitmap(icon,(int)(xloc*1.5),(int)(yloc*1.5), null); //setting the location of the water mark image view on front camera/photo
}
if(cam_id==0){
canvas.drawBitmap(icon,xloc*2,yloc*2, null);
//setting the location of the water mark image view on back camera/photo
}
FileOutputStream fos = new FileOutputStream(pictureFile);
mutableBitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
fos.close();
}
I have a problem of setting up the location of water mark image view on the captured photo from the camera! I just want to set the location of the water mark image view to be set where the user dragged and dropped that water mark image view.
Though the code works alright, but there is a lack of precision and accuracy in setting up the water mark image view location on captured photo for different devices.
I have been trying on different devices, but each device distorts the accurate position.
Can somebody give me any idea or a better approach to add a water mark image on the camera captured photo!
Please Note That the ids for camera are:
cam_id=1 for the from camera
cam_id=0 for the back camera
I need an approach, so that I could able to position my water mark image on all device orientation modes and for at least some multiple devices.
Suppose that if i drag my image view on this blue button when the screen is in portrait position, the image should be save on the camera captured photo on the same location that is on the blue button!
Similarly, if i placed it on that box the camera captured photo should position this image view same on that box in landscape mode!
Here is the used XML below
<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="">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/colorAccent">
<ToggleButton
android:id="@+id/flipper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:background="@drawable/my_btn_toggle"
android:textOff=""
android:textOn=""/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="10"
android:id="@+id/root">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/camera_preview">
</FrameLayout>
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/watermark"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#000"
android:layout_alignParentBottom="true"
android:gravity="center"
android:id="@+id/capture_layout">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/capture"
android:text="Capture"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/neg"
android:text="Cancel Para"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>