I have a requirement that I need to create a custom camera and allow the user to place the logo during image capture. The logo can be enlarged / resized and moved anywhere. I wrote the following code to do this, I was able to successfully enlarge / reduce the image and move the logo, but when I combine both the logo and the image taken from the camera, it does not fit correctly. The image of the logo placed elsewhere has been reduced. Please help me with this, as I am stuck here and could not find what is wrong. I also attached screenshots taken in my phone for reference. Please check this out.
I moved the logo to the lower left corner before clicking on the capture button
After clicking on the capture button, both images are combined as follows.
public class CustomCamera extends Activity implements OnTouchListener,
SurfaceHolder.Callback {
private Matrix matrix = new Matrix();
private Matrix savedMatrix = new Matrix();
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE;
private PointF start = new PointF();
private PointF mid = new PointF();
private float oldDist = 1f;
private float d = 0f;
private float newRot = 0f;
private float[] lastEvent = null;
String logoImageId = "";
Bitmap bitmap = null;
private Camera camera = null;
private SurfaceView cameraSurfaceView = null;
private SurfaceHolder cameraSurfaceHolder = null;
private boolean previewing = false;
RelativeLayout relativeLayout;
int currentCameraId = 0;
private Button btnCapture = null;
ImageButton useOtherCamera = null;
ImageView logoImageView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.camera_layout);
logoImageView = (ImageView) findViewById(R.id.logoImageView);
Bundle extras = getIntent().getExtras();
if (extras != null) {
logoImageId = extras.getString("logoImageId ");
}
try {
File file = new File(Environment.getExternalStorageDirectory()
+ "/" + getPackageName() + "/logo/" + logoImageId
+ ".jpg");
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
logoImageView.setImageBitmap(bitmap);
logoImageView.setOnTouchListener(this);
relativeLayout = (RelativeLayout) findViewById(R.id.containerImg);
relativeLayout.setDrawingCacheEnabled(true);
cameraSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
cameraSurfaceHolder = cameraSurfaceView.getHolder();
cameraSurfaceHolder.addCallback(this);
btnCapture = (Button) findViewById(R.id.button);
btnCapture.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
camera.takePicture(null, null, cameraPictureCallbackJpeg);
}
});
}
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
lastEvent = null;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
lastEvent = new float[4];
lastEvent[0] = event.getX(0);
lastEvent[1] = event.getX(1);
lastEvent[2] = event.getY(0);
lastEvent[3] = event.getY(1);
d = rotation(event);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
lastEvent = null;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
matrix.set(savedMatrix);
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
matrix.postTranslate(dx, dy);
} else if (mode == ZOOM) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = (newDist / oldDist);
matrix.postScale(scale, scale, mid.x, mid.y);
}
if (lastEvent != null && event.getPointerCount() == 3) {
newRot = rotation(event);
float r = newRot - d;
float[] values = new float[9];
matrix.getValues(values);
float tx = values[2];
float ty = values[5];
float sx = values[0];
float xc = (view.getWidth() / 2) * sx;
float yc = (view.getHeight() / 2) * sx;
matrix.postRotate(r, tx + xc, ty + yc);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
private float rotation(MotionEvent event) {
double delta_x = (event.getX(0) - event.getX(1));
double delta_y = (event.getY(0) - event.getY(1));
double radians = Math.atan2(delta_y, delta_x);
return (float) Math.toDegrees(radians);
}
PictureCallback cameraPictureCallbackJpeg = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap cameraBitmap = BitmapFactory.decodeByteArray(data, 0,
data.length);
int wid = cameraBitmap.getWidth();
int hgt = cameraBitmap.getHeight();
Bitmap newBitmap = Bitmap.createBitmap(wid, hgt,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawBitmap(cameraBitmap, 0f, 0f, null);
canvas.drawBitmap(bitmap, matrix, null);
File storagePath = new File(
Environment.getExternalStorageDirectory() + "/PhotoAR/");
storagePath.mkdirs();
File myImage = new File(storagePath, Long.toString(System
.currentTimeMillis()) + ".jpg");
try {
FileOutputStream out = new FileOutputStream(myImage);
newBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
out.flush();
out.close();
} catch (FileNotFoundException e) {
Log.d("In Saving File", e + "");
} catch (IOException e) {
Log.d("In Saving File", e + "");
}
}
};
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if (previewing) {
camera.stopPreview();
previewing = false;
}
try {
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
camera.setDisplayOrientation(90);
}
camera.setPreviewDisplay(cameraSurfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera = Camera.open();
} catch (RuntimeException e) {
Toast.makeText(
getApplicationContext(),
"Device camera is not working properly, please try after sometime.",
Toast.LENGTH_LONG).show();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
and this is my xml
<FrameLayout 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" >
<RelativeLayout
android:id="@+id/containerImg"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
<ImageView
android:id="@+id/logoImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/app_name"
android:scaleType="matrix" />
</RelativeLayout>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:background="@drawable/camera" />
Thanks in advance.