I try show a bitmap from the gallery. this is my URL
file:///storage/emulated/0/DCIM/Camera/IMG_20161103_180603.jpg
I know how to get bitmap using onActivityResult(), but I don't know how to get a bitmap
this is my source
final ImageView imageView=(ImageView)findViewById(R.id.imageView);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
final Bitmap bitmap = BitmapFactory.decodeFile("file:///storage/emulated/0/DCIM/Camera/IMG_20161103_180603.jpg", options);
runOnUiThread(new Runnable() {
#Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
How can I solve my problem?
please refer below code
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
//Get our saved file into a bitmap object:
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "DCIM"+ File.separator + "Camera "+File.separator + "IMG_20161103_180603.jpg");
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
imageView.setImageBitmap(bitmap);
I had the same problem caused by large image size which couldn't be processed at run time. Solved it using this.
// Decodes image and scales it to reduce memory consumption
public static Bitmap decodeFile(File f) {
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_SIZE = 200;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE &&
o.outHeight / scale / 2 >= REQUIRED_SIZE) {
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) {
e.printStackTrace();
}
return null;
}
where File f will be retrieved using https://stackoverflow.com/a/20559418/3758972
just put the size of thumbnail you want (typically the size of your imageview) in REQUIRED_SIZE and you are done. It will give you a scaled image which you can set to your imageview.
decodeFile( "file:///storage/emulated/0/DCIM/Camera/IMG_20161103_180603.jpg
Change to:
decodeFile( "/storage/emulated/0/DCIM/Camera/IMG_20161103_180603.jpg
Related
I'm facing this problem since a month with no solution:
I need to convert a file into a bitmap and rescaling it.
I'm using the following method, taken from android guide: Loading Large Bitmaps Efficiently
public Bitmap decodeSampledBitmapFromFile(String path, int reqSize) {
// First decode with inJustDecodeBounds=true to check dimensions
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inMutable = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
double ratio = (double) options.outHeight / options.outWidth;
boolean portrait = true;
if (ratio < 1) {
portrait = false;
}
double floatSampleSize = options.outHeight / (double)reqSize;
options.inSampleSize = (int) Math.floor(floatSampleSize);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap resultBitmap = BitmapFactory.decodeFile(path, options);
if(floatSampleSize % options.inSampleSize != 0){
if(portrait) {
resultBitmap = Bitmap.createScaledBitmap(resultBitmap, (int)(reqSize/ratio), reqSize, true);
} else {
resultBitmap = Bitmap.createScaledBitmap(resultBitmap, reqSize, (int)(ratio*reqSize), true);
}
}
return resultBitmap;
}
I've got the same NullPointerException but i can't reproduce it:
NullPointerException (#Utilities:decodeSampledBitmapFromFile:397) {AsyncTask #2}
NullPointerException (#Utilities:decodeSampledBitmapFromFile:399) {AsyncTask #3}
lines 397 and 399 are:
resultBitmap = Bitmap.createScaledBitmap(resultBitmap, (int)(reqSize/ratio), reqSize, true);
resultBitmap = Bitmap.createScaledBitmap(resultBitmap, reqSize, (int)(ratio*reqSize), true);
in this device models:
ST21a
U9500
M7
U8950-1
GT-I9305
Someone can help me to solve this?
is BitmapFactory.decodeFile returns null?
thank you so much
Try this hope works for you
public Bitmap decodeFile(String path, int reqSize) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, o);
// The new size we want to scale to
final int REQUIRED_SIZE = reqSize;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE)
scale *= 2;
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeFile(path, o2);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
I am Getting error on my code : Out of Memory Error
Below is my code :
public class ViewFullImage extends Activity {
//Bitmap bitmap;
private Bitmap bitmap;
private ImageView iv;
private String ImgFile_Name;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.view_draw_picture);
Log.v("","===================== viewFullImage.java================");
try{
String path = "mfc/cam_img/";
int s_id=getIntent().getIntExtra("s_id", -1);
int intentKey=getIntent().getIntExtra("iv", -1);
iv = (ImageView)findViewById(R.id.iv_display);
File Dir= Environment.getExternalStorageDirectory();
File imageDirectory = new File(Dir,path);
File file = new File(imageDirectory, "img_"+s_id+"_"+intentKey+".jpg");
ImgFile_Name = file.getAbsolutePath();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = 1;
BitmapFactory.decodeFile(file.getAbsolutePath(),options);
int h = options.outHeight;
int w = options.outWidth;
Log.v("","This is h : "+h);
Log.v("","This is w : "+w);
bitmap = BitmapFactory.decodeFile(ImgFile_Name,options);
iv = (ImageView)findViewById(R.id.image);
if(h<w)
{
iv.setImageBitmap(rotateBitmap(bitmap));
}
else{
iv.setImageBitmap(bitmap);
}
}catch (Exception e) {
// TODO: handle exception
Log.v("","Exception : "+e);
}
}
Bitmap rotateBitmap(Bitmap bitmap)
{
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap bitmap1 = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(),
matrix, true);
bitmap.recycle();
bitmap=null;
return bitmap1;
}
}
In this class i am trying to displaying image from sdcard. I am calling this Activity from other activities Like :
Intent intent =new Intent(cxt,ViewFullImage.class);
intent.putExtra("iv", 8);
intent.putExtra("s_id", s_id);
startActivity(intent);
Please somebody tell where i m doing mistack.....
You aren't doing anything wrong, you can't just allocate an image (or even a large string) in Android without knowing if it's going to fit in memory.
The problem happens in Android 4 devices because there is more 4.0 devices out there with only 16MB heaps. The memory heap is the memory where you will open your image in.
To solve this issue you should scale your image if required (depending both on the heap size and image size). Below is the code for how to decode with scaling:
public static Bitmap decodeSampleImage(File f, int width, int height) {
try {
System.gc(); // First of all free some memory
// 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 requiredWidth = width;
final int requiredHeight = height;
// Find the scale value (as a power of 2)
int sampleScaleSize = 1;
while (o.outWidth / sampleScaleSize / 2 >= requiredWidth && o.outHeight / sampleScaleSize / 2 >= requiredHeight)
sampleScaleSize *= 2;
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = sampleScaleSize;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (Exception e) {
Log.d(TAG, e.getMessage()); // We don't want the application to just throw an exception
}
return null;
}
The other thing is, if you don't free some memory (System.gc()) and you click/switch between many pictures you may run out of memory anyway. If you run out of memory you don't want to blow the app, instead manage the case where the Bitmap is null. You can improve the Exception's catch cases for that as well.
Hope it helps.
I am doing a "Image Editor" like application. I used default camera intent to capture the image. I used to parse the URI and set that to the image view like the following:
imgCaptured.setImageURI(Uri.parse(filePath));
If I use this raw image, occasionally it is throwing me out of memory error! So I decided to decode the image using the following:
"Got from stackoverflow"
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
preview_bitmap = BitmapFactory.decodeStream(is, null, options);
private Bitmap decodeFile(File f) {
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_SIZE = 95;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE
&& o.outHeight / scale / 2 >= REQUIRED_SIZE)
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;
}
If I use the decoded image, the output is not in good quality. Some how it seems to be blur. I want a good clear image! After setting it into the ImageView. I need to drag and drop another views.
How can I achieve the above?
What is a good way to do this?
what is the reason to divide by 2 in the loop ?
try this
while (o.outWidth / scale >= REQUIRED_SIZE
&& o.outHeight / scale >= REQUIRED_SIZE)
Probably You also would like to scale the image to the view's size with this method
http://developer.android.com/reference/android/graphics/Bitmap.html#createScaledBitmap(android.graphics.Bitmap, int, int, boolean)
change options.inSampleSize = 8 to options.inSampleSize = 4.
The method which you had used is not complete, you have to add few Math functions to, too maintain the quality of the image.
private static Bitmap decodeFile(File f) {
Bitmap b = null;
final int IMAGE_MAX_SIZE = 100;
try {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int) Math.pow(
2.0,
(int) Math.round(Math.log(IMAGE_MAX_SIZE
/ (double) Math.max(o.outHeight, o.outWidth))
/ Math.log(0.5)));
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
} catch (Exception e) {
Log.v("Exception in decodeFile() ", e.toString() + "");
}
return b;
}
Please let me know, if it worked for you...!!!!:)
i am displaying my images from assests/image folder ,
but this code is not working . this code display images from assets folder in gallery . i am using gallery prefine library or jar file.
please expert check it . thank u
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("image");
} catch (IOException e) {
Log.e("tag", e.getMessage());
}
for(String filename : files) {
System.out.println("File name => "+filename);
InputStream in = null;
try {
ImageViewTouch imageView = new ImageViewTouch(Rahul.this);
imageView.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
final Options options = new Options();
options.outHeight = (int) scaleHeight;
options.outWidth = (int) scaleWidth;
options.inScaled = true;
options.inPurgeable = true;
options.inSampleSize = 2;
in = assetManager.open("image/"+filename);
Bitmap bit=BitmapFactory.decodeStream(in);
imageView.setImageBitmap(bit);
} catch(Exception e) {
Log.e("tag", e.getMessage());
}
}
gallery.setAdapter(arrayAdapter);
Hey please check my answer on the same issue: bitmap size exceeds Vm budget error android
And also always try to use maximum options while dealing with bitmaps like this:
final Options options = new Options();
options.outHeight = (int) scaleHeight; // new smaller height
options.outWidth = (int) scaleWidth; // new smaller width
options.inScaled = true;
options.inPurgeable = true;
// to scale the image to 1/8
options.inSampleSize = 8;
bitmap = BitmapFactory.decodeFile(imagePath, options);
This might solve your problem.
1) try to use bitmap.recycle(); to release memory before setting a new bitmap to your images
BitmapDrawable drawable = (BitmapDrawable) myImage.getDrawable();
Bitmap bitmap = drawable.getBitmap();
if (bitmap != null)
{
bitmap.recycle();
}
2) if your images are too large scale down them:
public static Bitmap decodeFile(File file, int requiredSize) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(file), null, o);
// The new size we want to scale to
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < requiredSize
|| height_tmp / 2 < requiredSize)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(file),
null, o2);
return bmp;
} catch (FileNotFoundException e) {
} finally {
}
return null;
}
Update
something like this:
for(int i=0; i<it.size();i++) {
ImageViewTouch imageView = new ImageViewTouch(GalleryTouchTestActivity.this);
imageView.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
Options options = new Options();
options.inSampleSize = 2;
String photoURL = it.get(i);
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bitmap = drawable.getBitmap();
if (bitmap != null)
{
bitmap.recycle();
}
bitmap = BitmapFactory.decodeFile(photoURL);
imageView.setImageBitmap(bitmap);
arrayAdapter.add(imageView);
}
I want to resize an image on the sd card and send it to a Web service, the call is asynchronous and ParcelFileDescriptor and CountingInputStreamEntity use to display progress bar. What should I do to resize and send in the same way ! This is my current code:
ParcelFileDescriptor fileDescriptor = context.getContentResolver().openFileDescriptor(uri, "r");
InputStream in = context.getContentResolver().openInputStream(uri);
CountingInputStreamEntity entity = new CountingInputStreamEntity(in, fileDescriptor.getStatSize());
entity.setUploadListener(this);
entity.setContentType("application/octet-stream");
put.setEntity(entity);
Thanks in Advance.
The image can be re-sized by using BitmapFactory.Options
You need to create a new small width and height of the image like following:
private Bitmap decodeFile(File f){
Bitmap b = null;
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
} catch (IOException e) {
}
return b;
}
To resize the camera image you can use the following code in onActivitResult().
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap receipt = BitmapFactory.decodeFile(photo.toString(),options);
In which the you can resize the image using options.inSampleSize and then pass that image to the web service by your style.
I hope it helps..