Android-BitmapRegionDecoder區(qū)域解碼器的使用

public class RegionImageView extends ImageView {
    private BitmapRegionDecoder mRegionDecoder;//區(qū)域解碼器
    private BitmapFactory.Options mOptions = new BitmapFactory.Options();
    private int mImageWidth;//原圖寬
    private int mImageHeight;//原圖高
    private Bitmap mBitmap;
    private InputStream mInputStream;
    private Matrix mMatrix = new Matrix();
    private int image_resId;//屬性 圖片resId
    private float scaleBias = 1;//縮放會導致bitmap變大不建議縮放
    private int rate = 5;//滑動速率

    public RegionImageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initAttrs(attrs);
        init();
    }

    private void initAttrs(AttributeSet attrs) {
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.RegionImageView);
        image_resId = typedArray.getResourceId(R.styleable.RegionImageView_image_resId, 0);
        typedArray.recycle();
    }

    private void init() {
        mInputStream = getResources().openRawResource(image_resId);
        setRegionDecoder(mInputStream);
    }


    private void updateRegion(int x, int y, boolean isInvalidate) {
        x = rate * x;
        y = rate * y;
        mRectLeft = x;
        mRectTop = y;
        mRectRight = (int) (mRectLeft + measuredWidth * scaleBias);
        mRectBottom = (int) (mRectTop + measuredHeight * scaleBias);
        if (mRectLeft < 0) {
            mRectLeft = 0;
            mRectRight = (int) (measuredWidth * scaleBias);
            dx = mRectLeft / rate;
        }
        if (mRectTop < 0) {
            mRectTop = 0;
            mRectBottom = (int) (measuredHeight * scaleBias);
            dy = mRectTop / rate;
        }
        if (mRectLeft > mImageWidth - measuredWidth * scaleBias) {
            mRectLeft = (int) (mImageWidth - measuredWidth * scaleBias);
            mRectRight = mImageWidth;
            dx = mRectLeft / rate;
        }
        if (mRectTop > mImageHeight - measuredHeight * scaleBias) {
            mRectTop = (int) (mImageHeight - measuredHeight * scaleBias);
            mRectBottom = mImageHeight;
            dy = mRectTop / rate;
        }
        if (isInvalidate)
            invalidate();
    }

    //設置區(qū)域解碼器
    public void setRegionDecoder(InputStream inputStream) {
        mOptions.inJustDecodeBounds = true;//設置此參數(shù)是僅僅讀取圖片的寬高到options中,不會將整張圖片讀到內存中,防止oom
        BitmapFactory.decodeStream(inputStream, null, mOptions);
        mImageWidth = mOptions.outWidth;
        mImageHeight = mOptions.outHeight;
        mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
        mOptions.inJustDecodeBounds = false;
        try {
            //區(qū)域解碼器
            mRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private int mRectLeft, mRectTop, mRectRight, mRectBottom;
    private Rect mRect = new Rect();
    private int measuredWidth;
    private int measuredHeight;

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        measuredWidth = getMeasuredWidth();
        measuredHeight = getMeasuredHeight();
        updateRegion(0, 0, false);//默認左上角
    }

    @Override
    protected void onDraw(Canvas canvas) {
//        scale(canvas);//pass不用縮放壓縮的方式
//        super.onDraw(canvas);//直接繪制大圖java.lang.RuntimeException: Canvas: trying to draw too large(275646000bytes) bitmap. 意思262mb太大了

        //如果設置,則采用Options對象的解碼方法將在加載內容時嘗試重用此位圖。
        mOptions.inBitmap = mBitmap;
        mRect.set(mRectLeft, mRectTop, mRectRight, mRectBottom);
        mMatrix.setScale(1 / scaleBias, 1 / scaleBias);
        mBitmap = mRegionDecoder.decodeRegion(mRect, mOptions);
        canvas.drawBitmap(mBitmap, mMatrix, null);

    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        try {
            if (mInputStream != null) {
                mInputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private float dx, dy, downX, downY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getRawX() + dx;
                downY = event.getRawY() + dy;
                break;
            case MotionEvent.ACTION_MOVE:
                dx = downX - event.getRawX();
                dy = downY - event.getRawY();
                updateRegion((int) dx, (int) dy, true);
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }


    private Matrix matrix = new Matrix();
    private Bitmap bitmap;
    private int drawCount = 0;
    Bitmap newBitmap;

    //縮放相當于壓縮原bitmap體積
    private void scale(Canvas canvas) {
        if (drawCount == 0) {
            bitmap = ((BitmapDrawable) getDrawable()).getBitmap();//獲取bitmap
            //新bitmap尺寸原來1/10 相當于原bitmap大小的1/100  2.62mb
            newBitmap = Bitmap.createBitmap(bitmap.getWidth() / 10, bitmap.getHeight() / 10, bitmap.getConfig());
            Canvas newCanvas = new Canvas(newBitmap);
            matrix.setScale(0.1f, 0.1f);//矩陣原圖縮放1/10
            newCanvas.drawBitmap(bitmap, matrix, null);
            setImageBitmap(null);//置空釋放原bitmap引用消耗的內存
            bitmap = null;//置空釋放原bitmap引用消耗的內存
            drawCount++;
        }
        matrix.setScale(1f, 1f);
        canvas.drawBitmap(newBitmap, matrix, null);
    }


}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容