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.
Related
I'm using following code from here. I want to compress image.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
After choose image from Camera, Gallery and Photos, i'm getting different type of paths in different devices based on OS type and device model. like:
1) /storage/emulated/0/Android/data/...
2) /raw//storage/emulated/0/mb/1511172993547.jpg
3) /2/1/content://media/external/images/media/11647/ORIGINAL/NONE/486073582
If path is like 1st url, this code is working fine. But if i get other types of images, then BitmapFactory.decodeFile() is giving null.
Is there any way to compress image in all types of devices and OS versions.
UPDATE :
To Open Picker :
Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.setType("image/*");
startActivityForResult(pickIntent, 1001);
After choosing image :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Uri imgUri = Uri.fromFile(new File(data.getData().getPath()));
Bitmap cmpBitmap = ImageUtils.compressUriQuality(OpenWallWeb.this, imgUri);
dlgImageToPost.setImageBitmap(cmpBitmap);
...
}
For compression :
public static Bitmap compressUriQuality(Context mContext, Uri selectedImage) {
InputStream imageStream = null;
Bitmap bmp = null;
try {
imageStream = mContext.getContentResolver().openInputStream(
selectedImage);
bmp = BitmapFactory.decodeStream(imageStream);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 50, stream);
if (imageStream != null)
imageStream.close();
stream.close();
stream = null;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bmp;
}
Tv 2) /raw//storage/emulated/0/mb/1511172993547.jpg
That is not a path you would get if the user selected pictures from Gallery or Photos. And certainly it is no file system path you could use for .decodeFile(). How did you obtain it?
3) /2/1/content://media/external/images/media/11647/ORIGINAL/NONE/486073582
That is no valid content scheme path. How did you obtain it? And certainly cannot be used for .decodeFile().
i'm getting different type of paths
You will never get such paths if you 'act normal'. So what is it what you are doing? Elementary uri handling wrong?
using following code from here.
That is pretty dirty example code for a big part as you have perceived now.
any way to compress image in all types of devices and OS versions.
Of course. Just use the obtained selected uri directly. Open an InputStream for it and use .decodeStream() instead.
My god.. you are not using the uri directly.
Bitmap cmpBitmap = ImageUtils.compressUriQuality(OpenWallWeb.this, imgUri);
Change to
Bitmap cmpBitmap = ImageUtils.compressUriQuality(OpenWallWeb.this, data.getData());
I had same issue, please add storage permission to your app.
Check this link for more info
Storage permission error in Marshmallow
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.)
I have tried to getting absolute path and I got the success too but when I try with the cloud images to get that image and used in application file is not find and getting null. I am implementing to receive files from another app like when you select image from Photos, Gallery or File application and share image by using my application.
Here I got the Uri content://com.google.android.apps.photos.contentprovider/0/1/mediaKey%3A%2FAF1QipOFLMMm8uXbeDMQk-P4S0Hx1dlmRDMr4SFABfVi/ACTUAL/61235243
When I select image which is on Google Photos cloud and it'll be first download and then given me above URI. From that point I directly execute in query and getting the name of the file "Filename.png" in all the columns but not the full path.
When same things I tried with the Facebook to share it will display in compose exact which I want to share.
I have also refer this from this link to get the path from Photos application, but the problem is with cloud image.
Anybody have solution or suggestion will be appriciated.
Try getting the Bitmap first:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Uri selectedImage = data.getData();
InputStream inputStreamBitmap = null;
Bitmap imageBitmap = null;
try {
inputStreamBitmap = getContentResolver().openInputStream(inputStreamBitmap);
imageBitmap = BitmapFactory.decodeStream(inputBitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (inputStreamBitmap != null) {
inputStreamBitmap.close();
}
} catch (IOException ignored) {
}
}
if (imageBitmap != null) {
processImageBitmap(imageBitmap);
} else {
Log.e("ImageIntent", "Error: couldn't open the specified image.");
}
}
}
Then you could save the Bitmap to a temp file if you want to.
More details here.
I am developing an app that will allow users to capture images of secure documents and upload those images to a server (a good example of what I'm trying to do is a banking app that allows users to take pictures of checks.)
For security reasons, I do not want the image physically stored on disk at any point, if possible.
When I try to do this with the MediaStore.ACTION_IMAGE_CAPTURE intent, it works... but the resolution is very low. I assume this is to prevent overuse of RAM. I've looked around for solutions, but all of the ones I found involve storing the image on the SD card or internal NAND storage. I do not want to do that.
If it is not possible to avoid storing the photo, is there a way for the image to be stored to a location only accessible to my app? I would then delete the file after it's uploaded. And if I have to do it this way, is there any way to encrypt the photo as it's being stored?
Here's a simplification of my current code, in case that helps at all:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent,requestCode);
and
protected void onActivityResult(int requestCode, int resultcode, Intent data)
{
if (resultcode == RESULT_OK)
{
Bitmap bmp = getBitmapFromIntent(data);
}
}
private Bitmap getBitmapFromIntent(Intent intent)
{
Bundle extras = intent.getExtras();
return (Bitmap) extras.get("data");
}
You can save files directly on the device's internal storage. By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user). When the user uninstall your application, these files are removed.
String file_path = "/data/data/com.packagename/cache/";
File dir = new File(file_path);
if (!dir.exists())
dir.mkdirs();
File file = new File(dir, "1" + ".jpg");
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(data); // data in byte format
fos.close();
} catch (FileNotFoundException e) {
Log.e("Not Found", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.e("Not Found", "Error accessing file: " + e.getMessage());
}
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.