【问题标题】:Converting base64 imageString to bitmap to display in ImageView showing null in bitmap将 base64 imageString 转换为位图以在 ImageView 中显示,在位图中显示为空
【发布时间】:2016-03-15 06:43:52
【问题描述】:

(已编辑)

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

  • 我已更改服务器名称并将example.com 添加到该 URL。所以 它在浏览器中运行时不会下载图像文件。但是你可以 看图片文件 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。任何人都可以帮助我。

【问题讨论】:

  • I need to convert that file id to http image format。不可以。您必须将其用作 url 参数才能从网络服务器请求文件。但是你对接收到的数据什么也不做。您正在尝试从您的文件 id 而不是从网络服务器接收到的数据制作位图。
  • @greenapps 谢谢你的建议。我不知道我有什么用。让我试试那个,稍后告诉你
  • @greenapps 是否有任何示例。到目前为止,我认为在服务器响应中的文件 ID 的帮助下,我必须下载图像并在我的应用程序中使用它。
  • 当然。上传图片 base64 编码的例子很多。或下载经过 base64 编码的图像。然后显示或保存结果。都在这个网站上。所以稍微搜索一下。如果你阅读了 20 页(50 个线程)带有“android”标签的文章,你就会发现它们了。
  • 您的位图代码看起来不错,我怀疑是输入流的问题,也许设置了一个日志并捕获输入的值(您的 InputStream)?

标签: android android-volley


【解决方案1】:

从日志中可以看出

E/myBitmap: null

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

Convert Base64 string to bitmap

还要确保您采取适当的方法,具体取决于您是否收到

data:image/jpg;base64

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

另外,如果它不起作用,请告诉我编码图像字符串的值是什么。 还要确保

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>

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

【讨论】:

  • 我已经尝试过这样的答案。但它对我不起作用;
  • 我已经编辑了代码,还请注意,向example.com/api/v1/file=JpSCOmBcI1Fi09zq24Dt1445694203 发出请求不会提供 Base64 字符串格式的图像。它返回一个 html 页面。
  • 示例意味着我删除了该服务器名称
  • 好的。然后尝试上面的代码,如果你仍然得到 null 请让我知道 encodeImage 的值
  • 我没有把日志放在那里。你放了log语句吗?甚至在放置日志语句之后也没有打印任何内容
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    您在loadImage(); 中没有得到正确的bitmap 所以做出改变

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

    这样你会得到bitmap

    【讨论】:

      【解决方案4】:

      实际上,一个 Base64 字符串有很多字符。你的Base64字符串不正确,上传图片到this website获取Base64字符串。在您的代码中使用该字符串。

      【讨论】:

        【解决方案5】:

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

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

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

        Base64 填充

        您的硬编码输入字符串是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 字符串时才会起作用。

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

        二进制数据上的BitmapFactory.decode 仅在您从网络库接收byte[]InputStream 时才有效(Readers 也有关联的文本编码,这对于二进制数据是错误的)。

        【讨论】:

          【解决方案6】:
          byte[] decodedString = Base64.decode(StrBase64, Base64.DEFAULT);
          Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); 
          imageView1.setImageBitmap(decodedByte);
          

          【讨论】:

            【解决方案7】:

            这可能会有所帮助,尽管不是直接的。我的情况是我有一个图像处理程序脚本,它通过隐藏图像的位置并仅在严格验证后渲染它们的 base64 编码字符串来保护图像。然后我认为这可以与本地 html 文件上的 android web 视图一起使用,该文件具有到本地存储位置的硬编码 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;
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-05-11
              • 1970-01-01
              • 2012-07-01
              • 2014-03-28
              • 2011-02-17
              • 2016-05-24
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多