Android Large Image on Imageview Crashes App on OOM Error - java

The below code allows a user to pick 4 images from their gallery and upload to a server. At the moment It is uploading all 4 small images but when i try large images it crashes on OOM error.
Even when i try to load 2 large images the app crashes when i load a big images on OOM error. What is the most efficient way to handle such issues?. I have read this Android Bitmaps but i don't seem to get how to implement in my four images code. I have tried Picasso but the app still behaves the same (ditto) above.
SelectImageGallery1 = (Button)findViewById(R.id.buttonSelect1);
SelectImageGallery2 = (Button)findViewById(R.id.buttonSelect2);
SelectImageGallery3 = (Button)findViewById(R.id.buttonSelect3);
SelectImageGallery4 = (Button)findViewById(R.id.buttonSelect4);
UploadImageServer = (Button)findViewById(R.id.buttonUpload);
SelectImageGallery1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Image1 From Gallery"), 1);
}
});
SelectImageGallery2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Image4 From Gallery"), 2);
}
});
SelectImageGallery3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Image3 From Gallery"), 3);
}
});
SelectImageGallery4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Image4 From Gallery"), 4);
}
});
UploadImageServer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
GetImageNameEditText1 = imageName1.getText().toString();
GetImageNameEditText2 = imageName2.getText().toString();
GetImageNameEditText3 = imageName3.getText().toString();
GetImageNameEditText4 = imageName4.getText().toString();
ImageUploadToServerFunction();
}
});
}
#Override
protected void onActivityResult(int RC, int RQC, Intent I) {
super.onActivityResult(RC, RQC, I);
if (RC == 1&&RQC == RESULT_OK&&I != null&&I.getData() != null) {
Uri uri = I.getData();
try {
bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
imageView1.setImageBitmap(bitmap1);
} catch (IOException e) {
e.printStackTrace();
}
}
if (RC == 2 && RQC == RESULT_OK && I != null && I.getData() != null) {
Uri uri = I.getData();
try {
bitmap2 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
//bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView2.setImageBitmap(bitmap2);
} catch (IOException e) {
e.printStackTrace();
}
}
if (RC == 3 && RQC == RESULT_OK && I != null && I.getData() != null) {
Uri uri = I.getData();
byte[] imageAsBytes=null;
try {
bitmap3 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
//bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView3.setImageBitmap(bitmap3);
} catch (IOException e) {
e.printStackTrace();
}
}
if (RC == 4 && RQC == RESULT_OK && I != null && I.getData() != null) {
Uri uri = I.getData();
try {
bitmap4 = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
//bitmap1 = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView4.setImageBitmap(bitmap4);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String getStringImage1(Bitmap bitmap1){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap1.compress(Bitmap.CompressFormat.JPEG, 60, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage1 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage1;
}
public String getStringImage2(Bitmap bitmap2){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap2.compress(Bitmap.CompressFormat.JPEG, 60, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage2 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage2;
}
public String getStringImage3(Bitmap bitmap3){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap3.compress(Bitmap.CompressFormat.JPEG, 60, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage3 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage3;
}
public String getStringImage4(Bitmap bitmap4){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap4.compress(Bitmap.CompressFormat.JPEG, 60, baos);
byte[] imageBytes = baos.toByteArray();
String encodedImage4 = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage4;
}

This was achieved by using Glide as follows. Using glide ensures the OOM errors are handled and they are not repeated on loading even a 30mb image.
#Override
protected void onActivityResult(int RC, int RQC, Intent I) {
super.onActivityResult(RC, RQC, I);
if (RC == 1 && RQC == RESULT_OK && I != null && I.getData() != null) {
Uri uri = I.getData();
RequestOptions options = new RequestOptions()
.format(DecodeFormat.PREFER_ARGB_8888)
.placeholder(R.drawable.ic_launcher_background)
.error(R.drawable.ic_launcher_background);
Glide.with(this)
.setDefaultRequestOptions(options)
.asBitmap()
.load(uri)
.centerInside()
.into(new CustomTarget<Bitmap>(512, 512) {
#Override
public void onResourceReady(#NonNull Bitmap bitmap1, #Nullable Transition<? super Bitmap> transition) {
imageView1.setImageBitmap(bitmap1);
UploadActivity.this.bitmap1 = bitmap1;
}
#Override
public void onLoadCleared(#Nullable Drawable placeholder) {
}
});
}

ByteArrayOutputStream holds all data in memory. So you cannot store data larger than the heap. Modify the "manifest" in the first way.
AndroidManifest.xml
<application
android:largeHeap="true">
</application>
Use FileInputStream instead of ByteArrayOutputStream.

You should decode bitmap to decrease the size of bitmap before upload to sever:
You can change size(reqWidth\reqHeight) at your disposal
You can refer to my Github to get full code: https://github.com/vancuong0429/ResizeImageUtil/blob/master/ResizeImageUtil
To get a file from onActivityResult(), You can refer link
Android Studio get File from Gallery Intent
In onActivityResult():
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (RC == 1 && RQC == RESULT_OK && I != null && I.getData() != null) {
Uri uri = I.getData();
// Creating file
// Get the path from the Uri
final String path = getPathFromURI(uri);
if (path != null) {
File yourFile = new File(path);
bitmap1 = decodeBitmapFromFile(yourFile, 512, 512)
}
}
}
public String getPathFromURI(Uri contentUri) {
String res = null;
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(contentUri, proj, null,
null, null);
if (cursor.moveToFirst()) {
int column_index =
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
fun decodeBitmapFromFile(imageFile: File, reqWidth: Int, reqHeight: Int): Bitmap {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeFile(imageFile.absolutePath, options)
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false
var scaledBitmap = BitmapFactory.decodeFile(imageFile.absolutePath, options)
scaledBitmap = modifyOrientation(scaledBitmap, imageFile.absolutePath)
return scaledBitmap
}

Related

FileNotFoundException: No files supported by provider at content

I have an error whenever I try to take a picture by using camera intent.
This is the error
FileNotFoundException: No files supported by provider at content://com.example.fahad.inventory/my_images/dcim/Inventory/JPEG20170922_170324_1975076666.jpg
at com.example.fahad.inventory.AddProductActivity.getBitmap(AddProductActivity.java:270) 09-22 17:03:30.117 12950-12950/? W/System.err: at com.example.fahad.inventory.AddProductActivity.onActivityResult(AddProductActivity.java:197)
This is my code
public class AddProductActivity extends AppCompatActivity {
private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final int REQUEST_SELECT_IMAGE = 2;
private static final String IMAGE_PATH = "imagePath";
private static final String IMAGE_URI = "imageUri";
private static final String BITMAP = "bitmap";
private static final String CAMERA_DIR = "/dcim/";
private String imagePath = "";
private String imageUri = "";
private ImageView imageView;
private Bitmap bitmap;
private Uri mUri;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_product);
Button addProduct = (Button) findViewById(R.id.id_btn_add_product);
Button addImage = (Button) findViewById(R.id.id_btn_add_image);
Button addGalleryImage = (Button) findViewById(R.id.id_btn_add_gallery_image);
imageView = (ImageView) findViewById(R.id.id_image_view);
if (savedInstanceState != null) {
imagePath = savedInstanceState.getString(IMAGE_PATH);
imageUri = savedInstanceState.getString(IMAGE_URI);
bitmap = (Bitmap) savedInstanceState.get(BITMAP);
imageView.setImageBitmap(bitmap);
}
addProduct.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
insert();
}
});
addImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
File f = createImageFile();
mUri = FileProvider.getUriForFile(
AddProductActivity.this, ProductContract.CONTENT_AUTHORITY, f);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);
// Solution taken from http://stackoverflow.com/a/18332000/3346625
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(takePictureIntent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
grantUriPermission(packageName, mUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
}
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
addGalleryImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
} else {
intent = new Intent(Intent.ACTION_GET_CONTENT);
}
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "Select image"), REQUEST_SELECT_IMAGE);
}
});
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG" + timeStamp + "_";
File albumF = getAlbumDir();
File imageF = File.createTempFile(imageFileName, ".jpg", albumF);
return imageF;
}
private File getAlbumDir() {
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
storageDir = new File(Environment.getExternalStorageDirectory()
+ CAMERA_DIR
+ getString(R.string.app_name));
if (storageDir != null) {
if (!storageDir.mkdirs()) {
if (!storageDir.exists()) {
return null;
}
}
}
} else {
Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
}
return storageDir;
}
public void insert() {
EditText editProductName = (EditText) findViewById(R.id.id_edit_product_name);
EditText editProductPrice = (EditText) findViewById(R.id.id_edit_product_price);
EditText editProductQuantity = (EditText) findViewById(R.id.id_edit_product_quantity);
String name = editProductName.getText().toString();
String quantity = editProductQuantity.getText().toString();
String price = editProductPrice.getText().toString();
ContentValues values = new ContentValues();
values.put(ProductContract.ProductColumns.PRODUCT_NAME, name);
values.put(ProductContract.ProductColumns.PRODUCT_QUANTITY, quantity);
values.put(ProductContract.ProductColumns.PRODUCT_PRICE, price);
values.put(ProductContract.ProductColumns.PRODUCT_IMAGE_PATH, imagePath);
values.put(ProductContract.ProductColumns.PRODUCT_IMAGE_URI, imagePath);
Uri uri = getContentResolver().insert(ProductContract.ProductColumns.CONTENT_URI, values);
if (uri != null) {
finish();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
imageUri = mUri.getPath();
bitmap = getBitmap(mUri);
imageView.setImageBitmap(bitmap);
} else if (requestCode == REQUEST_SELECT_IMAGE && resultCode == RESULT_OK) {
if (data != null) {
Uri uri = data.getData();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final int flags = data.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION;
ContentResolver contentResolver = getContentResolver();
contentResolver.takePersistableUriPermission(uri, flags);
}
imageView.setImageBitmap(getBitmapFromUri(uri));
imageUri = uri.toString();
imagePath = uri.toString();
}
}
}
public Bitmap getBitmapFromUri(Uri uri) {
if (uri == null || uri.toString().isEmpty())
return null;
// Get the dimensions of the View
int targetW = imageView.getWidth();
int targetH = imageView.getHeight();
InputStream input = null;
try {
input = this.getContentResolver().openInputStream(uri);
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(input, null, bmOptions);
input.close();
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;
input = this.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bmOptions);
input.close();
return bitmap;
} catch (FileNotFoundException fne) {
fne.printStackTrace();
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
input.close();
} catch (IOException ioe) {
}
}
}
private Bitmap getBitmap(Uri uri) {
ParcelFileDescriptor parcelFileDescriptor = null;
try {
parcelFileDescriptor =
getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
return image;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (parcelFileDescriptor != null) {
parcelFileDescriptor.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(IMAGE_PATH, imagePath);
outState.putString(IMAGE_URI, imageUri);
outState.putParcelable(BITMAP, bitmap);
}
The contentAuthority is my package name.
com.example.fahad.inventory
And this is my paths :
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="my_images" />
</paths>
And this is my provider in manifest :
<provider
android:name=".data.ProductProvider"
android:authorities="com.example.fahad.inventory"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider_paths" />
</provider>
I have seen some posts like this by I don't understands it. or it didn't help me with my problem.
The error in the logs are pointing to :
getContentResolver().openFileDescriptor(uri, "r");
Also the data returned in onActivityResult from the camera is always null.
I think the problem is I have to implement OpenFile method in my custom contentProvider but the problem I don't know what to write in that method.
Or the getUriForFile return wrong uri.
Please help me I'm in this problem for two weeks now and it seems I'm not going anywhere.
And I'm new to contentProvider.
Thanks in Advance And happy coding !

Get image from storage not working in Android

I am capturing an image and store it in storage in mobile but when I get this image it cannot show any thing in Image View. I have tried a lot of code to get images from file but none of them are working in my emulator or real Samsung device.
enter code here
imageHolder = (ImageView)findViewById(R.id.captured_photo);
Button capturedImageButton = (Button)findViewById(R.id.photo_button);
capturedImageButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent photoCaptureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(photoCaptureIntent, requestCode);
}
});
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(this.requestCode == requestCode && resultCode == RESULT_OK){
Bitmap bitmap = (Bitmap)data.getExtras().get("data");
String partFilename = currentDateFormat();
storeCameraPhotoInSDCard(bitmap, partFilename);
// display the image from SD Card to ImageView Control
String storeFilename = "photo_" + partFilename + ".jpg";
Bitmap mBitmap = getImageFileFromSDCard(storeFilename);
imageHolder.setImageBitmap(mBitmap);
}
}
private String currentDateFormat(){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HH_mm_ss");
String currentTimeStamp = dateFormat.format(new Date());
return currentTimeStamp;
}
private void storeCameraPhotoInSDCard(Bitmap bitmap, String currentDate){
File outputFile = new File(Environment.getExternalStorageDirectory(), "photo_" + currentDate + ".jpg");
try {
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private Bitmap getImageFileFromSDCard(String filename){
/* Bitmap bitmap = null;
File imageFile = new File(Environment.getExternalStorageDirectory() + filename);
try {
FileInputStream fis = new FileInputStream(imageFile);
bitmap = BitmapFactory.decodeStream(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return bitmap; */
File imageFile = new File(Environment.getExternalStorageDirectory() + filename);
// File imgFile = new File(filename);
//("/sdcard/Images/test_image.jpg");
Bitmap myBitmap;
if(imageFile.exists()){
myBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
// ImageView myImage = (ImageView) findViewById(R.id.imageviewTest);
// myImage.setImageBitmap(myBitmap);
return myBitmap;
}
return null;
}
First of All make sure you have declared the "Access External Storage" and "Access Hardware Camera" permissions in "AndroidManifest" and if you are using Android version 23 or 23+ then you have to take permissions on run-time.
If this is not the problem then use this code given below, it's working fine for me.
For Camera:
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, ACTION_REQUEST_CAMERA);
For Gallery:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
Intent chooser = Intent.createChooser(intent, "Choose a Picture");
startActivityForResult(chooser, ACTION_REQUEST_GALLERY);
OnActivityResultMethod:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case ACTION_REQUEST_GALLERY:
Uri galleryImageUri = data.getData();
try{
Log.e("Image Path Gallery" , getPath(getActivity() , galleryImageUri));
selectedImagePath = getPath(getActivity() , galleryImageUri);
} catch (Exception ex){
ex.printStackTrace();
Log.e("Image Path Gallery" , galleryImageUri.getPath());
selectedImagePath = galleryImageUri.getPath();
}
break;
case ACTION_REQUEST_CAMERA:
// Uri cameraImageUri = initialURI;
Uri cameraImageUri = data.getData();
Log.e("Image Path Camera" , getPath(cameraImageUri));
selectedImagePath = getPath(cameraImageUri);
break;
}
}
}
Method to get path of Image returned from Camera:
/**
* helper to retrieve the path of an image URI
*/
public String getPath(Uri uri) {
// just some safety built in
if( uri == null ) {
// TODO perform some logging or show user feedback
return null;
}
// try to retrieve the image from the media store first
// this will only work for images selected from gallery
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().managedQuery(uri, projection, null, null, null);
if( cursor != null ){
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
// this is our fallback here
return uri.getPath();
}

Select multiple images from Photo Gallery on Android using Intents NullPointerException

I try to select multiple images from photo gallery and save it in my custom folder on sdCard.
I wrote some code but i have nullPintException
this is a my source
Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), PICK_FROM_GALLERY);
and this is OnActivityResultCode
if(data!=null)
{
ClipData clipData = data.getClipData();
for (int i = 0; i < clipData.getItemCount(); i++)
{
Uri selectedImage = clipData.getItemAt(i).getUri();
if (selectedImage != null) {
mCurrentPhotoPath = getRealPathFromURI(selectedImage);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, options);
// bitmap=getResizedBitmap(bitmap,1280,720);
String partFilename = currentDateFormat();
if (bitmap != null) {
SaveImage(bitmap, partFilename);
}
}
}
public String getRealPathFromURI(Uri uri) {
Cursor cursor = CarRecieveActivity.this.getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
private void SaveImage(Bitmap finalBitmap,String fileName) {
File myDir = new File(rootDirectory + "/"+vinNumber.getText().toString());
myDir.mkdirs();
String fname = fileName+".jpg";
File file = new File (myDir, fname);
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
this is my source .i have two errors.
first when i click only one image in my gallery clipData is null and second,when i choose multiple images from gallery and click ok button i have this error
java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it
error is in this function getRealPathFromURI()
how i can solve both problems?
thanks
Select images from device
//Uri to store the image uri
private List<Uri> filePath;
public String path[];
public static List<ImageBeen> listOfImage;
//Image request code
private int PICK_IMAGE_REQUEST = 1;
private int PICK_IMAGE_REQUEST_MULTI = 2;
// select multiple image
private void pickImages() {
filePath = new ArrayList<>();
listOfImage = new ArrayList<>();
Intent intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST_MULTI);
}else {
intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
}
Activity result
//handling the image chooser activity result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST_MULTI && resultCode == RESULT_OK && data != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
ClipData imagesPath = data.getClipData();
if (imagesPath != null) {
path = new String[imagesPath.getItemCount()];
for (int i = 0; i < imagesPath.getItemCount(); i++) {
filePath.add(imagesPath.getItemAt(i).getUri());
path[i] = getPath(imagesPath.getItemAt(i).getUri());
ImageBeen imageBeen = new ImageBeen(imagesPath.getItemAt(i).getUri());
imageBeen.setPath(path[i]);
listOfImage.add(imageBeen);
initViewPager();
}
}else {
path = new String[1];
path[0] = getPath(data.getData());
ImageBeen imageBeen = new ImageBeen(data.getData());
imageBeen.setPath(path[0]);
listOfImage.add(imageBeen);
initViewPager();
}
} else if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null) {
path = new String[1];
path[0] = getPath(data.getData());
ImageBeen imageBeen = new ImageBeen(data.getData());
imageBeen.setPath(path[0]);
listOfImage.add(imageBeen);
initViewPager();
}
}
genarate images path using Image URI
//method to get the file path from uri
public String getPath(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
String path = null;
if(cursor!=null) {
if (cursor.moveToFirst()) {
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
cursor.close();
cursor = getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
return path;
}
}
return path;
}
This is image bean where stored image URI and Image path
public class ImageBeen {
private Uri fileUri;
private String path;
public ImageBeen(Uri fileUri)
{
this.fileUri=fileUri;
}
public String getPath() {
return path;
}
public void setPath(String path)
{
this.path=path;
}
public Uri getFileUri() {
return fileUri;
}
}
For display image use Picasso
compile 'com.squareup.picasso:picasso:2.5.2'
Picasso.with(context)
.load(imageBeen.getFileUri())
.placeholder(R.drawable.not_vailable)
.error(R.drawable.not_vailable)
.into(holder.image);

Application crashes after selecting bitmap image from gallery/camera (maybe scaling is solution)

I have an application with an image view, and when i click on it it opens menu of choosing Take From Gallery/ Open Camera.
after i choose a large image (large size or large scaling) the app crashes.
how can i fix it?
this is the code and logcat:
Select image+onActivityResult:
private void selectImage() {
final CharSequence[] options = { "Take Photo", "Choose From Gallery",
"Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(
AddContactActivity.this);
builder.setTitle("Add Photo!");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Take Photo"))
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment
.getExternalStorageDirectory(), "temp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(intent, 1);
} else if (options[item].equals("Choose From Gallery")) {
Intent intent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 2);
} else if (options[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == 1) {
File f = new File(Environment.getExternalStorageDirectory()
.toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
break;
}
}
try {
Bitmap bitmap;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),
bitmapOptions);
imginAdd.setImageBitmap(bitmap);
ByteArrayOutputStream stream3 = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream3);
byteArray = stream3.toByteArray();
String path = android.os.Environment
.getExternalStorageDirectory()
+ File.separator
+ "Phoenix" + File.separator + "default";
f.delete();
OutputStream outFile = null;
File file = new File(path, String.valueOf(System
.currentTimeMillis()) + ".jpg");
try {
outFile = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outFile);
outFile.flush();
outFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
} else if (requestCode == 2) {
Uri selectedImage = data.getData();
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor c = getContentResolver().query(selectedImage, filePath,
null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
Bitmap bitmap = (BitmapFactory.decodeFile(picturePath));
Log.w("path of image from gallery......******************.........",
picturePath + "");
imginAdd.setImageBitmap(bitmap);
ByteArrayOutputStream stream4 = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream4);
byteArray = stream4.toByteArray();
}
}
}
Getting the image from another through sql:
(4 lines as one code, i have problem with quoting:)
Blockquote byte[] photo = rs.getBlob(rs
.getColumnIndex(DBHelper.CONTACTS_COLUMN_IMAGE));
ByteArrayInputStream imageStream = new ByteArrayInputStream(photo);
Bitmap theImage = BitmapFactory.decodeStream(imageStream);
imginView.setImageBitmap(theImage);
LOGCAT: http://textuploader.com/69on
Simply use this function which will decode your large image too.
private void setPic(final String path) {
int targetW = imageView.getWidth();
int targetH = imageView.getHeight();
final BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
bitmap = BitmapFactory.decodeFile(path, bmOptions);
}
Now call this function after retrieve your image path from gallery
setPic(imagepath);
imageView.setImageBitmap(bitmap); // this bitmap object will be declare globally

Getting a crash when taking a picture on Android. Why?

When I take a picture with my device, this code is crashing on the inputStream = line with an error of java.lang.NullPointerException
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri uriImage;
InputStream inputStream = null;
ImageView imvCover = (ImageView)this.findViewById(R.id.imvCover);
if ((requestCode == CAPTURE_IMAGE) && resultCode == Activity.RESULT_OK) {
uriImage = data.getData();
try {
inputStream = getContentResolver().openInputStream(uriImage);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, null);
imvCover.setImageBitmap(bitmap);
} catch (NullPointerException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
imvCover.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imvCover.setAdjustViewBounds(true);
}
}
Any ideas why?
This is the code I am using to open the camera to take a picture:
Button btnTakePicture = (Button)this.findViewById(R.id.btnTakePicture);
btnTakePicture.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE);
}
});
try this..
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File out = Environment.getExternalStorageDirectory();
out = new File(out, "newImage.jpg");
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out));
startActivityForResult(i, 1);
and this is onActivity result..
#Override
protected void onActivityResult(int requestCode, int resultcode, Intent intent)
{
super.onActivityResult(requestCode, resultcode, intent);
File out = new File(Environment.getExternalStorageDirectory(), "newImage.jpg");
if(!out.exists())
{
Log.v("log", "file not found");
Toast.makeText(getBaseContext(),
"Error while capturing image", Toast.LENGTH_LONG)
.show();
return;
}
Log.v("log", "file "+out.getAbsolutePath());
File f = new File(out.getAbsolutePath());
try {
ExifInterface exif = new ExifInterface(out.getAbsolutePath());
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
//Toast.makeText(getApplicationContext(), ""+orientation, 1).show();
Log.v("log", "ort is "+orientation);
} catch (IOException e)
{
e.printStackTrace();
}
Bitmap photo =decodeFile(f,400,400);
}
and this is decodeFile Function...
public static Bitmap decodeFile(File f,int WIDTH,int HIGHT){
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_WIDTH=WIDTH;
final int REQUIRED_HIGHT=HIGHT;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale/2>=REQUIRED_WIDTH && o.outHeight/scale/2>=REQUIRED_HIGHT)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
return null;
}
This approach may not work for all devices. Instead, you can specify where the new image would be saved, and then you can use that pre-determined file path to work with the new image.
File tempFolder = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/your_folder");
tempFolder.mkdir();
file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/your_folder", String.valueOf(System.currentTimeMillis()) + ".jpg");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, TAKE_PICTURE);

Categories

Resources