I have an image in the S3 server stored with the .bmp extension and retrieve the object with a call to getObject(). I then instantiate an InputStream with a call to getObjectContent(). I'm trying to create a bitmap object by passing the inputStream to BitmapFactory's decodeStream() method. As stated in the docs, it is returning null (instead of a Bitmap) presumably because the inputStream "cannot be used to decode a bitmap". Any ideas on why this is happening? Alternatively, ideas on other ways to download a photo from S3 would be greatly appreciated. Thanks so much!
GetObjectRequest getPhoto = new GetObjectRequest(MainActivity.USERS_BUCKET_NAME, finalList.get(i));
S3Object photoObject = s3.getObject(getPhoto);
InputStream inputStream = photoObject.getObjectContent();
//process inputStream
Bitmap bmp = BitmapFactory.decodeStream(inputStream); //this is returning null
//close inputStream
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
I fixed the problem by using the Apache Commons IOUtils library - I converted the inputstream into a byte array with IOUtils.toByteArray(inputStream) and passed that into BitmapFactory.decodeByteArray(); it no longer returns null.
Related
Context
I believe I have searched enough about this topic but haven't found an answer yet. If any of you have any answer please help out.
I am trying to send an image as an output to a service call from an android app.
I have used BufferedImage, ImageIO and a ByteArrayOutputStream to convert the image to a Base64 encoded string (from many of the examples I could find on stackoverflow).
This Base64 encoded string is received by the android app. Now, this needs to be converted back to an image and shown on an activity.
FYI. The image I am trying to send over is a QR code generated using zxing libraries.
Problem
This is where I am struggling. I am not sure how to do it. I haven't posted any sample code, since the server side code is pretty self explanatory and I don't yet have any code on the server side.
Sample code on the Android side
private Bitmap getBitmap() {
String base64String="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";
ByteArrayInputStream imageArr=new ByteArrayInputStream(Base64.decode(base64String, Base64.DEFAULT));
Bitmap bitmap = BitmapFactory.decodeStream(imageArr);
return bitmap;
}
#haraldK, thanks for giving me the right pointer. I was also wondering why I didn't see any padding, but didn't put enough focus on it to understand the issue. But, based on your hint, I finally figured out the issue. The issue was that I was not closing the OutputStream given by Base64 Encoder properly. In my code I had a the Base64 encoder stream as a wrapper of a ByteArrayOutputStream as below:
final ByteArrayOutputStream os = new ByteArrayOutputStream();
String qString = "";
try {
MatrixToImageWriter.writeToStream(matrix, formatName, Base64.getEncoder().wrap(os));
qString = os.toString("UTF-8");
os.close();
return qString;
} catch (final IOException ioe) {
throw new UncheckedIOException(ioe);
}
In the above code, I was closing the ByteArrayOutputStream using os.close() which was not required. But what was required was closing of the OutputStream given out by the Base64 encoder. I changed the code as below to make it work:
final ByteArrayOutputStream os = new ByteArrayOutputStream();
OutputStream base64Stream = Base64.getEncoder().wrap(os);
String qString = "";
try {
MatrixToImageWriter.writeToStream(matrix, formatName, base64Stream);
base64Stream.close();
qString = os.toString("UTF-8");
os.close();
return qString;
} catch (final IOException ioe) {
throw new UncheckedIOException(ioe);
}
After the above change, the base64 encoded strings are properly padded and are properly getting decoded on the Android side. On the android side this is code I have to display the image:
byte[] imageArr=Base64.decode(base64String.getBytes(), Base64.NO_WRAP);
Bitmap bitmap=BitmapFactory.decodeByteArray(imageArr, 0, imageArr.length);
return bitmap;
I didn't know how to upvote your answer, so I have created this as a separate answer. Thanks for your help.
Can you please add your image Response string
As you are doing it in ByteArrayOutputStream you may missed the below item before decoding
String imageDataBytes = responseImageData.substring(responseImageData.indexOf(",")+1);
InputStream stream = new ByteArrayInputStream(Base64.decode(imageDataBytes.getBytes(), Base64.DEFAULT));
Bitmap bitmap = BitmapFactory.decodeStream(stream);
A good answer available for the same question here
I'm trying to convert String into Bitmap object to put it then on ImageView. String value is downloaded from web and is not null. Actually it is a jpeg file which I can download and open via browser.
I tried to use BitmapFactory.decodeByteArray method but got --- SkImageDecoder::Factory returned null message.
try{
byte[] encodeByte = encodedString.getBytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
return bitmap;
} catch(Exception e){
e.printStackTrace();
return null;
}
encodedString is actually a string I downloaded before:
...
HttpEntity resEntity = response.getEntity();
String encodedString = EntityUtils.toString(resEntity);
...
As mentioned in comments, when converting binary data to a string, it changes the data (to valid characgers, goes through encoding) at EntityUtils.toString(resEntity)
Thanks to #yoah
Changed code to
byte[] img = EntityUtils.toByteArray(resEntity);
and then passed this byte array into BitmapFactory
Bitmap bitmap = BitmapFactory.decodeByteArray(img, 0, img.length);
Image displays correctly.
So, the conclusion is that is better to operate with byte array than with accessory String.
i have 2 applications. One application act as server and it is created in java and sends continuously screen shot of desktop by using the following code.
public void screenCap() throws IOException, AWTException{
Rectangle captureSize = new Rectangle(lastXpos, lastYpos, 500, 500);
img = robot.createScreenCapture(captureSize);
Robot robot=new Robot();
OutputStream os = null;
BufferedImage image = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
ImageIO.write(image, "jpg", os);
}
The second application is Android application acts a client application and has to read continuously the above image stream from inputstream.
Could please help me to read the images from inputstream in the client application.
Use Bitmap decodeStream() method of BitmapFactory Class.
public static Bitmap decodeStream (InputStream is)
Since: API Level 1
Decode an input stream into a bitmap. If the input stream is null, or cannot be used to decode a bitmap, the function returns null. The stream's position will be where ever it was after the encoded data was read.
Example:
String urlOfBitmap = ""; // Url of inputstream
Bitmap bitmap = null;
try {
InputStream in = new java.net.URL(urlOfBitmap).openStream();
bitmap = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
FileInputStream in;
in = ...;
bitmap = BitmapFactory.decodeStream(in);
My final year project requires me to develop a mobile application which fetches a number of Json values from a server. This is my first experience in android development but sure learned something’s and enjoyed the experience.
I have managed to develop the following.
1-a json parser class which fetches the value.
2-a class which displays these values.
3-a database where I store the json response.
However I'm one step away from completing my project, I cannot display the response string image address as real images (shame on me).
I need to do the following.
1- Parse the string path of the image and display the response as image.
I have spent most of my time trying to find the solution on the web, stack overflow. But no luck so far.
I need to do something like this in order to display these images together with the text descriptions.
I have now reached the cross roads and my knowledge has been tested.Is what i'm trying to do here posible?.
Who can show me the way? ,to this outstanding platform.
if you have the image url as a string, you can load and save the image using something like this:
try {
Bitmap bitmap = null;
File f = new File(filename);
InputStream inputStream = new URL(url).openStream();
OutputStream outputStream = new FileOutputStream(f);
int readlen;
byte[] buf = new byte[1024];
while ((readlen = inputStream.read(buf)) > 0)
outputStream.write(buf, 0, readlen);
outputStream.close();
inputStream.close();
bitmap = BitmapFactory.decodeFile(filename);
return bitmap;
} catch (Exception e) {
return null;
}
For saving, make sure you have appropriate permissions if you're going to save to sdcard.
if you just want to load the image (without saving):
Bitmap bm = null;
try {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
Log.e(TAG, "Error getting bitmap", e);
}
return bm;
Just make sure you fetch the image in a separate thread or using AsyncTask or else you'll get ANRs!
you can try this ImageDownloader class from google. It´s works nice :)
Is an AsynkTask that handle the download and set the bitmap to an ImageView.
ImageDownloader
Usage:
private final ImageDownloader mDownload = new ImageDownloader();
mDownload.download("URL", imageView);
I have kept my images in assets folder and tried to display them. I tried in many ways but still I am unable to display the image. In logcat it is not displaying any error.
Please help me regarding this..........
AssetManager mngr = mContext.getResources().getAssets();
is = mngr.open("test3.png");
bitmap = BitmapFactory.decodeStream(is);
Uri uriSavedImage=Uri.fromFile(pictures_directory);
((ImageView) view.findViewById(R.id.imageView1)).setImageBitmap(bitmap);
You can use AssetManager to get the InputStream using its open() method and then use decodeStream() method of BitmapFactory to get the Bitmap.
private Bitmap getBitmapFromAsset(String strName)
{
AssetManager assetManager = getAssets();
InputStream istr = null;
try {
istr = assetManager.open(strName);
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(istr);
return bitmap;
}
Something isn't right here, what error are you getting? Because the error in you question wouldn't come up from that code below... if anything it would say "Unable to open content: file:///testing/test3.png."
It sound like your images are stored in the wrong place and that is why it's saying it can't find them.