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..
Related
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
After calling gallery intent and getting the image URI in onActivityResult()
Uri selectedImageUri = data.getData();
String filePath;
try {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImageUri,
projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
filePath = cursor.getString(column_index);;
} catch (Exception e) {
}
File imageFile = new File(filePath);
Bitmap bitmap = decodeFile(imageFile.getAbsolutePath());
imageView.setImageBitmap(bitmap);
But the image in the imageView is rotated 90 degree. I even sent the image as a file to a web server and that's rotated too.
So, I tried checking for the Exif details,
//getOutputMediaFile() just returns a filepath to store image in my app folder
String newFilePath = getOutputMediaFile();
//800 is the desired width and height
Bitmap photo = decodeSampledBitmapFromFile(filePath, 800, 800);
//reduce the size of the image and store it in a new file ie.. newFilePath
FileOutputStream out = new FileOutputStream(newFilePath);
photo.compress(Bitmap.CompressFormat.JPEG, 100, out);
ExifInterface exif = new ExifInterface(newFilePath);
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
//If rotation is required
if (rotation != 0) {
Matrix matrix = new Matrix();
matrix.preRotate(rotationInDegrees);
File imageFile = new File(newFilePath);
//get the same image
Bitmap bitmap = decodeFile(imageFile.getAbsolutePath());
//rotate it
Bitmap adjustedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
//and save in the same file
FileOutputStream out2 = new FileOutputStream(newFilePath);
adjustedBitmap.compress(Bitmap.CompressFormat.JPEG, 100,out2);
}
decodeSampledBitmapFromFile()
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth,
int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize, Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
int inSampleSize = 1;
if (height > reqHeight) {
inSampleSize = Math.round((float) height / (float) reqHeight);
}
int expectedWidth = width / inSampleSize;
if (expectedWidth > reqWidth) {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
decodeFile()
private Bitmap decodeFile(String path) {
IMAGE_MAX_SIZE = 800;
Bitmap b = null;
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
File f = new File(path);
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 null;
}
return b;
}
The code never goes inside if(rotation != 0f){}. Which means the image Orientation is proper, then why the file I get or the Bitmap I get are rotated. What am I missing?
Hi I download images from url & save them in cache. Then load those images from cache into carousel view.
but the problem is when phone resolution(720X1124) is high image size become small.
Here I give the code of images save & show them from cach...
private Bitmap getBitmap(String url)
{
File f=fileCache.getFile(url);
//from SD cache
Bitmap b = decodeFile(f);
if(b!=null)
return b;
//from web
try {
Bitmap bitmap=null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(300000000);
conn.setReadTimeout(300000000);
conn.setInstanceFollowRedirects(true);
InputStream inputstream=conn.getInputStream();
OutputStream outputstream = new FileOutputStream(f);
Utils.CopyStream(inputstream, outputstream);
outputstream.close();
conn.disconnect();
bitmap = decodeFile(f);
return bitmap;
} catch (Throwable ex){
ex.printStackTrace();
if(ex instanceof OutOfMemoryError)
memoryCache.clear();
return null;
}
}
public void getDimension(int width,int height){
widthScreen=width;
heightScreen=height;
}
//decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f){
try {
//decode image size
final int IMAGE_MAX_SIZE = 120000000; // 1.2MP
BitmapFactory.Options scaleOptions = new BitmapFactory.Options();
scaleOptions.inJustDecodeBounds = true;
FileInputStream stream1=new FileInputStream(f);
BitmapFactory.decodeStream(stream1,null,scaleOptions);
stream1.close();
// find the correct scale value as a power of 2.
int scale = 1;
while (scaleOptions.outWidth / scale / 2 >= widthScreen
&& scaleOptions.outHeight / scale / 2 >= heightScreen) {
scale *= 2;
}
Bitmap bitmap = null;
if (scale > 1) {
scale--;
// scale to max possible inSampleSize that still yields an image
// larger than target
scaleOptions = new BitmapFactory.Options();
scaleOptions.inSampleSize = scale;
bitmap = BitmapFactory.decodeStream(stream1, null, scaleOptions);
int width=widthScreen;
int height=heightScreen;
double y=height;
double x=width;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, (int) x,
(int) y, true);
bitmap.recycle();
bitmap = scaledBitmap;
System.gc();
} else {
bitmap = BitmapFactory.decodeStream(stream1);
}
if((widthScreen>=450)&& (heightScreen>=750) ) {
sample=1;
}
else{
sample=2;
}
//decode with inSampleSize
BitmapFactory.Options scalOption = new BitmapFactory.Options();
scalOption.inSampleSize=sample;
FileInputStream stream2=new FileInputStream(f);
Bitmap bitMap=BitmapFactory.decodeStream(stream2, null, scalOption);
stream2.close();
return bitMap;
} catch (FileNotFoundException e) {
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
how to increase the image sizes according phone resolution. I have tired more days to overcome this problem. But it doesn't work. So give me right instruction.......
thanks............
You need to define your layout for the different screen sizes / resolutions.
See Supporting Multiple Screens.
try to load images with this image loader library
public 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;
}
put this method in my code and call this method as following way ,
private Bitmap decodeFile(File f) {
try {
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream stream1 = new FileInputStream(f);
BitmapFactory.decodeStream(stream1, null, o);
stream1.close();
Matrix matrix = new Matrix();
// matrix.postScale(scaleWidth, scaleHeight);
matrix.postRotate(45);
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
//calculateInSampleSize1(o, widthScreen,heightScreen);
o2.inSampleSize=calculateInSampleSize(o, widthScreen,heightScreen);;
FileInputStream stream2 = new FileInputStream(f);
o2.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
stream2.close();
return bitmap;
} catch (FileNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
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);
}