How Get bitmap from input stream after decode size - android

I want to get bitmap from a inputstream, then resize it. But I am getting null pointer exception.
I try inputstream.reset() but not working.
Can anybody help please?
BufferedInputStream my_is = new BufferedInputStream(is);
Bitmap bit = null;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(my_is, null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
try {
my_is.reset();
} catch (IOException e) {
e.printStackTrace();
}
bit = BitmapFactory.decodeStream(my_is, null, options);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
FileOutputStream fos = null;
try {
fos = getActivity().openFileOutput(timeStamp + ".png", Context.MODE_PRIVATE);
bit.compress(Bitmap.CompressFormat.PNG,90,fos);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
crud.update_photo_path(String.valueOf(position), timeStamp);
return bit;

I used this utils:
public static Bitmap decodeSampledBitmapFromResource(String uri,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(uri, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(uri, options);
}
private static 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;
}

Related

jerky scroll while loading image from local storage

While loading image from local storage path in Coordinator Layout and app bar layout getting jerky while scrolling
I had used myImageview.setImageURI(MYURI); but not working properly
My issue was solved as i am using Picasso i had tried using bellow code
Picasso.with(context).load(YOUR_IMAGE_URI).placeholder(R.drawable.profile_img).error(R.drawable.profile_imgd).resize(250,250).centerCrop().into(myImageview);
Yet i have tried bellow code but i think it might be helpful
public static Bitmap decodeFile(File f, int reqWidth, int reqHeight) {
Bitmap b = null;
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = calculateInSampleSize(o2,reqWidth, reqHeight);
try {
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return b;
}
public static 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) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}

Sampling a bitmap from url

I am trying to reduce the size of bitmap from a url. I saw many posts, but all were about sampling a local file. I want to sample the image at url. Here is my code:
public Bitmap getScaledFromUrl(String url) {
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 1 / 10;
try {
return BitmapFactory.decodeStream((InputStream) new URL(url)
.getContent());
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Is this approach correct? I am getting out of memory crashes in my app at this function. Any ideas?
This works. I found it at http://blog.vandzi.com/2013/01/get-scaled-image-from-url-in-android.html . Use the following snippet of code, pass params as you like.
private static Bitmap getScaledBitmapFromUrl(String imageUrl, int requiredWidth, int requiredHeight) throws IOException {
URL url = new URL(imageUrl);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(url.openConnection().getInputStream(), null, options);
options.inSampleSize = calculateInSampleSize(options, requiredWidth, requiredHeight);
options.inJustDecodeBounds = false;
//don't use same inputstream object as in decodestream above. It will not work because
//decode stream edit input stream. So if you create
//InputStream is =url.openConnection().getInputStream(); and you use this in decodeStream
//above and bellow it will not work!
Bitmap bm = BitmapFactory.decodeStream(url.openConnection().getInputStream(), null, options);
return bm;
}
private static 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;
}
It's really flexible.. I think you should try it out.
You are using it wrong. You are asking to make the picture 10 times bigger :) You should give the command in normal numbers, not fraction. For example:
final BitmapFactory.Options options2 = new BitmapFactory.Options();
options2.inSampleSize = 8;
b = BitmapFactory.decodeFile(image, options2);
with this configuration you obtain 8 times smaller picture than the original.
UPDATE: To load image from internet add this class to the project and do the following:
ImageLoader loader = new ImageLoader(context);
Bitmap image = loader.getBitmap(URL);

BitmapFactory.Options returns 0 width and height

final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
final int height = options.outHeight;
final int width = options.outWidth;
path is the image file path which is proper.
The problem is options.outHeight and options.outWidth are 0 when the image is captured in Landscape mode with AutoRotate on. If I turn off AutoRotate, it works fine. Since its width and height are 0 I was getting a null Bitmap at the end.
Complete Code:
Bitmap photo = decodeSampledBitmapFromFile(filePath, DESIRED_WIDTH,
DESIRED_HEIGHT);
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);
}
I had the same issue, I fixed it by changing :
BitmapFactory.decodeFile(path, options);
to:
try {
InputStream in = getContentResolver().openInputStream(
Uri.parse(path));
BitmapFactory.decodeStream(in, null, options);
} catch (FileNotFoundException e) {
// do something
}
After that change, the width and height were correctly set.

How to reduce picture size?

I want to send photo taken from camera to server. But it's size around 1M and i believe it is two much. Thus i want to reduce size of the photo. Below method which I am using.
saveFile - simply save bitmap to file and return path to it.
calculateInSampleSize returns inSampleSize to adjust photo dementions to chosen.
decodeSampledBitmapFromResource decodes birmap from file and rebuild it with new parameters.
Evrything is nice but seems not working. Dimentions of small3.png are 1240*768*24 and size is still ~1M.
I call it with
photo = saveFile(decodeSampledBitmapFromResource(picturePath,
800, 800),3);
methods
public String saveFile(Bitmap bm,int id) {
String file_path = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/Mk";
File dir = new File(file_path);
if (!dir.exists())
dir.mkdirs();
File file = new File(dir, "smaller" + id + ".png");
FileOutputStream fOut;
try {
fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return file.getPath();
}
public static 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) {
// Calculate ratios of height and width to requested height and
// width
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will
// guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(String path,
int reqWidth, int reqHeight) {
Log.d("path", path);
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
Why you are writing the image two times just do it in all one time
What i do
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap myBitmap = BitmapFactory.decodeFile({ImagePath}, options);
FileOutputStream fileOutputStream = new FileOutputStream({ImagePath});
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
myBitmapClose.compress(CompressFormat.JPEG, imageQuality, bos);
if (bos != null) {
bos.flush();
bos.close();
}
if (fileOutputStream != null) {
fileOutputStream.flush();
fileOutputStream.close();
}
It will definitely compress Mind the line
myBitmapClose.compress(CompressFormat.JPEG, imageQuality, bos);
where set imageCompression type CompressFormat.JPEG
Thats my code...I want to reduce the size of image where path is String.
String pics=(arraylist.get(position).getImage());
try{
BitmapFactory.Options op = new BitmapFactory.Options();
op.inJustDecodeBounds = true;
//op.inSampleSize = 20; op.outWidth = 25;
op.outHeight = 35;
bmp = BitmapFactory.decodeFile(pics);
image.setImageBitmap(bmp);
}catch(Exception e) {
}

Open an image from Uri, resize and return Base64

I'm trying to open an image from a specific uri, checking if this image is too big to resize it, and return it as Base64. My problem is the code I have to resize image never resize images (never indicate that the image is too big). I looked for others questions similar this, but I didn't get any answer.
I don't know why always in this two code lines the values are -1:
final int height = options.outHeight; // Always -1 WHY?
final int width = options.outWidth; // Always -1 WHY?
I attach my code:
private class WriteImage extends AsyncTask<Object, Void, String>{
private static Bitmap decodeSampledBitmapFromStream(InputStream is,
int reqWidth,
int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream aux = inputStreamCopy(is);
BitmapFactory.decodeStream(is, null, options); // SkImageDecoder::Factory returned null
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(aux, null, options);
}
private static InputStream inputStreamCopy(InputStream is) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len;
byte[] buffer = new byte[1024];
try {
while ((len = is.read(buffer)) > -1) baos.write(buffer, 0, len);
} catch (IOException e) {
e.printStackTrace();
}
return new ByteArrayInputStream(baos.toByteArray());
}
private static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight; // Always -1 WHY?
final int width = options.outWidth; // Always -1 WHY?
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);
// This offers some additional logic in case the image has a strange
// aspect ratio. For example, a panorama may have a much larger
// width than height. In these cases the total pixels might still
// end up being too large to fit comfortably in memory, so we should
// be more aggressive with sample down the image (=larger
// inSampleSize).
final float totalPixels = width * height;
// Anything more than 2x the requested pixels we'll sample down
// further.
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap)
inSampleSize++;
}
for (int i=5; i>0; i--){
if (Math.pow(2, i)<=inSampleSize){
inSampleSize = (int) Math.pow(2, i);
break;
}
}
return inSampleSize;
}
#Override
protected void onPreExecute(){
}
#Override
protected void onProgressUpdate(Void... values){
}
#Override
protected String doInBackground(Object... params) {
try {
InputStream is = ((android.app.Activity) params[1]).getContentResolver().openInputStream((Uri) params[0]);
Bitmap bitmap = decodeSampledBitmapFromStream(is, 300, 300);
int bytes = bitmap.getWidth()*bitmap.getHeight()*4;
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bitmap.copyPixelsToBuffer(buffer);
return Base64.encodeToString(buffer.array(), Base64.DEFAULT);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result){
}
}
The solution was this! Replace the following:
In decodeSampledBitmapFromStream function:
private Bitmap decodeSampledBitmapFromStream(InputStream is,
int reqWidth,
int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream aux = inputStreamCopy(is);
BitmapFactory.decodeStream(aux, null, options); // SkImageDecoder::Factory returned null
try {
aux.reset();
} catch (IOException e) {
e.printStackTrace();
}
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(aux, null, options);
}
And in doInBackground method:
#Override
protected String doInBackground(Object... params) {
try {
InputStream is = ((android.app.Activity) params[1]).getContentResolver().openInputStream((Uri) params[0]);
Bitmap bitmap = decodeSampledBitmapFromStream(is, 300, 300);
System.gc();
int bytes = bitmap.getWidth()*bitmap.getHeight()*2;
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bitmap.copyPixelsToBuffer(buffer);
return Base64.encodeToString(buffer.array(), Base64.DEFAULT);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
:)

Categories

Resources