Converting base64 imageString to bitmap to display in ImageView showing null in bitmap
Asked Answered
D

7

9

(Edited)

  • While hitting the API in browser, it is downloading the image. The URL is http://example.com/api/v1/filedownloader.json?file=GvygDaYb64wUon0lxp2H1458543376 .

  • I have changed the server name and added example.com to that URL. So it won't download an image file while running in browser. But you can see the image file here.

  • Then I checked the file with Encode tool and Decode tool.

  • After decoding, I am getting .bin file. Then I changed into .png format. Only then can I get the exact image.

  • I don't know how to do all these functionalities to get the image and display it in imageView.

  • Anyhow I tried the code below with this:

Logcat:

03-24 04:29:43.816: E/OnResponse(15392): ÿØÿà��JFIF������������ÿí��Photoshop 3.0��8BIM����������g��9dXpsI_ORS9jWIcxWfWe(��bFBMD01000abe030000070e0000c51a0000161c0000251d0000bc2000007f350000fc370000323a00003f3c0000f4620000ÿâICC_PROFILE������lcms����mntrRGB XYZ Ü��������)��9acspAPPL����������������������������������������������������öÖ����������Ó-lcms����������������������������������������������������������������������������������������������
03-24 04:29:43.816: E/OnResponse(15392): desc������ü������^cprt����\������wtpt����h������bkpt����|������rXYZ����������gXYZ����¤������bXYZ����¸������rTRC����Ì������@gTRC����Ì������@bTRC����Ì������@desc��������������c2��������������������������������������������������������������������������������������������������������������������������������������������������������������������text��������FB����XYZ ������������öÖ����������Ó-XYZ ����������������3����¤XYZ ������������o¢����8õ����XYZ ������������b����·����ÚXYZ ������������$ ��������¶Ïcurv��������������������ËÉckö?Q4!ñ)2;FQw]íkpz±|¬i¿}ÓÃé0ÿÿÿÛ��C��       
03-24 04:29:43.816: E/OnResponse(15392):    

"##!  %*5-%'2(  .?/279<<<$-BFA:F5;<9ÿÛ��C
03-24 04:29:43.816: E/OnResponse(15392): 9& &99999999999999999999999999999999999999999999999999ÿÂ��¸¸��"��ÿÄ����������������������������ÿÄ��������������������������ÿÄ��������������������������ÿÚ����������íÐÙG,!.Ph5ð8ò÷¸¥®ÐàÔ§DUdº
de��kP'.¤ÅS BG  ìóölâvw@+.ÆÖ®©$¸
Ø
03-24 04:29:43.816: E/OnResponse(15392): K¥Yp ³ºXC¹O/)u RÉuEÊ$£³UÂP©hL^ÅÌ ·üûÌ%§ EU-1i6Ss©,ÞÌõ®{·W¹k`¤I!kwt%ÙeP¦*Ôªóï-¿
03-24 04:29:43.816: E/OnResponse(15392):  l"4áá#^-KSIBá¯S¨jYeîÌùucÓq}Lvå^ jÍ [Bz¾·í'nUï#tE  ÂQ(äf)Uw(5ݨG/cUÙÀSAIÓ(´ÌÑY.,±iíÒ«Bଽ^pvf;TAX,KÄEµ XbìÜHqßìx¯Wf    ¬«R\¤.ªªì#IOYçx=ÿ��7+J%g(ªÉM*ÖhÙ­¶ìíZMøعs^²Èó¡fº­(%F¬î\ÓF¥§*ÇÈÉ+«Çu{H륭]G4Q%A]Eñî>±3¦Y:,tÖØ&:×F3Óf]¡9ÖõQ9Zã��ÕZ3¼9zIÖy¶ÓT ÓPֺϫ@eÎv ìô}¿%ên[Tz)h6v¹n­,h°°?ÅfìÓOÇZ1ЮÑCdÖJí³íÁ±ÌN·VcÔpÐèkEÃ`W°+5hg
`Eçg4µãß4VzÆÏ[ã½-x7¨A`ºÊD5Wå®ky{º¬ZùöeÔÏG¶Br    VD&´³·
&µçY׬fLDLEP²¬X°2®æ¹\{Æ|°o{¾¦®w* Kªj2ÖåÉâ��nkv¼yöÐC3·±MÎWÆ%ÈmÞ  e��æÌè*ÍsgJSWPØ+bn]@0×<¸7cßnçé³Ü߸pª(©AÕÂÖV*ϯNlë^¬:ùõÝjfz½©vuwV4nvFåf°ÒT±0&§c,³ Yv#tUH\%Ø\ÚÇ6¹-úr[n}ÃêÈÊ`J¡£!  t¬ªÍ£<7VMXë³Fmú¹«vwED¥pÐlÌ6k!m+[lI@2Ò¬êÂhFè© jl%\Gfß Ìäï¿>o!jJ²Ìn¡,®XJg"<ÊH!»±ô±ÔÞ¶c¦¥ÙÝÚÙ  `HwW¨Â]¡Â;R´eZ¦Í.¡T`-MSs3ståS|˧ØY¢VÛ1ÌA^¶"­¹Id"¹¹=,»ùÄô0o¾=©7¥ù¦u¶ò:WÚa..ÊAÙ F®tXhÐåJB#)Â1bj±jhÙÍÍÒæôåV,×-^ãÃûPúuë9rj#D^®4WFªêÞ_sÇÓÈáú(?¥r2³¡'äa¥y]yÖfúRàîèGf´¦vuóñCYë³Gj¹$t&
03-24 04:29:43.816: E/OnResponse(15392): ftK4]Oc¾yØ;u^ØÎûÀ!×ÎÖZ±yVµv    ÐÙËò¿/.ÃÇìr±Ó6ìÚõdÌél0MU±:æ3¤¼æµ¸é[qêÍ}´õà\ÈÚÍg³å^{0½*ÃÓÎò£¨Äàb«Óæëë/£¬Îo|½æîV{ðUµr®1É.¥Ü.
¥!ù±ÐyÝNo>ØõfÔ\ãuvc=C¨².¥H:M$º$£\é:·
dt(ÓZÆP×ró¬³P-P¥µR¯ü]9wØÕóínnÿ��+£æùç
pçRv¢E¢òêNw1j>]¸ë65.çլ첢² 1ì0aÝÉVrÀ¦] j¬eµpïÍeä×]9vW&;§ÑùßAßÆéɽc®|n Ù!æYbÔ£¢èLVwñïËÍÕâGUÙuã©°hC-eEg~u
03-24 04:29:43.816: E/OnResponse(15392):  MnK9Û0ìW¥Îzr¥º.êVÅBrjǬKOx%³*·µÍßÛÍììòúÉrCÍBcAXrÅ1Þ;Óçã¦Xusé jLS[uXïFuJf¡«²Ãôb|t3µ¶¢£(XÂÐùwË£ÒÌÖ¢#:qê^o·T��ä%gÈ`*WQlJ N×EÌéx®4»õáÓÃÓ±n6f6


03-24 04:29:43.816: D/skia(15392): --- SkImageDecoder::Factory returned null

03-24 04:29:43.816: E/myBitmap(15392): null

03-24 04:29:43.816: D/AndroidRuntime(15392): Shutting down VM
03-24 04:29:43.817: E/AndroidRuntime(15392): FATAL EXCEPTION: main
03-24 04:29:43.817: E/AndroidRuntime(15392): Process: com.steve.test, PID: 15392
03-24 04:29:43.817: E/AndroidRuntime(15392): java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
03-24 04:29:43.817: E/AndroidRuntime(15392):    at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:596)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at com.steve.test.SecondActivity$1.onResponse(SecondActivity.java:121)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at com.steve.test.SecondActivity$1.onResponse(SecondActivity.java:1)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:1)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at android.os.Handler.handleCallback(Handler.java:739)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at android.os.Handler.dispatchMessage(Handler.java:95)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at android.os.Looper.loop(Looper.java:135)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at android.app.ActivityThread.main(ActivityThread.java:5221)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at java.lang.reflect.Method.invoke(Native Method)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at java.lang.reflect.Method.invoke(Method.java:372)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
03-24 04:29:43.817: E/AndroidRuntime(15392):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

SecondActivity.java:

 public class SecondActivity extends AppCompatActivity {


    String base64String;
    Bitmap bitmap;
    ImageView img ;

     String userValidationURL, base64;
     byte[] data;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_activity);

        img = (ImageView)findViewById(R.id.imageView);

        base64String = "GvygDaYb64wUon0lxp2H1458543376";

        userValidationURL = "http://example.com/api/v1/filedownloader.json?file=GvygDaYb64wUon0lxp2H1458543376"; 

       hitSearchApi(); 
    }

    private void hitSearchApi(){

            Log.e("userValidationUrl", userValidationURL);

            StringRequest request = new StringRequest(Request.Method.GET, userValidationURL, new Response.Listener<String>() {

                @Override
                public void onResponse(String response) {
                    if(response != null && !response.startsWith("<HTML>")){
                        Log.e("OnResponse", response);                                               

                    byte[] decodedString = Base64.decode("GvygDaYb64wUon0lxp2H1458543376", Base64.DEFAULT);
                    Bitmap myBitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);

                    Log.e("mybitmap", ""+myBitmap);
                                            img.setImageBitmap(Bitmap.createScaledBitmap(myBitmap, img.getWidth(), img.getHeight(), false));

                        dialog.dismiss();

                    }else{

                        Log.e("onResponseElse", "onResponseElse");

                        dialog.dismiss();
                    }
                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    if(error != null){
                        Log.e("error", error.toString());
                        dialog.dismiss();
                    }

                }
            }){
                @Override
                protected Map<String,String> getParams(){
                    Map<String,String> params = new HashMap<String, String>();

                    params.put("file", base64String);

                    Log.e("paramsImg", ""+params);

                    return params;
                }

                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    Map<String,String> params = new HashMap<String, String>();
                    params.put("Content-Type","application/x-www-form-urlencoded");
                    return params;
                }
            };
        RequestQueue queue = Volley.newRequestQueue(SecondActivity.this);
        queue.add(request);
        queue.getCache().remove(userValidationURL);    
    }        
}

What is wrong with this code? Why I am getting null in bitmap. Anyone can help me with this.

Disremember answered 15/3, 2016 at 6:43 Comment(16)
I need to convert that file id to http image format. No. You have to use it as url parameter to request a file from a webserver. But you are doing nothing with the received data. And you are trying to make a bitmap from your file id instead of from the data received from the webserver.Forehead
@Forehead Thank you for your suggestion.I am not sure What I have to do with that.Let me try that one and tell you laterDisremember
@Forehead is there any sample for that.So far I think with the help of file id from server response,I have to download the image and use it in my app.Disremember
Of course. There are many examples of uploading an image base64 encoded. Or downloading an image base64 encoded. And then displaying or saving the result. All on this site. So search a little. And if you read twenty pages (50 threads) with tag 'android' you will find them already.Forehead
your bitmap code looks fine, I suspect its a problem at the input stream, maybe set a log and capture the value of input (your InputStream)?Thorough
Looks like the exception happened with CardsFragment.java, not MainActivity.java. Moreover, please post loadImage(...) inside CardsFragment.java if available. One more thing, I guess loadImage inside MainActivity.java not called because it will throw NetworkOnMainThreadException if calledMarsupium
@Marsupium Sorry I forget to change CardsFragment.java.That is cardsfragment.java not mainActivity.javaDisremember
@ScottishUser I have printed input logDisremember
can you post a dummy input streamSimms
@war_Hero Input Strean Log : E/input: buffer(com.android.okhttp.internal.http.HttpConnection$FixedLengthSource@dc71d13).inputStream()Disremember
I don't understand what you are trying to achieve: you receive a base64 image string and trying to convert it to Bitmap right? In this case the two line solution here should work assuming the string DON'T start with data:image/jpg;base64,. In fact I don't see why you convert directly the InputStream of the connection to bitmap as it's a String?Tore
@HugoGresse base64Image is a StringDisremember
@Naruto that didn't help muchn can you clarify the flow plz?Tore
Sorry Naruto what I mean is set a log right after you create your InputStream capturing the actual state of input i.e. Log.d(TAG, String.valueOf(input));Thorough
@ScottishUser I have added Log : E/input: buffer(com.android.okhttp.internal.http.HttpConnection$FixedLengthSource@dc71d13‌​).inputStream()Disremember
looks like decodeStream has a issue with your input stream and as a result is returning null. Have you looked at this thread: #5940987Thorough
G
3

03-24 04:29:43.816: D/skia(15392): --- SkImageDecoder::Factory returned null

This signals that the input to BitmapFactory.decode was invalid in some way.

Below I list a few possible scenarios that may trick you, not sure which one applies though, because you didn't disclose the real Url, and the code you posted doesn't even try to decode data coming from the network.

Base64 Padding

Your hardcoded input string is GvygDaYb64wUon0lxp2H1458543376 which is not a valid Base64 encoded string. To see why enter it on the page: http://string-functions.com/base64decode.aspx, it'll say:

Invalid length for a Base-64 char array.

Change it to GvygDaYb64wUon0lxp2H1458543376== (notice the end) and it'll show you weird glyphs, but that's just because it's binary data, so it successfully decoded.

Weirdly the Base64 class should throw an exception when padding is missing, which you didn't get...

You can also check the contents of an encoded string in the Chrome, enter this into the address-bar of a new tab (replace after comma, see valid example):

data:image/png;base64,GvygDaYb64wUon0lxp2H1458543376==

I see a little square, which is likely not the image (see next section).

Base64 Format

That sample you're trying to decode is also in some weird format. It's not a PNG/GIF/JPEG file which is supported by the Android system, it's missing a header. Take a look at the list of supported formats: http://developer.android.com/guide/appendix/media-formats.html (scroll down to Images), these are the data types you'll be able to load.

I tried loading the that short byte[] with multiple imaging software on my laptop and nothing recognized it as an image file and I agree with them, I can't see any image-like in it in a hex editor either.

Base64 - Not!

If you're trying to decode the variable response make sure it's a Base64 encoded string. What is in the logs above is a JPEG file, but it's probably broken. Notice that you're using StringRequest, that will only work if you're really getting a Base64 string which consists of [a-zA-Z0-9+/=] characters.

To read binary data you'll need to fire a different type of request which is different based on your networking library, but the key point is that if you receive binary data in String format that means there was some text encoding applied to it, but binary data doesn't have character encoding, it's just plain 0x00-0xFF bytes without any interpretation.

BitmapFactory.decode on binary data will only work if you're receiving a byte[] from the network library or an InputStream (Readers also have text encoding associated which is wrong for binary data).

Gober answered 28/3, 2016 at 22:58 Comment(0)
E
7

As you can see from the logs that

E/myBitmap: null

This means you are not able decode bitmap. Please refer this answer

Convert Base64 string to bitmap

Also make sure that you are taking appropriate approach depending upon whether or not you are receiving

data:image/jpg;base64

in the base64 encoded string. That is either slice the part

data:image/jpg;base64

from the string then decode it using Base64.DEFAULT

or alternatively use Base64.URL_SAFE if you are slicing it out.

Edit: Change the following line in loadImage

Bitmap myBitmap = BitmapFactory.decodeStream(input);

to

BufferedReader in = new BufferedReader(new InputStreamReader(input));
String inputLine;
StringBuffer response = new StringBuffer();

while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();

String encodedImage = response.toString();
byte[] decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
Bitmap myBitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);

Also if it doesn't work let me know what the value of encodedImage string is. Also make sure that

data:image/jpg;base64

is not being passed in the response.

If you are having problem verifying whether the string is image you can create a simple html page with following

<!DOCTYPE html>
<html>
<head>
    <title>Base 64 Sample</title>
</head>
<body>

<img src="data:image/< png/jpeg/gif etc goes here >;base64,< image content goes here>">

</body>
</html>

replace content within '<' , '>' with appropriate content and open html page in browser. Alternatively you can head over to this link and paste the string there.

Epicenter answered 23/3, 2016 at 6:41 Comment(8)
I had tried that SO Answer already.But it is not working for me;Disremember
I have edited the code, also note that making a request to example.com/api/v1/file=JpSCOmBcI1Fi09zq24Dt1445694203 is not giving a image in Base64 string format. It returns a html page.Epicenter
example means I removed that sever nameDisremember
Okay. Then try the above code if you still get null please let me know the value of encodedImageEpicenter
I haven't put the log in there. Did you put log statement ? or even after putting log statement nothing was printedEpicenter
I put Log.e("encodedImage", ""+encodedImage); But I can't get any result in log.I checked many times.Disremember
it is not entering into while loop.I had checked just now.that's why it is not printing encodedImage valueDisremember
That means you are not getting the response from the server, check the connection code or the request you are trying to makeEpicenter
A
5

You are getting correct base64 encoded String. Just convert that String into bitmap using following code:

byte[] decodedString = Base64.decode(StrBase64, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); 
imageView1.setImageBitmap(decodedByte);
Arise answered 24/3, 2016 at 6:41 Comment(0)
A
4

Bitmap that you are passing to bitMapToString function is null so you are getting null object error.

You are not getting correct bitmap in loadImage(); so make changes like

InputStream input = connection.getInputStream();
BufferedInputStream bufferedInputStream = new BufferedInputStream(input);
Bitmap myBitmap = BitmapFactory.decodeStream(input);

In this way you will get bitmap

Arise answered 24/3, 2016 at 6:54 Comment(0)
P
4

Actually, a Base64 string has so many characters. Your Base64 string is not correct, upload the image to this website to get the Base64 string. Use that string in your code instead.

Plastic answered 24/3, 2016 at 14:36 Comment(0)
G
3

03-24 04:29:43.816: D/skia(15392): --- SkImageDecoder::Factory returned null

This signals that the input to BitmapFactory.decode was invalid in some way.

Below I list a few possible scenarios that may trick you, not sure which one applies though, because you didn't disclose the real Url, and the code you posted doesn't even try to decode data coming from the network.

Base64 Padding

Your hardcoded input string is GvygDaYb64wUon0lxp2H1458543376 which is not a valid Base64 encoded string. To see why enter it on the page: http://string-functions.com/base64decode.aspx, it'll say:

Invalid length for a Base-64 char array.

Change it to GvygDaYb64wUon0lxp2H1458543376== (notice the end) and it'll show you weird glyphs, but that's just because it's binary data, so it successfully decoded.

Weirdly the Base64 class should throw an exception when padding is missing, which you didn't get...

You can also check the contents of an encoded string in the Chrome, enter this into the address-bar of a new tab (replace after comma, see valid example):

data:image/png;base64,GvygDaYb64wUon0lxp2H1458543376==

I see a little square, which is likely not the image (see next section).

Base64 Format

That sample you're trying to decode is also in some weird format. It's not a PNG/GIF/JPEG file which is supported by the Android system, it's missing a header. Take a look at the list of supported formats: http://developer.android.com/guide/appendix/media-formats.html (scroll down to Images), these are the data types you'll be able to load.

I tried loading the that short byte[] with multiple imaging software on my laptop and nothing recognized it as an image file and I agree with them, I can't see any image-like in it in a hex editor either.

Base64 - Not!

If you're trying to decode the variable response make sure it's a Base64 encoded string. What is in the logs above is a JPEG file, but it's probably broken. Notice that you're using StringRequest, that will only work if you're really getting a Base64 string which consists of [a-zA-Z0-9+/=] characters.

To read binary data you'll need to fire a different type of request which is different based on your networking library, but the key point is that if you receive binary data in String format that means there was some text encoding applied to it, but binary data doesn't have character encoding, it's just plain 0x00-0xFF bytes without any interpretation.

BitmapFactory.decode on binary data will only work if you're receiving a byte[] from the network library or an InputStream (Readers also have text encoding associated which is wrong for binary data).

Gober answered 28/3, 2016 at 22:58 Comment(0)
U
3
byte[] decodedString = Base64.decode(StrBase64, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); 
imageView1.setImageBitmap(decodedByte);
User answered 29/3, 2016 at 5:2 Comment(0)
V
0

This may help, albeit not directly. My situation was that I had an image handler script which secured images by hiding their location and only rendering their base64-encoded strings after strict validations. Then I thought this could work with an android web-view on local html files with hardcoded URLs to local storage location but Bitmap Factory kept on complaining of null values. I had to secure the location by same script but instead of delivering base-64 data, I forced the image download via this code (at php server side) after necessary authorizations:

//url construction with creds from android – using normal download stream – app side (download class must be created) 
String targetURL = "https://www.example.com/images.php?download&xuname="+uname+"&xuagent="+useragent+"&xaccn="+ xaccn;

//grab vital details and validate the call – server side
if(isset($_GET['uname'])){      
    $uname = $_GET['xuname'];   //---- normal cleaning may apply
    //...
    //...
    //... authorization engines 
}else {
    //handle this with may be generic image 
}   
//if fine, now force the normal download of the file – normal input / output streams will understand it 
$filepath = "$path/$imagename";     //--- actual file location with name 
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
flush(); // Flush system output buffer
readfile($filepath);
exit;
Vellavelleity answered 19/12, 2019 at 15:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.