I'm working with eclipse to develop a custom camera app for android. I've figured out how to display the preview of the camera, but I can't figure out how to take a picture without saving the image. When a picture is taken, I don't want to save the image or display it to the screen, I simply want it saved to a data type that I can use within the app and overwrite when another picture is taken.
Edit:
public class MainActivity extends Activity {
private Camera mCamera;
private CameraPreview mCameraPreview;
private Bitmap picture;
private static Uri mImageCaptureUri;
private static Bitmap photo = null;
private byte[] image;
private int PICK_FROM_CAMERA = 1;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
#Override
protected void onCreate(Bundle savedInstanceState) {
releaseCameraAndPreview();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) return;
else{
Bundle extras = data.getExtras();
if (extras != null) {
photo = extras.getParcelable("data");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 100, bos);
image = bos.toByteArray();
}
File f = new File(mImageCaptureUri.getPath());
if (f.exists()){
f.delete();
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
//creates camera class for functions
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
Log.v("Schweigen", "camera will not open");
}
return camera;
}
//releases camera on completion
private void releaseCameraAndPreview() {
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
Log.v("Schweigen", "onShutter");
}
};
/** Handles data for raw picture */
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.v("Schweigen", "onPictureTaken");
}
};
/** Handles data for jpeg picture */
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
//picture = BitmapFactory.decodeByteArray(data , 0, data.length);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
try {
intent.putExtra("return-data", true);
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
};
}
Make a Uri from the picture.
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Uri uriSavedImage=Uri.fromFile(new File(Environment.getExternalStorageDirectory().toString()+"/ImagesFolder/image.jpg"));
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
Edit: After that you may store it in a byte[].
As I told you, you have to get the the Intent from the Camera and set it to a Uri:
private static Uri mImageCaptureUri;
private static Bitmap photo = null;
private byte[] image;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
"tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
try {
intent.putExtra("return-data", true);
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) return;
else{
Bundle extras = data.getExtras();
if (extras != null) {
photo = extras.getParcelable("data");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 100, bos);
image = bos.toByteArray();
}
File f = new File(mImageCaptureUri.getPath());
if (f.exists()) f.delete();
}
}
The API to directly take a picture is here.
Related
I am trying to put an image on my fragment, but the image is not showing up. I am certain that it was working just yesterday but now it is not. Any help is appreciated.
This code is in my Fragment:
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mUser = (User) getArguments().getSerializable(ARGS_USER);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.fragment_picture_picker, container, false);
mImageView = v.findViewById(R.id.imageView);
mSelectImageButton = v.findViewById(R.id.select_image);
mSelectImageButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, IMG_REQUEST);
}
});
return v;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == IMG_REQUEST && resultCode == Activity.RESULT_OK && data != null){
Uri path = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), path);
mImageView.setImageBitmap(bitmap);
mImageView.setVisibility(View.VISIBLE);
mUser.setProfilePicture(bitmap);
}catch(IOException e){
e.printStackTrace();
}
}
}
Actually you are not using the Volley. Please change the heading of your question. You are accessing the Gallery and showing the image inside the imageView. Use the below code for accessing the image from camera as well as gallery.
if (action.equals("CAMERA")) {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, ACTION_REQUEST_CAMERA);
} else {
openCamera();
}
} else if (action.equals("GALLERY")) {
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, ACTION_REQUEST_GALLERY);
} else {
openGallery();
}
}
private void openCamera(){
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
getActivity().startActivityForResult(cameraIntent, ACTION_REQUEST_CAMERA);
}
private void openGallery(){
Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
Intent chooser = Intent.createChooser(galleryIntent, "Choose a Picture");
getActivity().startActivityForResult(chooser, ACTION_REQUEST_GALLERY);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
System.out.println("OnActivityResult");
System.out.println("resultCode: "+resultCode+"\n"+"requestCode: "+requestCode);
ImageOperations operations = new ImageOperations();
if (resultCode == RESULT_OK) {
if (requestCode == ACTION_REQUEST_GALLERY) {
System.out.println("select file from gallery ");
Uri selectedImageUri = data.getData();
renderProfileImage(selectedImageUri,operations);
} else if (requestCode == ACTION_REQUEST_CAMERA) {
System.out.println("select file from camera ");
Bitmap photo = (Bitmap) data.getExtras().get("data");
String name = "profile_pic.png";
operations.saveImageToInternalStorage(photo,getActivity(),name);
profile_image.setImageBitmap(photo);
}
}
}
private void renderProfileImage(Uri selectedImageUri,ImageOperations operations) {
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), selectedImageUri);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bytes);
String name = "profile_pic.png";
operations.saveImageToInternalStorage(bitmap,getActivity(),name);
profile_image.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
private class ImageOperations {
public boolean saveImageToInternalStorage(Bitmap image, Context context, String name) {
try {
// Use the compress method on the Bitmap object to write image to
// the OutputStream
FileOutputStream fos = context.openFileOutput("profile_pic.png", Context.MODE_PRIVATE);
// Writing the bitmap to the output stream
image.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
return true;
} catch (Exception e) {
Log.e("saveToInternalStorage()", e.getMessage());
return false;
}
}
public Bitmap getThumbnail(Context context,String filename) {
String fullPath = Environment.getDataDirectory().getAbsolutePath();
Bitmap thumbnail = null;
// Look for the file on the external storage
try {
if (isSdReadable() == true) {
thumbnail = BitmapFactory.decodeFile(fullPath + "/" + filename);
}
} catch (Exception e) {
Log.e("Image",e.getMessage());
}
// If no file on external storage, look in internal storage
if (thumbnail == null) {
try {
File filePath = context.getFileStreamPath(filename);
FileInputStream fi = new FileInputStream(filePath);
thumbnail = BitmapFactory.decodeStream(fi);
} catch (Exception ex) {
Log.e("getThumbnail()", ex.getMessage());
}
}
return thumbnail;
}
public boolean isSdReadable() {
boolean mExternalStorageAvailable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = true;
Log.i("isSdReadable", "External storage card is readable.");
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
Log.i("isSdReadable", "External storage card is readable.");
mExternalStorageAvailable = true;
} else {
// Something else is wrong. It may be one of many other
// states, but all we need to know is we can neither read nor write
mExternalStorageAvailable = false;
}
return mExternalStorageAvailable;
}
}
action is like what you want to do. ACTION_REQUEST_GALLERY and ACTION_REQUEST_CAMERA use some integer constants like 100 and 101. profileImage is your ImageView.
I have an activity that starts the camera API.
I want to press the button (named by id "cptr_1") and take a picture and display it in another activity (PhotoPreview.class) where I can add photo effects.
I just need the code for:
ImageButton capture_1 = (ImageButton)findViewById(R.id.cptr_1);
capture_1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
And then how to transfer that image to PhotoPreview.class
You can take photo with the camera app of the device.
So when you click:
static final int ImageValue= 1;
ImageButton capture_1 = (ImageButton)findViewById(R.id.cptr_1);
capture_1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent takepic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takepic.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takepic, ImageValue);
}
}
});
Once capture is completed get the image back from the camera application
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ImageValue && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
}
}
Then send Bitmap to another activity.
Inside the activity that starts the camera API write:
Intent intent = new Intent(this, PhotoPreview.class);
intent.putExtra("GetBitmap", bitmap);
Inside PhotoPreview.class write:
Intent intent = getIntent();
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("GetBitmap");
Also you may need to add those permissions to Android Manifest
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
either you can use an Intent to take picture or use a custom camera class
for camera intent for custom camera class
if u already have a custom camera class, you can use this code`Camera cam = Camera.open(cameraId);
capture_1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
cam.takePicture(null, null, mPicture);
} catch (Exception e) {
}
}
});
private PictureCallback mPicture = new PictureCallback() {
public void onPictureTaken(final byte[] data, Camera camera) {
try {
File mediaFile = new File("file path/filename.jpg");
FileOutputStream fos = new FileOutputStream(mediaFile);
fos.write(data);
fos.close();
cam.startPreview();
} catch (Exception e) {
}
}
};`
I've been following the Camera API Demo from the android developer site. After fixing alot of stuf i've come to my last problem. I want to use the picture i've just taken and display it in another activity (like when after you take a picture you first gotta accept it or redo it style).
My TakePhoto class :
public class TakePhoto extends Activity {
public static final int MEDIA_TYPE_IMAGE = 1;
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
ImageButton captureButton;
private Camera mCamera;
private CameraPreview mPreview;
private Handler handler = new Handler();
private int SELECT_PICTURE = 1;
private String selectedImagePath;
FrameLayout preview;
private String documentType;
private Camera.Parameters p;
private PictureCallback mPicture = new PictureCallback() {
private String TAG = "DocsPro";
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
Log.d(TAG, "Error creating media file, check storage permissions : PICTURE FILE IS NULL");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
Log.d(TAG, "fos.new");
fos.write(data);
Log.d(TAG, "fos.write");
fos.close();
Log.d(TAG, "fos.close");
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
//Accessing cameras
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.scan);
Intent myIntent = getIntent();
documentType = myIntent.getStringExtra("documentType");
Button terug = (Button) findViewById(R.id.button_terug);
ImageButton iTerug = (ImageButton) findViewById(R.id.imageButton_terug);
ImageButton gallery = (ImageButton) findViewById(R.id.button_galery);
ImageButton flash = (ImageButton) findViewById(R.id.button_flash);
preview = (FrameLayout) findViewById(R.id.camera_preview);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(TakePhoto.this, mCamera);
captureButton = (ImageButton) findViewById(R.id.button_capture);
preview.addView(mPreview);
captureButton.bringToFront();
gallery.bringToFront();
flash.bringToFront();
p = mCamera.getParameters();
gallery.setOnClickListener(
new OnClickListener(){
#Override
public void onClick(View v)
{
// in onCreate or any event where your want the user to
// select a file
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
}
);
flash.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(p.getFlashMode() == android.hardware.Camera.Parameters.FLASH_MODE_ON){
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(p);
mCamera.startPreview();
Log.e("Torch","MODE ON");
}else if(p.getFlashMode() == android.hardware.Camera.Parameters.FLASH_MODE_OFF){
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(p);
mCamera.release();
mCamera=null;
Log.e("Torch","MODE OFF");
}else if(p.getFlashMode() == android.hardware.Camera.Parameters.FLASH_MODE_AUTO){
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(p);
mCamera.startPreview();
Log.e("Torch","MODE AUTO");
}else if(p.getFlashMode() == android.hardware.Camera.Parameters.FLASH_MODE_TORCH){
p.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
mCamera.setParameters(p);
mCamera.startPreview();
Log.e("Torch","MODE TORCH");
}else{
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(p);
mCamera.startPreview();
Log.e("Torch","MODE ELSE");
}
}
});
// Add a listener to the Capture button
captureButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the camera
handler.postDelayed(new Runnable() {
#Override
public void run() {
mCamera.autoFocus(autoFocusCallback);
}
}, 1500L);
}
AutoFocusCallback autoFocusCallback=new AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
mCamera.takePicture(null, null, mPicture);
}
};
});
// Add listeners to Terug buttons
terug.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(TakePhoto.this, PickDocumentType.class);
startActivity(intent);
finish();
}
});
// Add listeners to Terug buttons
iTerug.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(TakePhoto.this, PickDocumentType.class);
startActivity(intent);
finish();
}
});
}
/**
* A safe way to get an instance of the Camera object.
*/
public static Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
} catch (Exception e) {
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
/**
* Create a File for saving an image or video
*/
#SuppressLint("SimpleDateFormat")
private static File getOutputMediaFile(int type) {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "DocsPro");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_" + timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
/**
* helper to retrieve the path of an image URI
*/
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if(cursor!=null)
{
//HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
//THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
else return null;
}
#Override
protected void onPause() {
super.onPause();
releaseCamera(); // release the camera immediately on pause event
}
private void releaseCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
#Override
public void onStop()
{
super.onStop();
releaseCamera();
}
//Receiving camera intent result.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Image captured and saved to fileUri specified in the Intent
Log.d("foto", "Image saved to:\n" +
data.getData());
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
else if (requestCode == SELECT_PICTURE)
{
if (resultCode == RESULT_OK) {
releaseCamera();
Uri selectedImageUri = data.getData();
//MEDIA GALLERY
selectedImagePath = getPath(selectedImageUri);
Intent edit = new Intent(TakePhoto.this, EditPhoto.class);
edit.putExtra("filepath", selectedImagePath);
edit.putExtra("documentType", documentType);
startActivity(edit);
finish();
releaseCamera();
}
}
}
}
How do i get the image taken in the above class and transfer it to my new activity?
EDIT SOLUTION OF MY OWN :
I remembered that i had a method that would create the directory for my image, so i knew the location. Only trick was to get the filepath. And because the method getOutputMediaFile was saved in a File I just had to getAbsolutePath() and sent it with the intent :
String filepath = pictureFile.getAbsolutePath();
Intent edit = new Intent(TakePhoto.this, EditPhoto.class);
edit.putExtra("filepath", filepath);
startActivity(edit);
finish();
Then in the other activity i just get it like this and display it:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.bijsnijden);
Intent myIntent = getIntent();
imagePath = myIntent.getStringExtra("filepath");
documentType = myIntent.getStringExtra("documentType");
ImageView imageView = (ImageView) findViewById(R.id.Image);
imageView.setImageBitmap(BitmapFactory.decodeFile(imagePath));
}
Convert it to a Byte array before you add it to the intent, send it out, and decode.
//Convert to byte array
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image",byteArray);
Then in Activity 2:
byte[] byteArray = getIntent().getByteArrayExtra("image");
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
It's bugging me for few days know. Problem is that I don't know if I'm going in right direction.
My starting activity is ImageDisplay class which calls startActivityForRestult for CustomCamera activity. After picture is taken user is returned to ImageDisplay and capture image should be displayed, but its not. What am I doing wrong?
Second thing, I guess its really important, at which point camera should be released?
ImageDisplay:
public class ImageDisplay extends Activity{
ImageView imageHolder;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.al_imagedisplay);
imageHolder = (ImageView) findViewById(R.id.imageView1);
Intent intent = new Intent(this, CustomCamera.class);
startActivityForResult(intent, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0 && resultCode == RESULT_OK) {
Bitmap photo = (Bitmap) data.getExtras().get("result");
imageHolder.setImageBitmap(photo);
}
}
}
CustomCamera:
public class CustomCamera extends Activity {
private Camera mCamera;
private NewItemSurfaceView mPreview;
Button captureButton;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
public static final String MY_CAMERRA_APP = "MyCameraApp";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.al_newitem_camera);
captureButton = (Button) findViewById(R.id.buttonClick);
// Create an instance of Camera
mCamera = getCameraInstance();
mCamera.setDisplayOrientation(90);
// Create our Preview view and set it as the content of our activity.
mPreview = new NewItemSurfaceView(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.flCamera);
preview.addView(mPreview);
// Add a listener to the Capture button
captureButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
});
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
} catch (Exception e) {
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
Log.d("Camera error",
"Error creating media file, check storage permissions: ");
return;
}
Log.i("Picture", pictureFile.toString());
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d("Camera error", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("Camera error", "Error accessing file: " + e.getMessage());
}
Intent returnIntent = new Intent();
returnIntent.putExtra("result", pictureFile);
setResult(RESULT_OK, returnIntent);
finish();
}
};
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type) {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
"MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.i("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
} else if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
}
modify onActivityResult method like this
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0 && resultCode == RESULT_OK) {
String photoPath = (String) data.getExtras().get("result");
imageHolder.setImageBitmap(BitmapFactory.decodeFile("photoPath"));
}
}
Do some modification in your onPictureTaken method like this
Intent returnIntent = getIntent();
returnIntent.putExtra("result", pictureFile.getAbsolutePath());
setResult(RESULT_OK, returnIntent);
finish();
I have complete working code to take a picture, crop it, send email with image attachment.
Here is the flow of the code:
Take a picture > Find and select the picture we just took from Gallery > Crop it > Email attachment.
I would like to find out how I can skip the whole "Find and select the picture we just took from Gallery" part out and just go straight into cropping immediately after taking the picture.
Is there an Intent that can do what I am requesting?
I've tried this tutorial but it still makes the user go into gallery and look for the picture they just took
http://www.londatiga.net/featured-articles/how-to-select-and-crop-image-on-android/
EDIT I should also mention that I have a custom view when I am taking pictures so Im not sure if I can use Intent MediaStore.ACTION_IMAGE_CAPTURE
Here is the code that executes the cropping AND also makes you choose the image you just took by looking in the gallery.
Intent crop_pic = new Intent(Intent.ACTION_PICK, uriTarget); // used to be ACTION_GET_CONTENT /ACTION_PICK
crop_pic.putExtra("crop", "true"); // this enables crop feature
//crop_pic.putExtra("aspectX", 200); // this defines the aspect ration
//crop_pic.putExtra("aspectY", 150);
//crop_pic.putExtra("outputX", 500); // this defines the output bitmap size
//crop_pic.putExtra("outputY", 500);
//crop_pic.putExtra("scale", true);
try { crop_pic.putExtra("return-data", false); // true to return a Bitmap, false to directly save the cropped iamge
crop_pic.putExtra(MediaStore.EXTRA_OUTPUT, uriTarget); // save output image in uri
//crop_pic.setDataAndType(uriTarget, "image/*"); // this will open all images in the Galery
startActivityForResult(crop_pic, EMAIL_PIC);
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
}
catch (ActivityNotFoundException e) {
toast.showToastDialog(getApplicationContext(), e.toString());
}
LOGCAT.DEBUG(TAG, "Cropping Picture");
}
Is there an Intent im not aware of that can just start cropping if I supply it with a uri Target?
Here is the full code:
public class DigitalSignature extends Activity implements SurfaceHolder.Callback{
Camera camera;
SurfaceHolder surfaceHolder;
boolean previewing = false;
Uri uriTarget;
String[] recipients = new String[]{"test#gmail.com", "",};
final int CROP_PIC = 1, EMAIL_PIC = 2, RETURN_ACTIVITY = 3, FINISH = 4, INDEX_GALLERY = 5;
final String TAG = "Digital Signature";
ToastBuilder toast = new ToastBuilder(this);
ProjectDebug LOGCAT = new ProjectDebug();
ProgressDialogManager pDialog = new ProgressDialogManager();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DigitalSignature.this.requestWindowFeature(Window.FEATURE_NO_TITLE);
DigitalSignature.this.setContentView(R.layout.digitalsignature);
DigitalSignature.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
DigitalSignature.this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
DigitalSignature.this.getWindow().setFormat(PixelFormat.TRANSLUCENT); // Used to be TRANSPARENT
SurfaceView surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(DigitalSignature.this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
LayoutInflater controlInflater = LayoutInflater.from(getApplicationContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
DigitalSignature.this.addContentView(viewControl, layoutParamsControl); // Applying Filters and Parameters
TextView alignsig = (TextView)findViewById(R.id.alignsig);
alignsig.setText("Please take picture of the signature for" + "\n" + "Job Number " + DIGIJOB);
Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
LOGCAT.DEBUG(TAG, "Taking Picture");
// Sets camera monochrome filter ( Black and Whiite )
Camera.Parameters parameters = camera.getParameters();
parameters.setColorEffect(android.hardware.Camera.Parameters.EFFECT_MONO);
camera.setParameters(parameters);
camera.startPreview();
// Initiate Camera Focus
camera.autoFocus(mAutoFocusCallback);
// Creates Directory to save image in gallery
uriTarget = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());
//Notify the MediaScanner that a new file has been added and should be indexed so it shows up in the MediaStore.
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(uriTarget);
sendBroadcast(intent);
}
});
}
Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
camera.takePicture(myShutterCallback, myPictureCallback_RAW, myPictureCallback_JPG);
}
};
ShutterCallback myShutterCallback = new ShutterCallback(){
#Override
public void onShutter() {
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
//bmp = BitmapFactory.decodeByteArray(arg0, 0, arg0.length);
cropPic();
OutputStream imageFileOS;
try {
imageFileOS = getContentResolver().openOutputStream(uriTarget);
imageFileOS.write(arg0);
imageFileOS.flush();
imageFileOS.close();
toast.showToastDialog(getApplicationContext(), "Image saved: " + uriTarget.toString());
}
catch (IOException e) {
toast.showToastDialog(getApplicationContext(), e.toString());
}
// camera.startPreview(); // No need to start preview, we are saving
}}; // picture and no longer initiating camera
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case CROP_PIC:
cropPic();
LOGCAT.DEBUG(TAG, "cropPic Case");
break;
case EMAIL_PIC:
emailPic();
LOGCAT.DEBUG(TAG, "emailPic Case");
break;
case RETURN_ACTIVITY:
returnActivity();
LOGCAT.DEBUG(TAG, "returnActivity Case");
break;
}
}
private void cropPic() {
Intent crop_pic = new Intent(Intent.ACTION_PICK, uriTarget); // used to be ACTION_GET_CONTENT /ACTION_PICK
crop_pic.putExtra("crop", "true"); // this enables crop feature
//crop_pic.putExtra("aspectX", 200); // this defines the aspect ration
//crop_pic.putExtra("aspectY", 150);
//crop_pic.putExtra("outputX", 500); // this defines the output bitmap size
//crop_pic.putExtra("outputY", 500);
//crop_pic.putExtra("scale", true);
try { crop_pic.putExtra("return-data", false); // true to return a Bitmap, false to directly save the cropped iamge
crop_pic.putExtra(MediaStore.EXTRA_OUTPUT, uriTarget); // save output image in uri
//crop_pic.setDataAndType(uriTarget, "image/*"); // this will open all images in the Galery
startActivityForResult(crop_pic, EMAIL_PIC);
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
}
catch (ActivityNotFoundException e) {
toast.showToastDialog(getApplicationContext(), e.toString());
}
LOGCAT.DEBUG(TAG, "Cropping Picture");
}
private void emailPic(){
// new email_pic().execute();
GMailSender m = new GMailSender("username#gmail.com", "testtest");
String[] toArr = { "sendingto#gmail.com" };
m.setTo(toArr);
m.setFrom("sendingto#gmail.com");
m.setSubject("This is an email sent using my Mail JavaMail wrapper from an Android device.");
m.setBody("Email body.");
try {
m.addAttachment(getRealPathFromURI(uriTarget));
if(m.send()) {
Toast.makeText(DigitalSignature.this, "Email was sent successfully.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(DigitalSignature.this, "Email was not sent.", Toast.LENGTH_LONG).show();
}
} catch(Exception e) {
//Toast.makeText(MailApp.this, "There was a problem sending the email.", Toast.LENGTH_LONG).show();
Log.e("MailApp", "Could not send email", e);
}
// OLD METHOD OF SENDING EMAIL
/* Intent email_pic = new Intent(Intent.ACTION_SEND); // Commence choose photo action
email_pic.putExtra(Intent.EXTRA_EMAIL, recipients); // Inserts Digital Signature address automatically in recipient
email_pic.putExtra(Intent.EXTRA_SUBJECT, DIGIJOB); // Inserts Track Number automatically in subject
email_pic.putExtra(Intent.EXTRA_STREAM, uriTarget); // Attaches image to Gmail
email_pic.setType("image/jpeg"); // Converts image to jpeg
startActivityForResult(email_pic, RETURN_ACTIVITY);
overridePendingTransition(R.anim.fadein, R.anim.fadeout); */
JOB = "job"; // Reset job variable from track no (1736) to "job" so
LOGCAT.DEBUG(TAG, "Emailing Picture"); // when you go back into Jobs Activity, it can parse data.
returnActivity();
}
private void returnActivity() {
Intent email_pic = new Intent(DigitalSignature.this, AgentPortalActivity.class);
startActivityForResult(email_pic, FINISH);
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
LOGCAT.DEBUG(TAG, "Returning Activity");
}
private String getRealPathFromURI(Uri uriTarget) {
String[] projection = { MediaStore.Images.Media.DATA };
#SuppressWarnings("deprecation")
Cursor cursor = managedQuery(uriTarget, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
LOGCAT.DEBUG("getRealPathFromURI", cursor.getString(column_index));
return cursor.getString(column_index);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if (previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try { camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
}
catch (IOException e) {
toast.showToastDialog(getApplicationContext(), e.toString());
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
//camera = Camera.open(0);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
You just need to use the MediaStore.ACTION_IMAGE_CAPTURE intent action. That will launch the camera. And in your onActivityResult you can get a the image that was just taken. Now you can crop it and send it and whatever else you'd like. Below is an example.
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File pics = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File cameraPhotoFile = new File(pics, System.currentTimeMillis()+".jpg");
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraPhotoFile));
startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) return;
if (requestCode == REQUEST_CODE_CAMERA) {
MediaScannerConnection.scanFile(this,
new String[]{cameraPhotoFile.getAbsolutePath()}, null, null);
// do something with the image located at cameraPhotoFile
I've included the MediaScannerConnection because the image will not show up in the gallery until it gets scanned. You can remove that if you want, but I like images that were taken to show up. The bitmap is now located in the "cameraPhotoFile." Use that file however you like.
Also, here are the docs from Google about this called Taking Photos Simply. It's pretty straight forward
The easiest solution i can think of is:
Call the ACTION_IMAGE_CAPTURE Intent to take a picture with the Stock Camera
onActivityResult you will get the content uri of the new picture over data.getData()
Do it like vogella here http://blog.vogella.com/2011/09/13/android-how-to-get-an-image-via-an-intent/ and directly open an inputstream to the new picture
no need for the pick intent.