how to decode byte array to bitmap without OOM Exception - java

I stuck in out of memory. I’m trying to load an image with byte array but what ever i’ve done it wouldn’t work. I get bitmap decoder error I guess. These are all code :
String password = prefs.getString("BookKey", "");
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
buf.read(bytes, 0, bytes.length);
buf.close();
byte[] bytesdecrpy = decrypt(bytes, password);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = true;
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inTempStorage = new byte[32 * 1024];
options.inBitmap = BitmapFactory.decodeByteArray(bytesdecrpy, 0,
bytesdecrpy.length, options);
bm = Bitmap.createBitmap(options.outWidth,
options.outHeight, Bitmap.Config.ARGB_8888);
imageView.setImage(ImageSource.bitmap(bm));
I read as a byte array my encrypt png from device file but i having problem that when i create bitmap for bitmap variable. I still couldn’t run as well for 2 days. If anyone can help me to solve this problem it would be great. Thank you.
EDIT
I've tried only decode my byte array to bitmap like this but problem never changed i've started get problem in decode then
bm = BitmapFactory.decodeByteArray(bytesdecrpy, 0,
bytesdecrpy.length, options);

This can cause OOM Exception if the bitmap is too large
You could use a background thread to decode and load an image in the container
or use a caching technique as explained in https://developer.android.com/training/displaying-bitmaps/index.html

Related

How to compress downloaded images and decompress when needed in Android?

How to compress jpg/bmp files which I can store in the memory then when needed decompress those images and show to users without losing too much of image quality? How to do the compress and decompress, any guidance/ link would be helpful.
Thank you
create image thumbnails
'byte[] imageData = null;
try
{
final int THUMBNAIL_SIZE = 64;
FileInputStream fis = new FileInputStream(fileName);
Bitmap imageBitmap = BitmapFactory.decodeStream(fis);
imageBitmap = Bitmap.createScaledBitmap(imageBitmap, THUMBNAIL_SIZE, THUMBNAIL_SIZE, false);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
imageData = baos.toByteArray();
}
catch(Exception ex) {
}`
if u need for thumbNail then use
ThumbNailUtils.extractThumbnail(Bitmap source,int width,int height)
it show thumbnail from bitmap and when u want to show original bitmap then show bitmap
.
use wisely bitmap object cause it take more memory at runtime.

can't get the url of a image with jsoup

I'm trying to get the url of a range of images like that:
for(Element img : document.select(".left-column .strillo-content .lazy img[src]")) {
InputStream input = new java.net.URL(imageMainUrl).openStream();
Bitmap bitmap = BitmapFactory.decodeStream(input);
images.add(bitmap);
}
but everytime I trying to run my app I get this warning:
java.net.MalformedURLException: Unknown protocol: data
at java.net.URL.<init>(URL.java:184)
at java.net.URL.<init>(URL.java:127)
so I have tried to print the URL and I get this:
data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
and I can figure out why, because I'm 100% sure that the element I select is corrent and also I do the same process with other section of the website and it works..
UPDATE 1:
I have tried this method to decode the ´base64´ image:
byte[] decodedString = Base64.decode(imageMainUrl, Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
but the result is the same..
It's the data URI scheme
http://en.wikipedia.org/wiki/Data_URI_scheme
It allows to add inline data in your URI.
Extract the base64 part of the URI and get a byte array with parseBase64Binary, more information here : http://docs.oracle.com/javase/7/docs/api/javax/xml/bind/DatatypeConverter.html#parseBase64Binary%28java.lang.String%29
Use this array to build a ByteArrayInputStream
Use your BitmapFactory to decode it into a Bitmap
edit
This code works, it give a 1px*1px gif image. I used org.apache.commons.codec.binary.Base64 from commons-codec
String uri = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
byte[] decodedString = Base64.decodeBase64(uri.substring(uri.indexOf("data:image/gif;base64,") + "data:image/gif;base64,".length()));
ByteArrayInputStream is = new ByteArrayInputStream(decodedString);
FileOutputStream os = new FileOutputStream(new File("/tmp/test.gif"));
byte[] buffer = new byte[1024];
int length;
// copy the file content in bytes
while ((length = is.read(buffer)) > 0)
{
os.write(buffer, 0, length);
}
is.close();
os.close();

issue displaying byte array to bitmap to fetch an image in android

I'm having problem converting byte array to bitmap. Now what I'm trying to achieve is I'm getting image as a byte array and trying to convert into bitmap so that I can display the image. but after running my below code in my bitmap output i'm getting Null value.
String t= "byte array of the image";
byte[] temp = t.getBytes() ;
Bitmap bmp = BitmapFactory.decodeByteArray(temp, 0, temp.length);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
System.out.println("bitmap output"+bmp);
I have googled a lot and found this code works for every1. can please someone tell me where I'm doing wrong.
Thanks in advance
In my case this is working
String result = "here imge;
if (result != "") {
byte[] bloc = Base64.decode(result);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap b = BitmapFactory.decodeByteArray(bloc, 0, bloc.length);
Try this way
String t= "byte array of the image";
byte[] temp = Base64.decode(t, Base64.NO_WRAP); //UPDATE HERE
Bitmap bmp = BitmapFactory.decodeByteArray(temp, 0, temp.length);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
System.out.println("bitmap output"+bmp);

Read an Image/file from External storage Android

I'm trying to load an image from external storage. I set the permissions, I tried different ways, but none of them works.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(file.toString());
tv.setImageBitmap(bitmap);
and this one,
FileInputStream streamIn = new FileInputStream(file);
Bitmap bitmap = BitmapFactory.decodeStream(streamIn);
tv.setImageBitmap(bitmap);
streamIn.close();
If i have file abc.jpg on the sdcard then:
String photoPath = Environment.getExternalStorageDirectory() + "/abc.jpg";
and to get bitmap.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(photoPath, options);
or
Bitmap bitmap1 = BitmapFactory.decodeFile(photoPath);
to avoide out of memory error I suggest you use the below code...
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
final Bitmap b = BitmapFactory.decodeFile(photoPath, options);
To avoid above issue you can use Picasso (A powerful image downloading and caching library for Android)
Documentation
How To?
Picasso.with(context).load("file:///android_asset/DvpvklR.png").into(imageView2);
Picasso.with(context).load(new File(...)).into(imageView3);
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard.getAbsolutePath() + "/Pictures");
File file = new File(directory, "image_name.jpg"); //or any other format supported
FileInputStream streamIn = new FileInputStream(file);
Bitmap bitmap = BitmapFactory.decodeStream(streamIn); //This gets the image
streamIn.close();
Get the path of the image from your folder as below. And then decode the file as a bitmap.
File file= new File(android.os.Environment.getExternalStorageDirectory(),"Your folder");
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath())
If you have a file path, just use BitmapFactory directly, but tell it to use a format that preserves alpha:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(photoPath, options);
selected_photo.setImageBitmap(bitmap);
There is a function called
createFromPath(String)
in the Drawable class.
So the statement
String path="/storage/..<just type in the path>";
Drawable.createFromPath(path);
will return a drawable object

encoding and decoding in JPG images in Android

I am creating an application over Android where I need to manipulate my JPG files. I am not getting much of header information for JPG format so for that I am converting it to Bitmap, manipulated the pixel values in bitmap and then again convert it back to JPG.
Here what problem I am facing is- after manipulating only some pixels of bitmap and
converting it back to JPG, I do not get the same set of pixels I got earlier (for those pixels which I did not manipulate). I am getting the same image as the original in the new image. But when I check new image pixels values for decoding, the untouched pixels are different...
File imagefile = new File(filepath);
FileInputStream fis = new FileInputStream(imagefile);
Bitmap bi = BitmapFactory.decodeStream(fis);
int intArray[];
bi=bi.copy(Bitmap.Config.ARGB_8888,true);
intArray = new int[bi.getWidth()*bi.getHeight()];
bi.getPixels(intArray, 0, bi.getWidth(), 0, 0, bi.getWidth(), bi.getHeight());
int newArray[] = encodeImage(msgbytes,intArray,mbytes); // method where i am manipulating my pixel values
// converting the bitmap data back to JPG file
bi = Bitmap.createBitmap(newArray, bi.getWidth(), bi.getHeight(), Bitmap.Config.ARGB_8888);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bi.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();
Bitmap bitmapimage = BitmapFactory.decodeByteArray(data, 0, data.length);
String filepath = "/sdcard/image/new2.jpg";
File imagefile = new File(filepath);
FileOutputStream fos = new FileOutputStream(imagefile);
bitmapimage.compress(CompressFormat.JPEG, 100, fos);
Help me if I am wrong somewhere or whether I should use some other method to manipulate JPG pixel values...
JPEG is an image format that is usually based on lossy compression. That means that some information that is not important for the human eye is thrown away to further shrink the file size. Try to save your image as a PNG (a lossless format).
Be careful with using
Bitmap bi = BitmapFactory.decodeStream(fis);
bi = bi.copy(Bitmap.Config.ARGB_8888, true);
At the point where you have the first bi you may have already lost a lot of information, instead try using BitmapFactory.Options to force 8888 (which is the default too):
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inDither = false;
Bitmap bi = BitmapFactory.decodeStream(fis, options);
If you stay with copy you should still recycle() the one that you throw away.

Categories