android 加载大图或者长图时会遇到失真或者不显示的问题(imageloader 一般会失真,fresco一般不会显示)。

1、首先说一下为什么会出现这样的情况。

Canvas在绘制Bitmap的时候其实对Bitmap的长宽是有限制的,一般是2048或者是4096.这个值可以通过下面代码获取

int[] maxTextureSize = new int[1];GLES10.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);int maxBitmapDimension = Math.max(maxTextureSize[0], 2048);

maxBitmapDimension 就是Canvas 可以绘制Bitmap的最大宽高。Imageloader 在加载图片时对Bitmap 宽高做了限制,加载的图片都在这个值以内。比如你要加载的图片高度为8000,而你的手机的Canvas 可绘制图片高度最大值为4096,imageloader经过处理之后加载的图片高度其实是2000,比原始图片缩小了四倍,所以看起来才会模糊。而fresco 没有做这样的处理,所以图片不会显示,只会有异常提示:Bitmap too large to be uploaded into a texture 。

2、下面我们就来解决这个问题。

既然Canvas 只能绘制比4096小的图片,那我们就只能把图片限制在4096以内,但是我们又不显图像失真,所以不能采取像素压缩,那么怎么办呢。我们可以利用BitmapRegionDecoder类。BitmapRegionDecoder 可以获取指定区域的图片。比如高度为8000的图片。我们可以用BitmapRegionDecoder生成两张高度为4000的图片。这样我们就可以用Canvas把两张图片画出来。

public class BigImageView extends ImageView{    private int windowWidth;    private BitmapRegionDecoder mDecoder;    private Rect bsrc;    private Rect src;    private Rect dst;    private Paint paint;    private ArrayList bmps;    public BigImageView(Context context) {        super(context);        // TODO Auto-generated constructor stub        init();    }    public BigImageView(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub        init();    }    private void init() {        // TODO Auto-generated method stub        windowWidth = getResources().getDisplayMetrics().widthPixels;        bmps = new ArrayList();        src = new Rect();        dst = new Rect();        bsrc = new Rect();        paint = new Paint();        paint.setAntiAlias(true);        paint.setFilterBitmap(true);    }    @Override    protected void onDraw(Canvas canvas) {        // TODO Auto-generated method stub        int count = bmps.size();        for(int i = 0;i0;            src.top = 0;            src.right = bmp.getWidth();            src.bottom = bmp.getHeight();            dst.left = 0;            dst.top = i*getHeight()/count;            dst.right = getWidth();            dst.bottom = dst.top+getHeight()/count;            canvas.drawBitmap(bmp, src, dst, paint);        }    }    @Override    public void setImageBitmap(final Bitmap bm) {        super.setImageBitmap(bm);        if(bm!=null){            float imgmul = (float)bm.getHeight()/(float)bm.getWidth();            LayoutParams lp = this.getLayoutParams();            lp.width = windowWidth;            lp.height = (int) (imgmul*windowWidth);            this.setLayoutParams(lp);        }        new Thread() {            public void run() {                try{                    int imageCount = bm.getHeight() % ImageUtils.getMaxHeight();                    ByteArrayOutputStream baos = new ByteArrayOutputStream();                    bm.compress(Bitmap.CompressFormat.PNG, 100, baos);                    InputStream isBm = new ByteArrayInputStream(baos.toByteArray());                    mDecoder = BitmapRegionDecoder.newInstance(isBm, true);                    for (int i = 0; i < imageCount; i++) {                        bsrc.left = 0;                        bsrc.top = i*bm.getHeight()/imageCount;                        bsrc.right = bm.getWidth();                        bsrc.bottom = bsrc.top+bm.getHeight()/imageCount;                        Bitmap bmp = mDecoder.decodeRegion(bsrc,null);                        bmps.add(bmp);                    }                    postInvalidate();                }catch(Exception e){                    e.printStackTrace();                }            }        }.start();    }}
public class ImageUtils {    private static final int DEFAULT_MAX_BITMAP_DIMENSION = 2048;    private static int maxHeight = 0;    static {        int[] maxTextureSize = new int[1];        GLES10.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);        maxHeight = Math.max(maxTextureSize[0], DEFAULT_MAX_BITMAP_DIMENSION);    }    public static int getMaxHeight(){        return maxHeight;    }}

更多相关文章

  1. Android显示gif格式图片
  2. Android(安卓)MediaPlayer与Http Proxy结合之优化篇
  3. Android训练课程(Android(安卓)Training) - 使用Volley传输网络
  4. 高亮的关键字
  5. Android加载图片的几种方式
  6. 全面了解Android热修复技术
  7. afinal logo Android的快速开发框架 afinal
  8. Android(安卓)WebView总结
  9. Android(安卓)开源照相和图片选择框架PictureSelector

随机推荐

  1. 享受Android应用程序的Java技术盛宴
  2. android:layout_gravity 和 android:grav
  3. TS3.0 引入 opengl es 1.x, opengl es 2.
  4. Android的消息机制,用Android线程…
  5. 【转】有关Android线程的学习
  6. Android常用复杂控件使用(三)--Fragment
  7. Android彻底组件化方案实践
  8. [导入]2010-03-02 传智播客—Android(四)数
  9. Android的Application中onCreate执行多次
  10. 开放的Android更易中招 安全防护刻不容缓