• android笔记--解决SkImageDecoder::Factory returned null


    使用HttpClient方式从网络上下载一张大的图片的Bitmap对象,用ImageView显示出来,运行下面的代码会下面的错误:

    05-10 13:42:57.206: D/skia(2250): --- SkImageDecoder::Factory returned null
    

     代码:

    package com.test.demo;
    
    import java.io.InputStream;
    import java.sql.Date;
    
    import android.content.res.Resources;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Rect;
    import android.util.Log;
    
    public class ImageUtil {
    
    	public static Bitmap decodeSampledBitmapFromResource(Resources res,
    			int resId, int reqWidth, int reqHeight) {
    
    		// First decode with inJustDecodeBounds=true to check dimensions
    		final BitmapFactory.Options options = new BitmapFactory.Options();
    		options.inJustDecodeBounds = true;
    		BitmapFactory.decodeResource(res, resId, options);
    
    		// Calculate inSampleSize
    		options.inSampleSize = calculateInSampleSize(options, reqWidth,
    				reqHeight);
    
    		// Decode bitmap with inSampleSize set
    		options.inJustDecodeBounds = false;
    		return BitmapFactory.decodeResource(res, resId, options);
    	}
    
    	public static Bitmap decodeSampledBitmapFromStream(InputStream is,
    			int reqWidth, int reqHeight, Rect outPadding){
    		
    		final BitmapFactory.Options options = new BitmapFactory.Options();
    		options.inJustDecodeBounds = true;
    		BitmapFactory.decodeStream(is, outPadding, options);
    		
    		options.inSampleSize = calculateInSampleSize(options, reqWidth,
    				reqHeight);
    		options.inJustDecodeBounds = false;
    		Log.i("outPadding", "---------");
    		return BitmapFactory.decodeStream(is, outPadding, options);
    	}
    	
    	public static Bitmap decodeSampledBitmapFromByteArray(byte[]data,
    			int reqWidth, int reqHeight, Rect outPadding){
    		
    		final BitmapFactory.Options options = new BitmapFactory.Options();
    		options.inJustDecodeBounds = true;
    		BitmapFactory.decodeByteArray(data, 0, data.length, options);
    		
    		options.inSampleSize = calculateInSampleSize(options, reqWidth,
    				reqHeight);
    		options.inJustDecodeBounds = false;
    		Log.i("outPadding", "---------");
    		return BitmapFactory.decodeByteArray(data, 0, data.length, options);
    	}
    	
    	
    	public static int calculateInSampleSize(BitmapFactory.Options options,
    			int reqWidth, int reqHeight) {
    		// Raw height and width of image
    		final int height = options.outHeight;
    		final int width = options.outWidth;
    		int inSampleSize = 1;
    
    		if (height > reqHeight || width > reqWidth) {
    
    			final int halfHeight = height / 2;
    			final int halfWidth = width / 2;
    
    			// Calculate the largest inSampleSize value that is a power of 2 and
    			// keeps both
    			// height and width larger than the requested height and width.
    			while ((halfHeight / inSampleSize) > reqHeight
    					&& (halfWidth / inSampleSize) > reqWidth) {
    				inSampleSize *= 2;
    			}
    		}
    
    		return inSampleSize;
    	}
    }
    
    package com.test.demo;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    import org.apache.http.HttpResponse;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.entity.BufferedHttpEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    
    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Matrix;
    import android.graphics.Rect;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.ImageView;
    
    public class LoadbigimageActivity extends Activity {
    
    	private ImageView imageView;
    	private DownloadTask task;
    	private ImageUtil util;
    	private String url = "https://unsplash.imgix.net/photo-1430132594682-16e1185b17c5?fit=crop&fm=jpg&h=700&q=75&w=1050";
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_loadbigimage);
    		imageView = (ImageView) findViewById(R.id.imageView1);
    		util = new ImageUtil();
    
    		task = new DownloadTask();
    		Matrix matrix = imageView.getImageMatrix();
    		Log.i("outPadding", matrix.toString());
    		task.execute(url);
    
    	}
    
    	@Override
    	public boolean onCreateOptionsMenu(Menu menu) {
    		// Inflate the menu; this adds items to the action bar if it is present.
    		getMenuInflater().inflate(R.menu.loadbigimage, menu);
    		return true;
    	}
    
    	@Override
    	public boolean onOptionsItemSelected(MenuItem item) {
    		// Handle action bar item clicks here. The action bar will
    		// automatically handle clicks on the Home/Up button, so long
    		// as you specify a parent activity in AndroidManifest.xml.
    		int id = item.getItemId();
    		if (id == R.id.action_settings) {
    			return true;
    		}
    		return super.onOptionsItemSelected(item);
    	}
    
    	private class DownloadTask extends AsyncTask<String, Void, Bitmap> {
    
    		@Override
    		protected Bitmap doInBackground(String... params) {
    			// TODO Auto-generated method stub
    			Bitmap bitmap = null;
    			HttpClient httpClient = new DefaultHttpClient();
    			HttpGet get = new HttpGet(params[0]);
    			try {
    				HttpResponse response = httpClient.execute(get);
    				if (response.getStatusLine().getStatusCode() == 200) {
    
    					BufferedHttpEntity bufEntity = new BufferedHttpEntity(
    							response.getEntity());
    
    					InputStream inputStream = bufEntity.getContent();
    					Rect outPadding = new Rect();
    					byte[] data = EntityUtils.toByteArray(bufEntity);
    					
    					
    					bitmap = ImageUtil.decodeSampledBitmapFromStream(
    							inputStream, 100, 100, outPadding);
    					
    					
    //					bitmap = ImageUtil.decodeSampledBitmapFromByteArray(data,
    //							100, 100, outPadding);
    
    
    
    					Log.i("outPadding", outPadding.toString());
    				} else {
    					Log.i("outPadding", "network error");
    				}
    
    			} catch (ClientProtocolException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    
    			return bitmap;
    		}
    
    		@Override
    		protected void onPostExecute(Bitmap result) {
    			// TODO Auto-generated method stub
    			super.onPostExecute(result);
    
    			imageView.setImageBitmap(result);
    
    		}
    
    	}
    }
    

    解决方法一:不使用decodeStream,而是使用decodeByteArray方式进行获取Bitmap.

    bitmap = ImageUtil.decodeSampledBitmapFromByteArray(data,100, 100, outPadding);
    

    解决方法二:

    stackverflow相关讨论:

    http://stackoverflow.com/questions/12006785/android-skimagedecoder-factory-returned-null

    按照下面的思路

    I have encountered the same problem. And also I make sure the url is correct to download the image. By debugging the code, I found the variable of position in inputstream was set to 1024 after the first decode. So I add inputstream.reset() before the second decode. That works. Hope can help others.

    修改decodeSampledBitmapFromStream函数,在第一次decodeStream后面调用InputStream的reset(),问题解决。

    修正后代码如下

    	public static Bitmap decodeSampledBitmapFromStream(InputStream is,
    			int reqWidth, int reqHeight, Rect outPadding){
    		
    		final BitmapFactory.Options options = new BitmapFactory.Options();
    		options.inJustDecodeBounds = true;
    		BitmapFactory.decodeStream(is, outPadding, options);
    		try {
    			is.reset();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		options.inSampleSize = calculateInSampleSize(options, reqWidth,
    				reqHeight);
    		options.inJustDecodeBounds = false;
    		Log.i("outPadding", "---------");
    		return BitmapFactory.decodeStream(is, outPadding, options);
    	}
    
  • 相关阅读:
    grub
    init
    内核的ramdisk
    kernel信息及其相关命令
    mvc和mvvm模式
    vue从零开始(一)
    echarts自动播放图形
    echarts自定义悬浮框的显示
    typescript入门
    echarts的最外层配置项
  • 原文地址:https://www.cnblogs.com/xiaozu/p/4492190.html
Copyright © 2020-2023  润新知