I am trying to capture image from camera but it come out to be blur. Below is the code that I am using.
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA_REQUEST);
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
mPhotoEditorView.getSource().setImageBitmap(thumbnail);
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
Above method only provides thumbnail.
To save the full-size Photo you should follow this tutorial.
Add this permission in your manifest.
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
</manifest>
Create a File. In this, we will save the image:
String currentPhotoPath;
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
return image;
}
Now, you can invoke capture Intent like this:
static final int REQUEST_TAKE_PHOTO = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
...
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
Add FileProvider in your Manifest file
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
...
</application>
Create res/xml/file_paths.xml file with the following content:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
</paths>
Here you go, you have saved a full-size image to the file you had created.
Bonus: You should always scale your image before using it in an ImageView, this will help you optimize your app's Memory usage.
private void setPic() {
// Get the dimensions of the View
int targetW = imageView.getWidth();
int targetH = imageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(currentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(currentPhotoPath, bmOptions);
imageView.setImageBitmap(bitmap);
}
Try to use following code to resolve blur issue
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
You can scale bitmap with your desired height and width high value to get more clearity.
first you have to get path from your intent data uri.
private String getpath(Context context, Uri uri) {
String filePath = null;
try {
Cursor cursor = context.getContentResolver().query(uri, null, null,
null, null);
if (cursor != null) {
if (cursor.moveToNext()) {
int dataColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
filePath = cursor.getString(dataColumn);
}
cursor.close();
}
} catch (IllegalStateException e) {
}
return filePath;
}
then use this code to get your image bitmap
public static Bitmap scaleImage(String p_path, int p_reqHeight, int p_reqWidth) throws Throwable {
Bitmap m_bitMap = null;
File m_file = new File(p_path);
if (m_file.exists()) {
BitmapFactory.Options m_bitMapFactoryOptions = new BitmapFactory.Options();
m_bitMapFactoryOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(m_file.getPath(), m_bitMapFactoryOptions);
m_bitMapFactoryOptions.inSampleSize = calculateInSampleSize(m_bitMapFactoryOptions, p_reqHeight, p_reqWidth);
m_bitMapFactoryOptions.inJustDecodeBounds = false;
m_bitMap = BitmapFactory.decodeFile(m_file.getPath(), m_bitMapFactoryOptions);
} else {
throw new Throwable(p_path + " not found or not a valid image");
}
return m_bitMap;
}
Related
I'm taking picture using camera and selecting from gallery. After that doing compression to reduce file size. I was using getRealPathFromURI() method to get actual image path, but in Android QMediaStore.Images.Media.DATA is deprecated.
fun getRealPathFromURI(contentUri: Uri, activityContext: Activity): String {
val proj = arrayOf(MediaStore.Images.Media.DATA)
val cursor = activityContext.managedQuery(contentUri, proj, null, null, null)
val column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor.moveToFirst()
return cursor.getString(column_index)
}
As per documentation I tried openFileDescriptor() to gain access:
private fun getBitmapFromUri(context: Context, uri: Uri): Bitmap {
val parcelFileDescriptor = context.contentResolver.openFileDescriptor(uri, "rw")
val fileDescriptor = parcelFileDescriptor?.fileDescriptor
val image = BitmapFactory.decodeFileDescriptor(fileDescriptor)
parcelFileDescriptor?.close()
return image
}
also tried this
Due to Scoped Storage, we can’t write the image directly to the desired folder and then update the MediaStore . Instead, Android Q introduces a new field MediaStore.Images.Media.RELATIVE_PATH in which we can specify the path of the image (for example, "Pictures/Screenshots/").
Please refer "Saving a photo to the gallery" section of this blog for more information.
for loading image from gallery you can use it and you have the create provide in manifest
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"></meta-data>
</provider>
create your #xml/provide_paths like this
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images"
path="Android/data/package_name/files/Pictures" /> //pictures is the folder where your image will store
</paths>
code:
if (resultCode == Activity.RESULT_OK) { //onActivity you will get the result like this way
if (data != null) {
Uri contentURI = data.getData();
String path = null;
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),contentURI);
path = saveImage(bitmap);
// decodeImage(path);
img.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
mCurrentPhotoPath = path;
}
}
public void activeGallery() {// for taking the picture from gallery
Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent,RESULT_LOAD_IMAGE);
}
and for capture image in on Activity use
Bundle bundle=data.getExtras(); //
Bitmap bitmap= (Bitmap) bundle.get("data");
img.setImageBitmap(bitmap);
saveImage(bitmap);
public String saveImage(Bitmap myBitmap) { //this method will compress your image
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
myBitmap.compress(JPEG, 90, bytes);
File wallpaperDirectory = new File(Environment.getExternalStorageDirectory() , ""+IMAGE_DIRECTORY);
// have the object build the directory structure, if needed.
if (!wallpaperDirectory.exists()) {
wallpaperDirectory.mkdirs();
}
try {
File f = new File(wallpaperDirectory, Calendar.getInstance()
.getTimeInMillis() + ".jpg");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
// FileOutputStream fos = new FileOutputStream(f);
myBitmap.compress(JPEG, 90, fo);
fo.write(bytes.toByteArray());
MediaScannerConnection.scanFile(this,
new String[]{f.getPath()},
new String[]{"image/jpeg"}, null);
fo.close();
Log.d("TAG", "File Saved::--->" + f.getAbsolutePath());
return f.getAbsolutePath();
} catch (IOException e1) {
e1.printStackTrace();
}
return "";
}
public void activeTakePhoto() {// it will go on camera intent
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getApplicationContext().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
I have some android code which taking photo from camera. But it is taking the picture as thumbnail but I want to take the picture as it is the original size. Here is my code:
private void onCaptureImageResult(Intent data) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
CommonResources.photoFinishBitmap = thumbnail;
goForEditing();
//ivImage.setImageBitmap(thumbnail);
}
Can you help me how to get the original image instead of the thumbnail.
You will need to provide a file name for the full-sized photo to be saved into. You will also need to get access to file storage if you are running on Android 6.0 or later.
This answer should provide a code example of saving the full-sized image to a file: https://stackoverflow.com/a/20353771/5527154
Here is the documentation from Google: https://developer.android.com/training/camera/photobasics.html#TaskPath
To take a photo, first we need to declare required permissions in AndroidManifest.xml. We need two permissions:
Camera - to open camera app. If attribute required is set to true you will not be able to install this app if you don't have hardware camera.
WRITE_EXTERNAL_STORAGE - This permission is required to create new file, in which captured photo will be saved.
AndroidManifest.xml
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
The main idea in taking full-sized photo from camera is that we need to create new file for photo, before we open camera app and capture photo.
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Log.e("DEBUG_TAG", "createFile", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getAlbumDir();
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
private File getAlbumDir() {
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
storageDir = new File(Environment.getExternalStorageDirectory()
+ "/dcim/"
+ "MyRecipes");
if (!storageDir.mkdirs()) {
if (!storageDir.exists()) {
Log.d("CameraSample", "failed to create directory");
return null;
}
}
} else {
Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
}
return storageDir;
}
private void setPic() {
/* There isn't enough memory to open up more than a couple camera photos */
/* So pre-scale the target bitmap into which the file is decoded */
/* Get the size of the ImageView */
int targetW = recipeImage.getWidth();
int targetH = recipeImage.getHeight();
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scaleFactor = 2;
if ((targetW > 0) && (targetH > 0)) {
scaleFactor = Math.max(photoW / targetW, photoH / targetH);
}
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Matrix matrix = new Matrix();
matrix.postRotate(getRotation());
/* Decode the JPEG file into a Bitmap */
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
/* Associate the Bitmap to the ImageView */
recipeImage.setImageBitmap(bitmap);
}
private float getRotation() {
try {
ExifInterface ei = new ExifInterface(mCurrentPhotoPath);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return 90f;
case ExifInterface.ORIENTATION_ROTATE_180:
return 180f;
case ExifInterface.ORIENTATION_ROTATE_270:
return 270f;
default:
return 0f;
}
} catch (Exception e) {
Log.e("Add Recipe", "getRotation", e);
return 0f;
}
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
private void handleBigCameraPhoto() {
if (mCurrentPhotoPath != null) {
setPic();
galleryAddPic();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
handleBigCameraPhoto();
}
}
I am able to save the image taken from camera into internal storage, however I can't load it into ImageView, which remains empty. I've read all relevant suggestions but couldn't find a suitable solution. Please find relevant code below, any help will be MUCH appreciated, as I'm struggling with it for days...
Manifest permissions:
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
ImageView on XML:
<ImageView
android:id="#+id/recipeImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:background="#color/backgroundColorHomeBottomLayout"
android:padding="30dp" />
Relevant activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
if (resultCode == RESULT_OK) {
setPic();
//mImageView.setImageURI(fileUri);
}
else if (resultCode == RESULT_CANCELED) {
/** user cancelled Image capture */
Toast.makeText(this,
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
/** failed to capture image */
Toast.makeText(this,
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
}
}
/** Internal memory methods */
private void launchCameraIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
/** Ensure that there's a camera activity to handle the intent */
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
/** Create the File where the photo should go */
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"v3.com.mycookbook5.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
/** return a unique file name for a new photo using a date-time stamp */
private File createImageFile() throws IOException {
/** Create an image file name */
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
/** Save a file: path for use with ACTION_VIEW intents */
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
private void setPic() {
// Get the dimensions of the View
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
mImageView.setImageBitmap(bitmap);
}
Log:
07-03 12:56:07.188 3950-16091/? E/Drive.UninstallOperation: Package still installed v3.com.mycookbook5
07-03 12:56:35.350 19680-19680/v3.com.mycookbook5 E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: file:/storage/emulated/0/Android/data/v3.com.mycookbook5/files/Pictures/JPEG_20160703_125629_-664091716.jpg: open failed: ENOENT (No such file or directory)
07-03 12:56:35.350 19680-19680/v3.com.mycookbook5 E/BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: file:/storage/emulated/0/Android/data/v3.com.mycookbook5/files/Pictures/JPEG_20160703_125629_-664091716.jpg: open failed: ENOENT (No such file or directory)
I believe that your problem is because you are not giving the image the required time to be saved to the sdcard as the code starts looking for it before it even completely saved, so you have to provide a delayed handler in order to making sure the image is successfully saved, also use the following way to get the image path:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
setPic();
}
}, 750);
and for getting the image from the sdcard:
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image_name.jpg");
Bitmap bitmap = decodeSampledBitmapFromFile(file.getAbsolutePath(), 1000, 700);
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight)
{
/*
* here you set all of your bmOptions specs
*/
return BitmapFactory.decodeFile(path, bmOptions);
}
Problem solved. To help others, here is how it should be performed:
Downgrade targetSdkVersion on build.gradle from 23 --> 22, to avoid permission issues.
Add the following code to launchCameraIntent() method:
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
Change setPic method as follow:
Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getPath());
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(rotatedBitmap, 200, 150 ,false);
mImageView.setImageBitmap(scaledBitmap);
I would say you might get a zero size image due to trying to resize it to the imageView size (which, if not rendered yet - may be zero size).
Try to load the image without any manipulation and after succeeding - change your code to reduce the memory consumption , but by but until you get the optimal result.
Good luck.
You realize you will have to pull the extra data from the intent right? 'onActivityResult' will get back to your activity with a result code and WITH EXTRA DATA which is the bitmap of the image, you should pass that data (in whatever way you choose) to your setPic method.
To get the Bitmap photo you can use the code down below
if (requestCode == REQUEST_IMAGE_CAPTURE) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
}
try this code for marshmallow
Uri imageFileUri = data.getData();
final Bitmap bitmap = getBitmapFromUri(imageFileUri);
private Bitmap getBitmapFromUri(Uri uri) throws IOException {
ParcelFileDescriptor parcelFileDescriptor =
getLocalContext().getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
return image;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
if (resultCode == RESULT_OK) {
//mImageView.setImageURI(fileUri);
Uri imageFileUri = data.getData();
final Bitmap bitmap = getBitmapFromUri(imageFileUri);
setPic(bitmap);
}
else if (resultCode == RESULT_CANCELED) {
/** user cancelled Image capture */
Toast.makeText(this,
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
/** failed to capture image */
Toast.makeText(this,
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
}
}
Image taken from a camera is not set even though the Code I'm using is from the android developer website. Please help. I don't get what I'm supposed to do. Sometimes, the OnActivityResult method isn't called either. Here is the code I am using:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
mImageView = (ImageView) findViewById(R.id.imageView);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dispatchTakePictureIntent();
}
});
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
ex.printStackTrace();
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
System.out.println("Created: " + mCurrentPhotoPath);
galleryAddPic();
return image;
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
private void setPic() {
// Get the dimensions of the View
// int targetW = mImageView.getWidth();
// int targetH = mImageView.getHeight();
//
// // Get the dimensions of the bitmap
// BitmapFactory.Options bmOptions = new BitmapFactory.Options();
// bmOptions.inJustDecodeBounds = true;
// BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
// int photoW = bmOptions.outWidth;
// int photoH = bmOptions.outHeight;
//
// // Determine how much to scale down the image
// int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
//
// // Decode the image file into a Bitmap sized to fill the View
// bmOptions.inJustDecodeBounds = false;
// bmOptions.inSampleSize = scaleFactor;
// bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath);
mImageView.setImageBitmap(bitmap);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
Log.d("", "onActivityResult: "+mCurrentPhotoPath);
if (requestCode == REQUEST_IMAGE_CAPTURE) {
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath);
mImageView.setImageBitmap(bitmap);
}
}
}
If you start an activity for result, the request code identifies the request. So if you started camera activity with request code, REQUEST_TAKE_PHOTO then you must use the same request code in activity result i.e.
onActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
Log.d("", "onActivityResult: "+mCurrentPhotoPath);
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath);
mImageView.setImageBitmap(bitmap);
}
}
UPDATE
Since you want to decodeFile, your mCurrentPhotoPath must be absolute file path and not uri.So remove "file:" from mCurrentPhotoPath
createImageFile
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
System.out.println("Created: " + mCurrentPhotoPath);
galleryAddPic();
return image;
}
Hope it helps you..
I'm currently trying to implement the Camera within my app to take a full image and save it. I'm following the guide at android.com under the 'Save the Full-Size Photo' section.
The first part of that tutorial worked without a problem, but it seems to simply not save the full image for some reason. When using the setPic function, it will crash as the Bitmap it gets has a size of 0. The addGalleryPic function doesn't seem to add anything to the gallery either.
Thanks for your help!
Manifiest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Activity:
String mCurrentPhotoPath;
static final int REQUEST_TAKE_PHOTO = 1;
Creating the file.
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
Opening the Camera intent.
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
Overriding the Activity Result.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Logger.d( "onResult: " + requestCode + " & " + resultCode );
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
Logger.d( "Attempting to open: " + mCurrentPhotoPath );
galleryAddPic();
setPic();
}
}
Adding the image to the gallery.
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
And setting the image to the imageView.
private void setPic() {
// Get the dimensions of the View
int targetW = image.getWidth();
int targetH = image.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Both of these values are zero.
Logger.d( "Size: " + photoW + "x" + photoH );
// Determine how much to scale down the image
// **THIS LINE CRASHES - Divide by zero ( size is zero ).**
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
image.setImageBitmap(bitmap);
}
I recommend that you get rid of String mCurrentPhotoPath and replace it with File mCurrentPhoto (or another name as you see fit). This will clear up a few bugs:
mCurrentPhotoPath = "file:" + image.getAbsolutePath(); results in a value that is neither a valid filesystem path nor a valid string representation of a Uri
File f = new File(mCurrentPhotoPath); results in an invalid File, because of the rogue file: you are putting on the filesystem path in the above bullet
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); will not work, because of the rogue file: you are putting on the filesystem path in the first bullet
Most of the time, you are using the File anyway. And then for decodeFile(), just call getAbsolutePath() at that point (BitmapFactory.decodeFile(mCurrentPhoto.getAbsolutePath(), bmOptions)).