Android Bitmap转换WebPng图片导致损坏的分析及解决方案
出现问题的code!!!
1 private void saveImage(String uri, String savePath) throws IOException { 2 3 // 创建连接 4 HttpURLConnection conn = createConnection(uri); 5 6 // 拿到输入流,此流即是图片资源本身 7 InputStream imputStream = conn.getInputStream(); 8 9 // 指使Bitmap通过流获取数据 10 Bitmap bitmap = BitmapFactory.decodeStream(imputStream); 11 12 File file = new File(savePath); 13 14 OutputStream out = new BufferedOutputStream(new FileOutputStream(file.getCanonicalPath()), BUFFER_SIZE); 15 16 // 指使Bitmap以相应的格式,将当前Bitmap中的图片数据保存到文件 17 if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)) { 18 out.flush(); 19 out.close(); 20 } 21 }
上述代码的原理就是读取网络上一张图片,先使用google API转换成bitmap,然后在转换成png到本地。
一般情况下这个方法是没有任何问题的,但是有时候在一些手机上表现却是不辣么乐观,表现为图片黑边,或者说是显示的不完整,再者说就是丢失数据!!!
这个问题的根本凶手就是底层rom算法的问题,不需要自己过多的考虑,由于咱们不可能要求手机厂商为咱们修改什么,在这说厂商修改了这个问题,用户也不一定能更新到,所以这样的问题还是需要想办法去克服,去修改!!!
这里直接上代码,修改code如下:
1 private void saveImage(String uri, String savePath) throws IOException { 2 3 // 创建连接 4 HttpURLConnection conn = createConnection(uri); 5 6 // 拿到输入流,此流即是图片资源本身 7 InputStream imputStream = conn.getInputStream(); 8 9 // 将所有InputStream写到byte数组当中 10 byte[] targetData = null; 11 byte[] bytePart = new byte[4096]; 12 while (true) { 13 int readLength = imputStream.read(bytePart); 14 if (readLength == -1) { 15 break; 16 } else { 17 byte[] temp = new byte[readLength + (targetData == null ? 0 : targetData.length)]; 18 if (targetData != null) { 19 System.arraycopy(targetData, 0, temp, 0, targetData.length); 20 System.arraycopy(bytePart, 0, temp, targetData.length, readLength); 21 } else { 22 System.arraycopy(bytePart, 0, temp, 0, readLength); 23 } 24 targetData = temp; 25 } 26 } 27 28 // 指使Bitmap通过byte数组获取数据 29 Bitmap bitmap = BitmapFactory.decodeByteArray(targetData, 0, targetData.length); 30 31 File file = new File(savePath); 32 33 OutputStream out = new BufferedOutputStream(new FileOutputStream(file.getCanonicalPath()), BUFFER_SIZE); 34 35 // 指使Bitmap以相应的格式,将当前Bitmap中的图片数据保存到文件 36 if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)) { 37 out.flush(); 38 out.close(); 39 } 40 }
哈哈 其实大家看到这个code 484就笑了,换汤不换药啊,这里直接就是换了个API,稍微不同的是这里传入了byteArray!!!不管咋地这个解法暂时还没遇到上述问题!!!
对了,我在看这个关于图片显示不完整的问题的时候,了解的一点小知识点吧算是给大家分享下,大家可以随便找个.png图片看下他的HEX(十六进制),png图片都是以IHDR开头,以IEND结尾的,不然的是无法显示的,上述问题黑边的但是能显示只是中间的一些像素丢失了。So END !!!