很多时候我们从网络上获取图片,但有时图片路径明明正确,却要出错。图片小无所谓,图片大了就出错了。
ImageView imageView = new ImageView(context);
URL url = new URL(\"图片路径\");
URLConnection conn = url.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 10;
originalImage = BitmapFactory.decodeStream(is,null,options);
imageView.setImageBitmap(bitmapWithReflection);
这样问题就可以解决了
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
在使用的过程中,如果网络比较慢的话,则会出现下载不成功的问题。经过google搜索,终于解决了这个问题。
一般我们会用以下的代码:
java代码:
//获取connection,方法略
conn = getURLConnection(url);
is = conn.getInputStream();
//获取Bitmap的引用
Bitmap bitmap = BitmapFactory.decodeStream(is)
但是网络不好的时候获取不了图片,推荐使用以下的方法:
java代码:
//获取长度
int length = (int) conn.getContentLength();
if (length != -1) {
byte[] imgData = new byte[length];
byte[] temp=new byte[512];
int readLen=0;
int destPos=0;
while((readLen=is.read(temp))>0){
System.arraycopy(temp, 0, imgData, destPos, readLen);
destPos+=readLen;
}
bitmap=BitmapFactory.decodeByteArray(imgData, 0, imgData.length);
}
使用上面的方法的好处是在网速不好的情况下也会将图片数据全部下载,然后在进行解码,生成图片对象的引用,所以可以保证只要图片存在都可以下载下来。当然在读取图片数据的时候也可用java.nio.ByteBuffer,这样在读取数据前就不用知道图片数据的长度也就是图片的大小了,避免了有时候 http获取的length不准确,并且不用做数组的copy工作。
java代码:
public synchronized Bitmap getBitMap(Context c, String url) {
URL myFileUrl = null;
Bitmap bitmap = null;
try {
myFileUrl = new URL(url);
} catch (MalformedURLException e) {
bitmap = BitmapFactory.decodeResource(c.getResources(),
com.jixuzou.moko.R.drawable.defaultimg);
return bitmap;
}
try {
HttpURLConnection myFileUrl.openConnection();
conn = (HttpURLConnection)
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
int length = (int) conn.getContentLength();
if (length != -1) {
byte[] imgData = new byte[length];
byte[] temp = new byte[512];
int readLen = 0;
int destPos = 0;
while ((readLen = is.read(temp)) > 0) {
System.arraycopy(temp, 0, imgData, destPos, readLen);
destPos += readLen;
}
bitmap = BitmapFactory.decodeByteArray(imgData, 0,imgData.length);
}
} catch (IOException e) {
bitmap =
BitmapFactory.decodeResource(c.getResources(),com.jixuzou.moko.R.drawable.defaultimg);
return bitmap;
}
return bitmap;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
从网络获取图片,数据为InputStream流对象,然后调用BitmapFactory的decodeStream()方法解码获取图片。代码如下:
private Bitmap getUrlBitmap(String url)
{
Bitmap bm;
try{
URL imageUrl=new URL(url);
HttpURLConnection conn=(HttpURLConnection)imageUrl.openConnection();
conn.connect();
InputStream is=conn.getInputStream();
//byte[] bt=getBytes(is); //注释部分换用另外一种方式解码
//bm=BitmapFactory.decodeByteArray(bt,0,bt.length);
bm=BitmapFactory.decodeStream(is); //如果采用这种解码方式在低版本的API上会出现解码问题
is.close();
conn.disconnect();
return bm;
}
catch(MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
结果在运行时编译器提示: DEBUG/skia(xxx): --- decoder->decode returned false
已经确定从网络获取的数据流没有出现问题,而是在图片解码时出现错误。上网查找了不少资料,也没有得出确切的原因,不过有几条意见值得关注。
一种说法是在android 较低版本的api中会有不少内部的错误,我的代码运行时选择2.1API Level 7和2.2API Level 8都会出现这个问题,而选择2.3 API Level 9后能够正常解码图片。
我的另外一种做法是换用别的解码方式对图片解码,见代码中被注释的那俩行,使用decodeByteArray()方法在低版本的API上也能够正常解码,解决了这个问题。
其中getBytes(InputStream is)是将InputStream对象转换为Byte[]的方法,具体代码如下:
private byte[] getBytes(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int len = 0;
while ((len = is.read(b, 0, 1024)) != -1)
{
baos.write(b, 0, len);
baos.flush();
}
byte[] bytes = baos.toByteArray();
return bytes;
}
private void queuePhoto(String url, Activity activity, ImageView imageView)
002 {
003 // This ImageView may be used for other images before. So there may be
004 // some old tasks in the queue. We need to discard them.
005
006 photosQueue.Clean(imageView);
007 PhotoToLoad p = new PhotoToLoad(url, imageView);
008
009 synchronized (photosQueue.photosToLoad)
010 {
011 photosQueue.photosToLoad.push(p);
012 photosQueue.photosToLoad.notifyAll();
013 }
014
015 // start thread if it's not started yet
016 if (photoLoaderThread.getState() == Thread.State.NEW)
017 photoLoaderThread.start();
018 }
019
020 public Bitmap getBitmap(String url)
021 {
022 try
023 {
024 // I identify images by hashcode. Not a perfect solution, good for the
025 // demo.
026 027 028
029 030 031 032 033
034 035 String filename = String.valueOf(url.hashCode());
File f = new File(cacheDir, filename);
// from SD cache
Bitmap b = decodeFile(f);
if (b != null)
return b;
// from web
try {
036 Bitmap bitmap = null;
037 if(!url.equals(\"\")){
038 InputStream is = new URL(url).openStream();
039 040 041 042 043 044 045 046 047 048 OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
bitmap = decodeFile(f);
}
return bitmap;
}
catch (Exception ex)
{
ex.printStackTrace();
049 return null;
050 }
051 }
052 catch(Exception e)
053 {
054 e.printStackTrace();
055
056 return null;
057 }
058 }
059
060 /*decodes image and scales it to reduce memory consumption
061 * @param file path
062 * @throws FileNotFoundException
063 * @return bitmap
0 * */
065 066 067 068
069 070 071 072 073 074 o);
Bitmap b = null;
try {
useThisBitmap = null;
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
final int IMAGE_MAX_SIZE = 70;
BitmapFactory.decodeStream(new FileInputStream(f), null, private Bitmap decodeFile(File f){
075 int scale = 2;
076 if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
077 scale = 2 ^ (int) Math.ceil(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5));
078 }
079
080 //Decode with inSampleSize
081 BitmapFactory.Options o2 = new BitmapFactory.Options();
082
083 o2.inSampleSize = scale;
084 b = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
085 useThisBitmap = b;
086
087 }
088 catch (FileNotFoundException e) {
0 }
090 091 092 093 094 095 096 097 098 099 }
catch(Exception e)
{
e.printStackTrace();
}
finally
{
System.gc();
}
return useThisBitmap;
100
101
102 // Task for the queue
103 private class PhotoToLoad
104 {
105 public String url;
106 public ImageView imageView;
107
108 public PhotoToLoad(String u, ImageView i) {
109 url = u;
110 imageView = i;
111 }
112 }
113
114 private PhotosQueue photosQueue = new PhotosQueue();
115
116
117
118 // stores list of photos to download
119 private class PhotosQueue
120 {
121 private Stack 122 // removes all instances of this ImageView 123 private void Clean(ImageView image) 124 { 125 for (int j = 0; j < photosToLoad.size();) new = 126 { 127 if (photosToLoad.get(j).imageView == image) 128 photosToLoad.remove(j); 129 else 130 ++j; 131 } 132 } 133 } 134 135 private class PhotosLoader extends Thread 136 { 137 public void run() 138 { 139 try 140 { 141 while (true) 142 143 the 144 145 146 147 148 149 150 151 { // thread waits until there are any images to load in // queue if (photosQueue.photosToLoad.size() == 0) synchronized (photosQueue.photosToLoad) { photosQueue.photosToLoad.wait(); } if (photosQueue.photosToLoad.size() != 0) { PhotoToLoad photoToLoad; synchronized (photosQueue.photosToLoad) { 152 photoToLoad photosQueue.photosToLoad.pop(); = 153 } 154 Bitmap bmp = getBitmap(photoToLoad.url); 155 156 157 158 BitmapDisplayer(bmp, 159 160 photoToLoad.imageView 161 162 163 cache.put(photoToLoad.url, bmp); if (((String) photoToLoad.imageView.getTag()) .equals(photoToLoad.url)) { BitmapDisplayer bd = new photoToLoad.imageView); Activity a = (Activity) .getContext(); a.runOnUiThread(bd); } 1 } 165 if (Thread.interrupted()) 166 break; 167 } 168 } catch (InterruptedException e) { 169 // allow thread to exit 170 } 171 } 172 } 173 174 private PhotosLoader photoLoaderThread = new PhotosLoader(); 175 176 // Used to display bitmap in the UI thread 177 private class BitmapDisplayer implements Runnable 178 { 179 private Bitmap bitmap; 180 private ImageView imageView; 181 182 private BitmapDisplayer(Bitmap b, ImageView i) 183 { 184 bitmap = b; 185 imageView = i; 186 } 187 188 public void run() 1 { 190 if (bitmap != null) 191 imageView.setImageBitmap(bitmap); 192 } 193 } 194 195 public void stopThread() 196 { 197 photoLoaderThread.interrupt(); 198 } 199 200 public void clearCache() 201 { 202 cache.clear(); 203 File[] files = cacheDir.listFiles(); 204 for (File f : files) 205 f.delete(); 206 207 } }
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- huatuo0.cn 版权所有 湘ICP备2023017654号-2
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务