package com.wajahatkarim3.longimagecamera;
import android.Manifest;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.MergeCursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraManager;
import android.media.Image;
import android.media.MediaScannerConnection;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.google.android.cameraview.CameraView;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.security.Permission;
import java.util.ArrayList;
public class LongImageCameraActivity extends AppCompatActivity {
private static final int MY_PERMISSIONS_REQUEST_CAMERA = 1002;
private static final int MY_PERMISSIONS_REQUEST_STORAGE = 1247;
public static final String IMAGE_PATH_KEY = "imagePathKey";
public static final int LONG_IMAGE_RESULT_CODE = 1234;
public final String TAG = LongImageCameraActivity.class.getSimpleName();
public enum ImageMergeMode {
HORIZONTAL,
VERTICAL
}
Button btnSnap;
ImageButton btnDone, btnFlashMode;
ImageView imgRecent;
CameraView cameraView;
ProgressBar progressBar;
boolean isFirstImage = true;
ArrayList<Bitmap> bitmapsList = new ArrayList<>();
private Handler mBackgroundHandler;
Bitmap finalBitmap;
ImageMergeMode mergeMode = ImageMergeMode.VERTICAL;
boolean showPreview = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_long_image_camera);
btnSnap = (Button) findViewById(R.id.btnSnap);
btnDone = (ImageButton) findViewById(R.id.btnDone);
btnFlashMode = (ImageButton) findViewById(R.id.btnFlashMode);
imgRecent = (ImageView) findViewById(R.id.imgRecent);
cameraView = (CameraView) findViewById(R.id.cameraView);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
imgRecent.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
btnDone.setVisibility(View.GONE);
btnSnap.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
btnSnapClick(view);
}
});
btnDone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
btnDoneClick(view);
}
});
btnFlashMode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
changeFlashMode();
}
});
checkForCameraPermission();
cameraView.addCallback(cameraCallback);
cameraView.setFlash(CameraView.FLASH_AUTO);
if (getIntent().getExtras() != null && getIntent().hasExtra("mergeMode"))
{
mergeMode = (ImageMergeMode) getIntent().getExtras().get("mergeMode");
}
}
@Override
protected void onResume() {
super.onResume();
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
if (permissionCheck == PackageManager.PERMISSION_GRANTED)
{
// Start camera
cameraView.start();
}
}
@Override
protected void onPause() {
cameraView.stop();
super.onPause();
}
public void changeFlashMode()
{
if (cameraView.getFlash() == CameraView.FLASH_AUTO)
{
cameraView.setFlash(CameraView.FLASH_ON);
btnFlashMode.setImageResource(R.drawable.ic_flash_on);
}
else if (cameraView.getFlash() == CameraView.FLASH_ON)
{
cameraView.setFlash(CameraView.FLASH_OFF);
btnFlashMode.setImageResource(R.drawable.ic_flash_off);
}
else if (cameraView.getFlash() == CameraView.FLASH_OFF)
{
cameraView.setFlash(CameraView.FLASH_AUTO);
btnFlashMode.setImageResource(R.drawable.ic_flash_auto);
}
}
public void btnSnapClick(View view)
{
cameraView.takePicture();
}
public void btnDoneClick(View view)
{
if (bitmapsList.size() <= 0) return;
if (mergeMode == ImageMergeMode.VERTICAL)
{
int width = bitmapsList.get(0).getWidth();
int height = 0;
for (Bitmap bitmap : bitmapsList)
{
height += bitmap.getHeight();
}
finalBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(finalBitmap);
float tempHeight = 0;
for (int i=0; i<bitmapsList.size(); i++)
{
Bitmap bitmap = bitmapsList.get(i);
canvas.drawBitmap(bitmap, 0f, tempHeight, null);
tempHeight += bitmap.getHeight();
}
}
else if (mergeMode == ImageMergeMode.HORIZONTAL)
{
int height = bitmapsList.get(0).getHeight();
int width = 0;
for (Bitmap bitmap : bitmapsList)
{
width += bitmap.getWidth();
}
finalBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(finalBitmap);
float tempWidth = 0;
for (int i=0; i<bitmapsList.size(); i++)
{
Bitmap bitmap = bitmapsList.get(i);
canvas.drawBitmap(bitmap, tempWidth, 0f, null);
tempWidth += bitmap.getWidth();
}
}
checkForFileWritePermission();
}
public void checkForFileWritePermission()
{
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck == PackageManager.PERMISSION_GRANTED)
{
// Save file
saveBitmap(finalBitmap);
}
else {
// ask for permission
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_STORAGE);
}
}
public void checkForCameraPermission()
{
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
if (permissionCheck == PackageManager.PERMISSION_GRANTED)
{
// Start camera
cameraView.start();
}
else {
// Ask for permissions here
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
// Show dialog explaning why we need camera permission here
showInfoDialog();
}
else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CAMERA);
}
}
}
public void showInfoDialog()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.dialog_title));
builder.setMessage(getString(R.string.dialog_message));
String positiveText = getString(android.R.string.ok);
builder.setPositiveButton(positiveText,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// positive button logic
// Ask for permission. User has agreed to grant it.
ActivityCompat.requestPermissions(LongImageCameraActivity.this,
new String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CAMERA);
}
});
String negativeText = getString(android.R.string.cancel);
builder.setNegativeButton(negativeText,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// negative button logic
// let it go then
}
});
AlertDialog dialog = builder.create();
// display dialog
dialog.show();
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_CAMERA: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
cameraView.start();
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
case MY_PERMISSIONS_REQUEST_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// save the image here now
saveBitmap(finalBitmap);
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
public CameraView.Callback cameraCallback = new CameraView.Callback() {
@Override
public void onCameraClosed(CameraView cameraView) {
super.onCameraClosed(cameraView);
}
@Override
public void onCameraOpened(CameraView cameraView) {
super.onCameraOpened(cameraView);
}
@Override
public void onPictureTaken(CameraView cameraView, byte[] data) {
super.onPictureTaken(cameraView, data);
Log.d(TAG, "onPictureTaken: Picture Taken");
if (isFirstImage)
{
imgRecent.setVisibility(View.VISIBLE);
btnDone.setVisibility(View.VISIBLE);
Animation downAnimation = AnimationUtils.loadAnimation(LongImageCameraActivity.this, R.anim.move_down_anim);
cameraView.startAnimation(downAnimation);
}
//Bitmap bitmapOriginal = BitmapFactory.decodeByteArray(data,0,data.length);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inPurgeable = true;
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length, options);
Bitmap croppedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth()*75/100, bitmap.getHeight());
bitmapsList.add(croppedBitmap);
imgRecent.setImageBitmap(croppedBitmap);
Log.d(TAG, "btnSnapClick: ");
Animation animation = AnimationUtils.loadAnimation(LongImageCameraActivity.this, R.anim.move_up_anim);
imgRecent.startAnimation(animation);
}
};
public void saveBitmap(Bitmap finalBitmap)
{
btnDone.setEnabled(false);
btnSnap.setEnabled(false);
btnFlashMode.setEnabled(false);
cameraView.setVisibility(View.INVISIBLE);
btnDone.setVisibility(View.INVISIBLE);
btnFlashMode.setVisibility(View.INVISIBLE);
progressBar.setVisibility(View.VISIBLE);
final String tmpImg = String.valueOf(System.currentTimeMillis()) + ".png";
File dstDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), getString(R.string.app_name));
dstDir.mkdirs();
final String destDirectoryPath = dstDir.getAbsolutePath();
final Bitmap bitmapToSave = finalBitmap;
getBackgroundHandler().post(new Runnable() {
@Override
public void run() {
File file = new File(destDirectoryPath, tmpImg);
OutputStream os = null;
try {
os = new FileOutputStream(destDirectoryPath + File.separator + tmpImg);
bitmapToSave.compress(Bitmap.CompressFormat.PNG, 100, os);
MediaScannerConnection.scanFile(LongImageCameraActivity.this, new String[] { (destDirectoryPath + File.separator + tmpImg) }, new String[] { "image/png" }, null);
//Toast.makeText(getApplicationContext(), "Image Saved Successfully!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
Log.w(TAG, "Cannot write to " + file, e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
// Ignore
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
btnDone.setEnabled(true);
btnSnap.setEnabled(true);
btnFlashMode.setEnabled(true);
progressBar.setVisibility(View.GONE);
btnDone.setVisibility(View.GONE);
btnFlashMode.setVisibility(View.VISIBLE);
btnSnap.setVisibility(View.VISIBLE);
isFirstImage = true;
bitmapsList.clear();
Intent resultIntent = new Intent();
resultIntent.putExtra(IMAGE_PATH_KEY, destDirectoryPath + File.separator + tmpImg);
setResult(Activity.RESULT_OK, resultIntent);
finish();
if (showPreview)
{
Intent ii = new Intent(LongImageCameraActivity.this, PreviewLongImageActivity.class);
ii.putExtra("imageName", destDirectoryPath + File.separator + tmpImg);
startActivity(ii);
}
}
});
}
}
});
}
private Handler getBackgroundHandler() {
if (mBackgroundHandler == null) {
HandlerThread thread = new HandlerThread("background");
thread.start();
mBackgroundHandler = new Handler(thread.getLooper());
}
return mBackgroundHandler;
}
public static void launch(Activity activity)
{
Intent ii = new Intent(activity, LongImageCameraActivity.class);
activity.startActivityForResult(ii, LONG_IMAGE_RESULT_CODE);
}
public static void launch(Activity activity, ImageMergeMode mergeMode)
{
Intent ii = new Intent(activity, LongImageCameraActivity.class);
ii.putExtra("mergeMode", mergeMode);
activity.startActivityForResult(ii, LONG_IMAGE_RESULT_CODE);
}
}