How can I resize image captured by default camera? - android

I capture photo with default camera by calling
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, ApplicationData.CAMERA_REQUEST);
Then I save the photo to sdcard and retrieve it and set it to ImageView
OutputStream output;
Bitmap photo = (Bitmap) data.getExtras().get("data");
output = new FileOutputStream(file);
photo.compress(Bitmap.CompressFormat.PNG, 100, output);
output.flush();
output.close();
mThumbnaiImagelLayout.setVisibility(View.VISIBLE);
mImageThumbNail.setImageBitmap(photo);
What I want in ImageView is exactly the same like thumbnail image of the device.For example:
But it become like this
So my question is:
1/How can I resize captured image?
2/Is any other way I can set image to ImageView without bitmap? Because when I set ImageView with Bitmap, it look terrible, like this (the image's size is 512x512)
Please help me to solve this problem.Thank you!

Try this
android:scaleType="fitCenter"

If you use Bundle extras = data.getExtras(); in your onActivityResult then it will return thumbnail image not actual image.
Here is code I have used for Capturing and Saving Camera Image then display it to imageview.
Here is method for opening capturing camera image activity.
private static final int CAMERA_PHOTO = 111;
private Uri imageToUploadUri;
private void captureCameraImage() {
Intent chooserIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(Environment.getExternalStorageDirectory(), "POST_IMAGE.jpg");
chooserIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
imageToUploadUri = Uri.fromFile(f);
startActivityForResult(chooserIntent, CAMERA_PHOTO);
}
then your onActivityResult() method should be like this.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_PHOTO && resultCode == Activity.RESULT_OK) {
if(imageToUploadUri != null){
Uri selectedImage = imageToUploadUri;
getContentResolver().notifyChange(selectedImage, null);
Bitmap reducedSizeBitmap = getBitmap(imageToUploadUri.getPath());
if(reducedSizeBitmap != null){
imageview.setImageBitmap(reducedSizeBitmap);
}else{
Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show();
}
}else{
Toast.makeText(this,"Error while capturing Image",Toast.LENGTH_LONG).show();
}
}
}
Here is getBitmap() method used in onActivityResult().
private Bitmap getBitmap(String path) {
Uri uri = Uri.fromFile(new File(path));
InputStream in = null;
try {
final int IMAGE_MAX_SIZE = 1200000; // 1.2MP
in = getContentResolver().openInputStream(uri);
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, o);
in.close();
int scale = 1;
while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) >
IMAGE_MAX_SIZE) {
scale++;
}
Log.d("", "scale = " + scale + ", orig-width: " + o.outWidth + ", orig-height: " + o.outHeight);
Bitmap b = null;
in = getContentResolver().openInputStream(uri);
if (scale > 1) {
scale--;
// scale to max possible inSampleSize that still yields an image
// larger than target
o = new BitmapFactory.Options();
o.inSampleSize = scale;
b = BitmapFactory.decodeStream(in, null, o);
// resize to desired dimensions
int height = b.getHeight();
int width = b.getWidth();
Log.d("", "1th scale operation dimenions - width: " + width + ", height: " + height);
double y = Math.sqrt(IMAGE_MAX_SIZE
/ (((double) width) / height));
double x = (y / height) * width;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x,
(int) y, true);
b.recycle();
b = scaledBitmap;
System.gc();
} else {
b = BitmapFactory.decodeStream(in);
}
in.close();
Log.d("", "bitmap size - width: " + b.getWidth() + ", height: " +
b.getHeight());
return b;
} catch (IOException e) {
Log.e("", e.getMessage(), e);
return null;
}
}

Related

How to save the image automatically when using camera intent from my app?

when i am using camera intent from my app then it is opening camera but after clicking it asks to save the image but when we click image using mobile camera app it saves automatically.
Using camera intent also opens the same inbuild camera app then why thid dual behaviour?
Also how to make the camera to save the image automatically when using camera intent from my app
try this
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//Get Image from Camera
if (requestCode == CAMERA_CLICK_RESULT && resultCode == RESULT_OK) {
dialog2.dismiss();
Bitmap photo = null;
try {
photo = MediaStore.Images.Media.getBitmap(
getContentResolver(), imageUri);
} catch (IOException e) {
e.printStackTrace();
}
selectedImage = getResizedBitmap(photo, 900)
try {
//Write file
filename = "your file name.extension";
File file = new File("Directory path where you want to save");
file.mkdir();
FileOutputStream fileOutputStream = new FileOutputStream(file + filename);
selectedImage.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
//Cleanup
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//Resize Bitmap
public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
int width = image.getWidth();
int height = image.getHeight();
float bitmapRatio = (float) width / (float) height;
if (bitmapRatio > 1) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(image, width, height, true);
}

Why the bitmap is empty

I am following the tutorial here to take picture with other app AND with customized SurfaceView.
When take picture with SurfaceView, the picture is taken successfully (I quit my app and saw the result image file does exist in file manager, and the image content is correct.), but the picture cannot show correctly in my app. The ImageView shows nothing.
My code is like this:
public void onPictureTaken(byte[] data, Camera camera) {
try {
File file = Utils.getOutputMediaFile(Utils.MediaFileType.Image);
FileOutputStream os = new FileOutputStream(file);
os.write(data);
os.flush();
os.close();
final Uri uri = Uri.fromFile(file);
showImage(uri);
} catch (FileNotFoundException e) {
Log.d(TAG, "onPictureTaken, e=" + e);
} catch (IOException e) {
Log.d(TAG, "onPictureTaken, e=" + e);
}
camera.startPreview();
}
private void showImage(Uri imageFileUri) {
int w = mContentContainer.getWidth();
int h = mContentContainer.getHeight();
Bitmap bmp = Utils.loadBitmapFromFile(imageFileUri.getPath(), w, h);
mImageView.setImageBitmap(bmp);
mStatusTextView.setText("take photo: succcess");
}
public static Bitmap loadBitmapFromFile(String filename, int maxWidth, int maxHeight) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, opt);
Log.d(TAG, "loadBitmapFromFile, w=" + opt.outWidth + ", h=" + opt.outHeight);
int widthRatio = (int) Math.ceil(opt.outWidth / maxWidth);
int heightRatio = (int) Math.ceil(opt.outHeight / maxHeight);
if (widthRatio > 1 || heightRatio > 1) {
if (widthRatio > heightRatio) {
opt.inSampleSize = widthRatio;
} else {
opt.inSampleSize = heightRatio;
}
}
opt.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(filename, opt);
Log.d(TAG, "loadBitmapFromFile, bmp=" + bmp);
return bmp;
}
From log, I saw the width and height is correctly loaded from file, and bmp is not null, but the ImageView is just empty.
Strange is, if my app firstly take a photo and show the photo with showImage() (the ImageView shows photo correctly), then after that, take phone with SurfaceView and show with showImage(), the photo shows correctly. But if directly take phone with SurfaceView and showImage(), the ImageView is empty.
Any comments about why the ImageView is empty? Thanks.
Try (see the comments):
private void showImage(Uri imageFileUri) {
int w = mContentContainer.getWidth();
int h = mContentContainer.getHeight();
Bitmap bmp = Utils.loadBitmapFromFile(imageFileUri.getPath(), w, h);
mImageView.requestLayout(); //try to request the layout first
mImageView.setImageBitmap(bmp);
//if its still not working try to call invalidate() method here
mStatusTextView.setText("take photo: succcess");
}

Out of memory error in Galaxy Note 3 only

I'm developing an application that can display a photo from the camera using the camera intent using the extra crop option. The code is working fine in most of the devices but when i tried to test it in my brand new Galaxy Note3 it crashes and didn't run properly, Also the image taken is still huge in size "Almost 4 MB" which is so large to be displayed in the imageview. Can anyone point me if there is anyway to avoid this?
Hereunder my code :
Intent intent = new Intent(
"android.media.action.IMAGE_CAPTURE");
file = getOutputMediaFile();
intent.putExtra("crop", "true");
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(file));
intent.putExtra("outputFormat",
Bitmap.CompressFormat.JPEG
.toString());
intent.putExtra(
MediaStore.EXTRA_SCREEN_ORIENTATION,
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
startActivityForResult(intent,
ACTION_REQUEST_CAMERA);
and for activityforresult
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case ACTION_REQUEST_CAMERA:
if (data != null) {
try {
int inWidth = 0;
int inHeight = 0;
InputStream in = new FileInputStream(
file.getAbsolutePath());
// decode image size (decode metadata only, not the
// whole image)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, options);
in.close();
in = null;
// save width and height
inWidth = options.outWidth;
inHeight = options.outHeight;
// decode full image pre-resized
in = new FileInputStream(file.getAbsolutePath());
options = new BitmapFactory.Options();
// calc rought re-size (this is no exact resize)
options.inSampleSize = Math.max(inWidth / 350,
inHeight / 550);
// decode full image
Bitmap roughBitmap = BitmapFactory.decodeStream(in,
null, options);
// calc exact destination size
Matrix m = new Matrix();
RectF inRect = new RectF(0, 0, roughBitmap.getWidth(),
roughBitmap.getHeight());
RectF outRect = new RectF(0, 0, 700, 800);
m.setRectToRect(inRect, outRect,
Matrix.ScaleToFit.CENTER);
float[] values = new float[9];
m.getValues(values);
// resize bitmap
Bitmap resizedBitmap = Bitmap.createScaledBitmap(
roughBitmap,
(int) (roughBitmap.getWidth() * values[0]),
(int) (roughBitmap.getHeight() * values[4]),
true);
// save image
try {
FileOutputStream out = new FileOutputStream(
file.getAbsolutePath());
resizedBitmap.compress(Bitmap.CompressFormat.JPEG,
90, out);
fullphoto = resizedBitmap;
setPic(file.getAbsolutePath(), camera);
} catch (Exception e) {
Log.e("Image", e.getMessage(), e);
}
} catch (IOException e) {
Log.e("Image", e.getMessage(), e);
}
}
// fullphoto = BitmapFactory.decodeFile(file.getAbsolutePath());
// photo = decodeSampledBitmapFromFile(file.getAbsolutePath(),
// 100, 100);
// camera.setImageBitmap(imghelper.getRoundedCornerBitmap(
// fullphoto, 10));
iscamera = "Yes";
firsttime = false;
break;
}

how to save captured image with custom size in android

in my application i can open the camera and take a picture. The picture is stored in a full size of 2448x3264 pixels on the sd-card. how can i configure this in my application, to save the picture in a size of 90x90 pixels and not in 2448x3264 pixel?
to open the camera and capture a image i use following methods:
/*
* Capturing Camera Image will lauch camera app requrest image capture
*/
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
private Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
private File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES), IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create " + IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).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;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// if the result is capturing Image
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
/*
try {
decodeUri(this, fileUri, 90, 90);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
*/
// successfully captured the image
Toast.makeText(getApplicationContext(),
"Picture successfully captured", Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
// user cancelled Image capture
Toast.makeText(getApplicationContext(),
"User cancelled image capture", Toast.LENGTH_SHORT).show();
} else {
// failed to capture image
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT).show();
}
}
}
public static Bitmap decodeUri(Context c, Uri uri, final int requiredWidth, final int requiredHeight) throws FileNotFoundException {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o);
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while(true) {
if(width_tmp / 2 < requiredWidth || height_tmp / 2 < requiredHeight)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o2);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// get the file url
fileUri = savedInstanceState.getParcelable("file_uri");
}
i hope that s.o. can help me with this. i am trying to load the captured images into a little imageview, look like that. thanks in advance
No, you cannot control the picture size when you use MediaStore.ACTION_IMAGE_CAPTURE Intent. You can achieve this if you implement your "custom camera" (and there are plenty of working samples on Internet), including mine.
The byte array received in onPictureTaken() is a Jpeg buffer. Look at this Java package for image manipulation: http://mediachest.sourceforge.net/mediautil/ (there is an Android port on GitHub). There are very powerful and efficient methods to scale down Jpeg, without decoding it into Bitmap and back.
Here, I'm giving a method which will take the saved path on SDCard of taken picture and will return the required size image as Bitmap. Now what you have to do is just pass image path on SDCard and get the resized image.
private Bitmap processTakenPicture(String fullPath) {
int targetW = 90; //your required width
int targetH = 90; //your required height
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fullPath, bmOptions);
int scaleFactor = 1;
scaleFactor = calculateInSampleSize(bmOptions, targetW, targetH);
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor * 2;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(fullPath, bmOptions);
return bitmap;
}
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth,
int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
After you had read the original image, you can use:
Bitmap.createScaledBitmap(photo, width, height, true);
here is another question wherre a guy has the same problem. He uses the following.
Bitmap ThumbImage = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(imagePath), THUMBSIZE, THUMBSIZE);

ACTION PICK of photo from SD filtering for size or resolution?

I'm getting a photo from sd starting a new intent how this:
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
This work great! but in some cases, image size is too large and mobile device crashes. If is a normal size image not problem, but I wanna a way to filter or avoid the larger size images.
Try using this
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(
Intent.createChooser(intent, "Select Picture"), 0);
hope it will help, it works for me.
I found the solution to this problem, I use the next method to get the bitmap resized using Bitmaps options. You can set the max size (actually 1.2MP) but it's great result there.
private Bitmap getBitmap(String path) {
Uri uri = getImageUri(path);
InputStream in = null;
try {
final int IMAGE_MAX_SIZE = 1200000; // 1.2MP
in = mContentResolver.openInputStream(uri);
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, o);
in.close();
int scale = 1;
while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) > IMAGE_MAX_SIZE) {
scale++;
}
Log.d(TAG, "scale = " + scale + ", orig-width: " + o.outWidth + ", orig-height: " + o.outHeight);
Bitmap b = null;
in = mContentResolver.openInputStream(uri);
if (scale > 1) {
scale--;
// scale to max possible inSampleSize that still yields an image
// larger than target
o = new BitmapFactory.Options();
o.inSampleSize = scale;
b = BitmapFactory.decodeStream(in, null, o);
// resize to desired dimensions
int height = b.getHeight();
int width = b.getWidth();
Log.d(TAG, "1th scale operation dimenions - width: " + width + ", height: " + height);
double y = Math.sqrt(IMAGE_MAX_SIZE
/ (((double) width) / height));
double x = (y / height) * width;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x, (int) y, true);
b.recycle();
b = scaledBitmap;
System.gc();
} else {
b = BitmapFactory.decodeStream(in);
}
in.close();
Log.d(TAG, "bitmap size - width: " +b.getWidth() + ", height: " + b.getHeight());
return b;
} catch (IOException e) {
Log.e(TAG, e.getMessage(),e);
return null;
}
}

Categories

Resources