将base64 imageString转换为位图以在ImageView中显示,在位图中显示null

时间:2016-03-15 06:43:52

标签: android android-volley

(适用编者)

  • 在浏览器中点击API时,它正在下载图像。该网址为http://example.com/api/v1/filedownloader.json?file=GvygDaYb64wUon0lxp2H1458543376

  • 我更改了服务器名称并将example.com添加到该网址。所以 在浏览器中运行时不会下载图像文件。但是你可以 看图像文件 here

  • 然后我用Encode tool和。检查了文件 Decode tool

  • 解码后,我收到了.bin file。然后我换成了.png format。只有这样我才能得到准确的图像。

  • 我不知道如何使用所有这些功能来获取图像和 在imageView中显示它。

  • 无论如何,我使用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);    
    }        
}

这段代码有什么问题?为什么我在位图中获得null。任何人都可以帮助我。

7 个答案:

答案 0 :(得分:7)

从日志中可以看出

E / myBitmap:null

这意味着您无法解码位图。请参考这个答案

Convert Base64 string to bitmap

还要确保您采取适当的方法取决于您是否正在接收

data:image/jpg;base64
<64>在base64编码的字符串中。 那就是切片部分

data:image/jpg;base64
从字符串

然后使用Base64.DEFAULT

对其进行解码

或 如果你正在切片,请使用Base64.URL_SAFE

修改 更改loadImage

中的以下行
Bitmap myBitmap = BitmapFactory.decodeStream(input);

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);

如果它没有工作,请告诉我encodeImage字符串的值是什么。 还要确保

data:image/jpg;base64

未在回复中传递。

如果您在验证字符串是否为图像时遇到问题,可以使用以下

创建一个简单的html页面
<!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>

替换&#39;&lt;&#; ,&#39;&gt;&#39;在浏览器中使用适当的内容和打开的html页面。 或者,您可以转到this链接并将字符串粘贴到那里。

答案 1 :(得分:5)

您获得了正确的base64编码字符串。只需使用以下代码将该String转换为bitmap

byte[] decodedString = Base64.decode(StrBase64, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); 
imageView1.setImageBitmap(decodedByte);

答案 2 :(得分:4)

您传递给bitMapToString函数的位图为null,因此您收到null对象错误。

bitmap您未得到正确loadImage();    所以进行更改,如

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

通过这种方式,您将获得bitmap

答案 3 :(得分:4)

实际上,Base64字符串有很多字符。您的Base64字符串不正确,将图像上传到this website以获取Base64字符串。请在代码中使用该字符串。

答案 4 :(得分:3)

  

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

这表示BitmapFactory.decode的输入在某种程度上无效。

下面我列出了一些可能会欺骗您的可能情况,但不确定适用哪种情况,因为您没有透露真实的Url,而您发布的代码甚至没有尝试解码来自网络的数据。

Base64 Padding

您的硬编码输入字符串是GvygDaYb64wUon0lxp2H1458543376,它不是有效的Base64编码字符串。要查看为什么在页面上输入它:http://string-functions.com/base64decode.aspx,它会说:

  

Base-64字符数组的长度无效。

将其更改为GvygDaYb64wUon0lxp2H1458543376==(注意结束),它会显示奇怪的字形,但这只是因为它是二进制数据,所以它成功解码。

奇怪的是,Base64类应该在缺少填充时抛出异常,但是你没有得到...

您还可以在Chrome中检查已编码字符串的内容,将其输入到新标签的地址栏中(在逗号后替换,请参阅valid example):

data:image/png;base64,GvygDaYb64wUon0lxp2H1458543376==

我看到一个小方块,可能不是图像(见下一节)。

Base64格式

您尝试解码的样本也是一种奇怪的格式。它不是Android系统支持的PNG / GIF / JPEG文件,它缺少标题。查看支持的格式列表:http://developer.android.com/guide/appendix/media-formats.html(向下滚动到图像),这些是您可以加载的数据类型。

我尝试在我的笔记本电脑上使用多个成像软件加载那个短字节[]并且没有将其识别为图像文件并且我同意它们,我在十六进制编辑器中也看不到任何图像。

Base64 - 不是!

如果您尝试解码变量response,请确保它是Base64编码的字符串。以上日志中的内容是JPEG文件,但它可能已损坏。请注意,您正在使用StringRequest,只有在您真正获得包含[a-zA-Z0-9+/=]个字符的Base64字符串时才能使用。

要读取二进制数据,您需要根据您的网络库激发不同类型的请求,但关键是如果您以String格式接收二进制数据,则意味着应用了一些文本编码它,但二进制数据没有字符编码,它只是普通的0x00-0xFF字节,没有任何解释。

关于二进制数据的

BitmapFactory.decode仅在您从网络库收到byte[]InputStreamReader s还具有关联的文本编码时才有效二进制数据错误)。

答案 5 :(得分:3)

byte[] decodedString = Base64.decode(StrBase64, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); 
imageView1.setImageBitmap(decodedByte);

答案 6 :(得分:0)

这可能会有所帮助,尽管不是直接的。我的情况是我有一个图像处理程序脚本,该脚本通过隐藏图像的位置并在经过严格验证后才呈现其base64编码的字符串来保护图像。然后,我认为这可以在本地html文件的android网络视图中使用,这些html文件具有到本地存储位置的硬编码URL,但是Bitmap Factory一直抱怨空值。我必须使用相同的脚本来保护位置,但没有提供base-64数据,而是在必要的授权后通过此代码(在php服务器端)强制下载了图像:

//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;