Saving bitmap to SD card with out compressing it in android - android

I am using android inbuilt camera to take picture and then attaching the same picture to email, when i am testing this functionality in 1.6 device, i am able name the picture that to be taken by in built camera, but in 2.1, the picture is having a name i.e given by device,
How to give user defined name in 2.1 inbuilt camera images..
to avoid that problem i am saving the image manually but when i try to get the image back through intent as bitmap and then saving it to sd card using compress method
this methods handles result from inbuilt camera
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
File file = new File(Environment.getExternalStorageDirectory()
+ "/test.png");
switch (requestCode)
{
case PHOTO_ACTION:
if (resultCode == RESULT_CANCELED)
{
addPhoto = false;
Toast.makeText(this, "Canceled ", Toast.LENGTH_LONG).show();
break;
} else if (resultCode == RESULT_OK)
{
Bundle b = data.getExtras();
Bitmap bm = (Bitmap) b.get("data");
FileOutputStream out;
try
{
out = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
scanPhoto(file.toString());
out = null;
addPhoto = true;
} catch (Exception e)
{
e.printStackTrace();
addPhoto = false;
}
but when i am storing like this i am getting two images. one with system given name and other with name given by me. but the image one which has user defined is having less resolution so i question is how to save the bitmap with more resolution with out compressing it ..
please help.... me

If you just want to save the bitmap without losing quality try using CompressFormat.PNG instead of JPEG, I've seen people having that problem before. Try changing:
bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
with:
bm.compress(Bitmap.CompressFormat.PNG, 100, out);
and see it it helps.

Apart from Rick answer above, make sure your are providing a URI to camera intent where it can save the full image, else it will return thumb image in data parameter of intent.
So it will be like:
Intent photoPickerIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
imgFile = new File("Cache directory","img.png"); //== where you want full size image
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(imgFile));
startActivityForResult(photoPickerIntent, PickPhoto);
This was the error that I was doing.

Related

Android Camera picture not showing in ImageView

I am trying to take a picture with the camera of "Nexus 5X API 26" and show it in ImageView field, before uploading it to Firebase.
First problem is that after taking a picture, it does not show up in imageView. I am doing the following:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, CAMERA_REQUEST_CODE);}
And then I was trying to show the picture in the same way I do for the pictures taken from Gallery:
filePath = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
The part which I do not understand is how data.getData() works in both cases (for Gallery and for Camera)?
I guess that the uploadImage() method, should be the same for both Gallery and Camera uploads (it works for Gallery already so...).
So the thing that I am currently missing is that I am not getting the filePath, I guess?
Is it necessary to "temporarily save" the camera's picture in order to .getData()? Or it can work without any kind of "saving"?
I just want the user to take a picture and it should be sent to Firebase. Not necessary for user to see it in imageView first, just to get the uri (data) in order to upload it.
view when i open the camera
view after taking a picture
This will help you.
Intent intent= new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent,7);
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
bitmap= (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream baos=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
imageEncoded = Base64.encodeToString(b,Base64.DEFAULT);
byte[] imageAsBytes = Base64.decode(imageEncoded.getBytes(), Base64.DEFAULT);
InputStream is=new ByteArrayInputStream(imageAsBytes);
bitmap1=BitmapFactory.decodeStream(is);
img.setImageBitmap(bitmap1);
}

In the android application, image isn't showing after closing app and restarting it

In an app I am allowing user to pick image from gallery or he can choose from camera. Though I can manage the image and show it in the activity in the first time, after closing the app and restarting it, the image is gone and the space is blank.There was an explanation given to me to save the image data in sharedPreferences but I am new in android and don't pretty much understand. I looked for sharedPreferences but don't know how to make it work.
So if anybody help kindly with some explanation and code, it would help me a lot.
Thanks.
Here is what I tried to do.
private void openCamera(){
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,getPhotoFileUri(photoFileName)); // set the image file name
// If you call startActivityForResult() using an intent that no app can handle, your app will crash.
// So as long as the result is not null, it's safe to use the intent.
if (intent.resolveActivity(getPackageManager()) != null) {
// Start the image capture intent to take photo
startActivityForResult(intent, TAKE_IMAGE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// final android.widget.LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) imageview.getLayoutParams();
if (requestCode == PICK_IMAGE && resultCode == RESULT_OK) {
Uri imageUri = data.getData();
imageview.setImageURI(imageUri);
//selectedImagePath = getPath(imageUri);
//ystem.out.println("Image Path : " + selectedImagePath);
}
else if (requestCode == TAKE_IMAGE && resultCode == Activity.RESULT_OK) {
Uri takenPhotoUri = getPhotoFileUri(photoFileName);
// by this point we have the camera photo on disk
Bitmap rawTakenImage = BitmapFactory.decodeFile(takenPhotoUri.getPath());
// RESIZE BITMAP, see section below
// See BitmapScaler.java: https://gist.github.com/nesquena/3885707fd3773c09f1bb
// Get height or width of screen at runtime
int screenWidth = DeviceDimensionsHelper.getDisplayWidth(this);
// Resize a Bitmap maintaining aspect ratio based on screen width
Bitmap resizedBitmap = BitmapScaler.scaleToFitWidth(rawTakenImage,screenWidth);
// Load the taken image into a preview
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
// Compress the image further
resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
// Create a new file for the resized bitmap (`getPhotoFileUri` defined above)
Uri resizedUri = getPhotoFileUri(photoFileName + "_resized");
File resizedFile = new File(resizedUri.getPath());
// Write the bytes of the bitmap to file
try{
resizedFile.createNewFile();
FileOutputStream fos = new FileOutputStream(resizedFile);
fos.write(bytes.toByteArray());
fos.close();
}catch (IOException e){
System.out.println("Error occured");
}
imageview.setImageBitmap(rawTakenImage);
}
}
public Uri getPhotoFileUri(String fileName) {
// Only continue if the SD Card is mounted
if (isExternalStorageAvailable()) {
// Get safe storage directory for photos
// Use `getExternalFilesDir` on Context to access package-specific directories.
// This way, we don't need to request external read/write runtime permissions.
File mediaStorageDir = new File(
getExternalFilesDir(Environment.DIRECTORY_PICTURES), APP_TAG);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()){
Log.d(APP_TAG, "failed to create directory");
}
// Return the file target for the photo based on filename
return Uri.fromFile(new File(mediaStorageDir.getPath() + File.separator + fileName));
}
return null;
}
// Returns true if external storage for photos is available
private boolean isExternalStorageAvailable() {
String state = Environment.getExternalStorageState();
return state.equals(Environment.MEDIA_MOUNTED);
}
You can use below ways to store image.
1. Database with Base64
You can convert image into base64 string and store in database.
So when you open application you can retrieve base64 String from database and display image in ImageView.
2. Store Image Path in Database
You can store image path in database, when you open application, just retrieve image path and display image in ImageView.
But if you delete image from memory, you will not get image from iamge path.
3. Store Image in Server.
If you store image in server, you can retrieve image path and download image using AsyncTask or sime 3rd party liberary. And display image in ImageView.
(Liberaries : Picaso, LazyLoading etc.)

Upload photo to drive without compression

I want to upload a photo from my camera directly into a drive folder:
OutputStream outputStream = result.getDriveContents().getOutputStream();
ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
/* image is my Bitmap */
image.compress(Bitmap.CompressFormat.PNG, 100, bitmapStream);
try {
outputStream.write(bitmapStream.toByteArray());
} catch (IOException e1) {
Log.i(TAG, "Unable to write file contents.");
}
So im doing this and it's working. The problem is that my pictures in drive is in very low quality and i need to have a High Quality video.
I already tried this solution Converting bitmap to byteArray android
But then in Drive the photo wasnt recognize as media file and can't read it. I may have failed something.
EDIT: i've done exactly the same things that is there https://stackoverflow.com/a/13000774/6644403 and doing this way to get my Bitmap in ActivityResult :
try {
mBitmapToSave = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
For Get Actual Image predefined path of Captured Image using
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
this.startActivityForResult(cameraIntent, 101);
After Captured Image you can get Captured Image on path which is set in cameraIntent. If you don't Want to set predefined path then check Intent data.
if (resultCode == android.app.Activity.RESULT_OK && requestCode == 101) {
try {
path_mm = "Onsuccess_resultcode";
generateNoteOnSD("photo34.txt", path_mm);
Bitmap photo = null;
if (data == null) {
//get Bitmap here.
} else {
Uri u1 = data.getData();
//get uri and find actual path on that uri.
}
}catch(Exception ex) {}
}
Refer this link Upload large files to Google Drive using GD API for google drive Uploadation.
I wasnt asking for rights to WRITE_EXTERNAL_STORAGE, it was in my manifest but since api23 i need to explicit and ask if the user ok.
Now it's good.

Saving image to SD card then displaying in imageview

UPDATE!!
So Lokesh put me on the right path, and showed me that the problem was the size of the file being too large to show in the imageview. I was able to fix the imageview preview problem with the following code under my onActivityResult:
try {
Bitmap picture = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/td01.png");
int nh = (int) ( picture.getHeight() * (512.0 / picture.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(picture, 512, nh, true);
Log.v("Path", Environment.getExternalStorageDirectory().getPath()+"/td01.png");
pic1.setImageBitmap(scaled);
} catch (Exception e) {
Log.e("Error reading file", e.toString());
}
Thanks Lokesh!
----------------- ORIGINAL ISSUE BELOW THIS LINE -------------------
So I'm trying to both save an image to the SD card for use later, AND display the saved image in an imageview which also serves as the button which takes the photo. Here's the code:
pic1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent camera_intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File image1 = new File(Environment.getExternalStorageDirectory(),"td01.png");
camera_intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image1));
startActivityForResult(camera_intent, CAMERA_PIC_REQUEST1);
}
});
followed by:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case 1:
if(resultCode==RESULT_OK){
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
pic1.setImageBitmap(thumbnail);
}
}
Now, if I remove the following code from the onclick, it shows the thumbnail as I expect it to:
File image1 = new File(Environment.getExternalStorageDirectory(),"td01.png");
camera_intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image1));
...but without that code, it doesn't save the file to my sd card.
The problem is, if I don't remove that code, it saves the image to my SD Card but immediately crashes before returning to the activity after tapping SAVE in the camera activity, unless I remove the following code from my onActivityResult:
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
pic1.setImageBitmap(thumbnail);
I've also tried many variations of the following code in my onActivityResult, hoping to display it from the actual file in a different way, but it never works and only shows a blank imageview, but at least in that case the crash doesn't occur, because I removed the get extras get data code:
Bitmap photo1 = BitmapFactory.decodeFile("/sdcard/td01.png");
pic1.setImageBitmap(photo1);
I've been struggling with this for days and am at a loss here. Hope someone can show me what stupid thing I'm doing wrong and explain why this isn't working.
Thanks!
Try this:
try {
Bitmap picture = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath()+"/DCIM/MyPhoto.jpg");
Log.v("Path", Environment.getExternalStorageDirectory().getPath()+"/DCIM/MyPhoto.jpg");
mImageView.setImageBitmap(picture);
} catch (Exception e) {
Log.e("Error reading file", e.toString());
}
do NOT access the SD card directly, try accessing it trough Environment Like this
String imageDir = Environment.getExternalStorageDirectory()+"/apple.jpg";
and then you can call BitmapFactory:
Bitmap myBitmap = BitmapFactory.decodeFile(imageDir);

android picture from camera being taken at a really small size

Im trying to capture an image from the camera, compress it, then store it to the SD card. If I directly save it to the SD card using the code directly below, I get the full image. But if i try and load the image in the system, i get a super small image size such as 320 by 240 instead of a full 5 mp image.
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, getImageUri());
startActivityForResult(intent, CAMERA_PIC_REQUEST);
where getImageURI() is
private Uri getImageUri() {
// Store image in dcim
file = new File(Environment.getExternalStorageDirectory() + "/DCIM","itshelp.jpg");
imgUri = Uri.fromFile(file);
file.deleteOnExit();
Log.e("syS","file is at "+imgUri);
return imgUri;
}
Now when i try to save it to internal memory instead, I use the following code that gets me the tiny image:
public void imageFromCamera() { //code to retrieve image
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
and in my startActivitForResult I have the following:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_PIC_REQUEST && resultCode == RESULT_OK) {
Bitmap bm = (Bitmap) data.getExtras().get("data");
Log.e("sys", "width is "+bm.getWidth()); //im gettting an extremely small width here
OutputStream outStream = null;
file = new File(Environment.getExternalStorageDirectory() + "/DCIM","itshelp.png");
try {
outStream = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.JPEG, 70, outStream);
outStream.flush();
outStream.close();
Log.i("Hub", "OK, Image Saved to SD");
Log.i("Hub", "height = "+ bm.getHeight() + ", width = " + bm.getWidth());
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.i("Hub", "FileNotFoundException: "+ e.toString());
} catch (IOException e) {
e.printStackTrace();
Log.i("Hub", "IOException: "+ e.toString());
}
}
When you call the camera intent without MediaStore.EXTRA_OUTPUT, the camera returns only a small thumbnail since the intent bundle is not designed to pass large memory blocks.
From the SDK documentation for MediaStore:
Standard Intent action that can be sent to have the camera application capture an image and return it.
The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field. This is useful for applications that only need a small image. If the EXTRA_OUTPUT is present, then the full-sized image will be written to the Uri value of EXTRA_OUTPUT.

Categories

Resources