美文网首页
大图不撑爆内存

大图不撑爆内存

作者: 红色海_ | 来源:发表于2020-03-12 22:38 被阅读0次

    答案 :分片显示

    使用系统提供的BitmapRegionDecoder类可以完成。

    BitmapRegionDecoder:区域解码器
    可以解码一个矩形区域的图像,
    可以自定义一块矩形的区域,
    根据手势来移动矩形区域的位置就能看到整张图片了。

    //初始化变量
    private void init(){
    
    //用来配置Bitmap相关的参数
    //如获取Bitmap的宽高 内存复用等参数。
        mOptions = new BitmapFactory.Options();
        //滑动器
        mScroller = new Scroller(getContext());
        //所放器
        mMatrix = new Matrix();
        //手势识别 双击事件
        mGestureDetector = new GestureDetector(getContext(),this);
    
       //手势识别 缩放事件
        mScaleGestureDetector = new ScaleGestureDetector(getContext(),this);
    }
    
    
    
    //设置需要加载的图片
    // 通过BitmapFactory.Options拿到图片的真实宽高
    public void setImage(InputStream is){
        mOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is,null,mOptions);
        mImageWidth = mOptions.outWidth;
        mImageHeight = mOptions.outHeight;
    
       //去掉透明通道
        mOptions.inPreferredConfig = Bitmap.Config.RGB_565;
        mOptions.inJustDecodeBounds = false;
        try {
            //区域解码器
            mRegionDecoder = BitmapRegionDecoder.newInstance(is,false);
        } catch (IOException e) {
            e.printStackTrace();
        }
        requestLayout();
    }
    
    
    //获取View的宽高,计算缩放值
    // 视图的大小发生更改时被调用
    // 第一次在onMeasure之后被调用,可拿到View的宽高。
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mViewWidth = w;
        mViewHeight = h;
        mRect.top = 0;
        mRect.left = 0;
        mRect.right = (int) mViewWidth;
        mRect.bottom = (int) mViewHeight;
        mScale = mViewWidth/mImageWidth;
        mCurrentScale = mScale;
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(mRegionDecoder == null){
            return;
        }
        //复用内存
        mOptions.inBitmap = mBitmap;
        mBitmap = mRegionDecoder.decodeRegion(mRect,mOptions);
        mMatrix.setScale(mCurrentScale,mCurrentScale);
        canvas.drawBitmap(mBitmap,mMatrix,null);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mGestureDetector.onTouchEvent(event);
    
        mScaleGestureDetector.onTouchEvent(event);
        return true;
    }
    
    @Override
    public boolean onDown(MotionEvent e) {
        //如果正在滑动,先停止
        if(!mScroller.isFinished()){
            mScroller.forceFinished(true);
        }
        return true;
    }
    
    
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        //滑动的时候,改变mRect显示区域的位置
        mRect.offset((int)distanceX,(int)distanceY);
        //处理上下左右的边界
        if(mRect.left<0){
            mRect.left = 0;
            mRect.right = (int) (mViewWidth/mCurrentScale);
        }
        if(mRect.right>mImageWidth){
            mRect.right = (int) mImageWidth;
            mRect.left = (int) (mImageWidth-mViewWidth/mCurrentScale);
        }
        if(mRect.top<0){
            mRect.top = 0;
            mRect.bottom = (int) (mViewHeight/mCurrentScale);
        }
        if(mRect.bottom>mImageHeight){
            mRect.bottom = (int) mImageHeight;
            mRect.top = (int) (mImageHeight-mViewHeight/mCurrentScale);
        }
        invalidate();
        return false;
    }
    
    
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        mScroller.fling(mRect.left,mRect.top,-(int)velocityX,-(int)velocityY,0,(int)mImageWidth
                ,0,(int)mImageHeight);
        return false;
    }
    
    @Override
    public void computeScroll() {
        super.computeScroll();
        if(!mScroller.isFinished()&&mScroller.computeScrollOffset()){
            if(mRect.top+mViewHeight/mCurrentScale<mImageHeight){
                mRect.top = mScroller.getCurrY();
                mRect.bottom = (int) (mRect.top + mViewHeight/mCurrentScale);
            }
            if(mRect.bottom>mImageHeight) {
                mRect.top = (int) (mImageHeight - mViewHeight/mCurrentScale);
                mRect.bottom = (int) mImageHeight;
            }
            invalidate();
        }
    }
    
    
    
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        //处理双击事件
        if (mCurrentScale>mScale){
            mCurrentScale = mScale;
        } else {
            mCurrentScale = mScale*mMultiple;
        }
        mRect.right = mRect.left+(int)(mViewWidth/mCurrentScale);
        mRect.bottom = mRect.top+(int)(mViewHeight/mCurrentScale);
        //处理边界
        if(mRect.left<0){
            mRect.left = 0;
            mRect.right = (int) (mViewWidth/mCurrentScale);
        }
        if(mRect.right>mImageWidth){
            mRect.right = (int) mImageWidth;
            mRect.left = (int) (mImageWidth-mViewWidth/mCurrentScale);
        }
        if(mRect.top<0){
            mRect.top = 0;
            mRect.bottom = (int) (mViewHeight/mCurrentScale);
        }
        if(mRect.bottom>mImageHeight){
            mRect.bottom = (int) mImageHeight;
            mRect.top = (int) (mImageHeight-mViewHeight/mCurrentScale);
        }
        
        invalidate();
        return true;
    }
    
    
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        //处理手指缩放事件
        //获取与上次事件相比,得到的比例因子
        float scaleFactor = detector.getScaleFactor();
    //        mCurrentScale+=scaleFactor-1;
        mCurrentScale*=scaleFactor;
        if(mCurrentScale>mScale*mMultiple){
            mCurrentScale = mScale*mMultiple;
        }else if(mCurrentScale<=mScale){
            mCurrentScale = mScale;
        }
        mRect.right = mRect.left+(int)(mViewWidth/mCurrentScale);
        mRect.bottom = mRect.top+(int)(mViewHeight/mCurrentScale);
        invalidate();
        return true;
    }
    
    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        //当 >= 2 个手指碰触屏幕时调用
       //若返回 false 则忽略改事件调用
        return true;
    }
    
    摘取自网络 ,已备自己学习。
    https://www.jianshu.com/p/dacdfcf95596
    
    

    相关文章

      网友评论

          本文标题:大图不撑爆内存

          本文链接:https://www.haomeiwen.com/subject/qxvgjhtx.html