1. 程式人生 > >利用圖片區域性解析技術,載入高清圖片,拒絕壓縮!!!

利用圖片區域性解析技術,載入高清圖片,拒絕壓縮!!!

本篇部落格主要介紹如何使用BitmapRegionDecoder來載入大型圖片,這樣的好處就是不需要對圖片進行壓縮,不會降低圖片顯示的效果,缺點也很明顯,就是不能一次完全顯示出來,一次只能顯示一幅圖片的部分。
先看一下動態效果圖吧:
這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述

主佈局檔案:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id
="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">
<com.example.navigationview.CustomNavigationView android:id="@+id/cnv" android:layout_width="match_parent" android:layout_height
="0dp" android:layout_weight="1" />
<com.example.navigationview.DecoderView android:id="@+id/dv" android:layout_width="match_parent" android:layout_height="0dp" android:layout_below="@id/cnv" android:layout_weight="2" /> </LinearLayout>

導航欄對應的View:

package com.example.navigationview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by zhuyuqiang on 2017/3/15.
 */

public class CustomNavigationView extends View {

    private Context mContext;
    private int mViewWidth, mViewHeight;
    private int mSourceWidth, mSourceHeight;
    private int BOUNDS_COLOR = Color.RED;
    private int VIEW_DEFAULT_WIDTH = 400;
    private int VIEW_DEFAULT_HEIGHT = 400;
    private int sample = 1;
    private Bitmap mNavigationMap;
    private Paint mBitmapPaint, mBoundsPaint;
    private int mSourceId;
    private int mImageWidth, mImageHeight;
    private float density = 1f;
    private Point mViewPortPosition = new Point();
    private Rect mBoundRect = new Rect();
    private Rect mViewPortRect = null;
    private int mBoundWidth, mBoundHeight;
    private onBoundsChangedListener mListener;

    public interface onBoundsChangedListener {
        void deliveryViewAndBoundsRect(int width, int height, Rect mBoundsRect);
    }

    public CustomNavigationView(Context context) {
        this(context, null);
    }

    public CustomNavigationView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomNavigationView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public CustomNavigationView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        Log.i("zyq", "CustomNavigationView:construction");
        initBitmapPaint();
        mContext = context;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.i("zyq", "CustomNavigationView:onMeasure");
        setMeasuredDimension(getCustomMeasureWidth(widthMeasureSpec), getCustomMeasureHeight(heightMeasureSpec));
        initNavigationMap();
        calculateBoundRect(mViewPortRect);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mNavigationMap != null) {
            Log.i("zyq", "onDraw:mNavigationMap");
            canvas.drawBitmap(mNavigationMap, mViewPortPosition.x, mViewPortPosition.y, mBitmapPaint);
            drawBounds(canvas);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mDetector.onTouchEvent(event);
        return true;
    }

    public void setBoundsRect(Rect boundsRect) {
        mViewPortRect = boundsRect;
        calculateBoundRect(boundsRect);

    }

    public void setOnBoundsRectChangeListener(onBoundsChangedListener listener) {
        this.mListener = listener;
    }

    private void calculateBoundRect(Rect mViewPortRect) {
        if (mViewWidth > 0 && mViewPortRect != null) {
            mBoundRect.left = (mViewPortRect.left * mImageWidth / mSourceWidth);
            mBoundRect.right = (mViewPortRect.right * mImageWidth / mSourceWidth);
            mBoundRect.top = (mViewPortRect.top * mImageHeight / mSourceHeight);
            mBoundRect.bottom = (mViewPortRect.bottom * mImageHeight / mSourceHeight);
            mBoundWidth = mBoundRect.width();
            mBoundHeight = mBoundRect.height();
            Log.i("zyq_bound", "reset rect:left" + mBoundRect.left + " top=" + mBoundRect.top + " right=" + mBoundRect.right + " bottom=" + mBoundRect.bottom + "\n" +
                    "viewPort:left=" + mViewPortRect.left + " top=" + mViewPortRect.top + " right=" + mViewPortRect.right + " bottom=" + mViewPortRect.bottom);
        }

        invalidate();
    }

    public void setDrawableId(int sourceId) {
        this.mSourceId = sourceId;
    }

    private void initNavigationMap() {
        density = getResources().getDisplayMetrics().density;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(getResources(), mSourceId, options);
        mSourceWidth = options.outWidth;
        mSourceHeight = options.outHeight;
        while (mSourceWidth / sample > (mViewWidth / density)
                || mSourceHeight / sample > (mViewHeight / density)) {
            sample *= 2;
        }
        Log.i("zyq", "sample =" + sample);
        options.inJustDecodeBounds = false;
        options.inSampleSize = sample;
        mNavigationMap = BitmapFactory.decodeResource(getResources(), mSourceId, options);
        mImageWidth = mNavigationMap.getWidth();
        mImageHeight = mNavigationMap.getHeight();
        mViewPortPosition.x = getPaddingLeft() + (mViewWidth - mImageWidth) / 2;
        mViewPortPosition.y = getPaddingTop() + (mViewHeight - mImageHeight) / 2;
        Log.i("zyq", "mViewWidth=" + mViewWidth + " mViewHeight=" + mViewHeight + " mImageWidth=" + mImageWidth + " mImageHeight=" + mImageHeight);
    }

    private void initBitmapPaint() {
        mBitmapPaint = new Paint();
        mBitmapPaint.setAntiAlias(true);
        mBitmapPaint.setDither(true);
        mBitmapPaint.setFilterBitmap(true);

        mBoundsPaint = new Paint();
        mBoundsPaint.setAntiAlias(true);
        mBoundsPaint.setDither(true);
        mBoundsPaint.setColor(BOUNDS_COLOR);
        mBoundsPaint.setStrokeWidth(2.0f);
        mBoundsPaint.setStyle(Paint.Style.STROKE);
    }

    private int getCustomMeasureWidth(int measureWidth) {
        int mode = MeasureSpec.getMode(measureWidth);
        int size = MeasureSpec.getSize(measureWidth);
        Log.i("zyq", "mode=" + mode + " EXACTLY=" + MeasureSpec.EXACTLY + " UNSPECIFIED=" + MeasureSpec.UNSPECIFIED + " AT_MOST=" + MeasureSpec.AT_MOST);
        if (mode == MeasureSpec.EXACTLY) {
            mViewWidth = size - getPaddingLeft() - getPaddingRight();
            return size;
        } else {
            mViewWidth = VIEW_DEFAULT_WIDTH;
            return VIEW_DEFAULT_WIDTH + getPaddingRight() + getPaddingLeft();
        }
    }

    private int getCustomMeasureHeight(int measureHeight) {
        int mode = MeasureSpec.getMode(measureHeight);
        int size = MeasureSpec.getSize(measureHeight);
        Log.i("zyq", "mode=" + mode + " EXACTLY=" + MeasureSpec.EXACTLY + " UNSPECIFIED=" + MeasureSpec.UNSPECIFIED + " AT_MOST=" + MeasureSpec.AT_MOST);
        if (mode == MeasureSpec.EXACTLY) {
            mViewHeight = size - getPaddingTop() - getPaddingBottom();
            return size;
        } else {
            mViewHeight = VIEW_DEFAULT_HEIGHT;
            return VIEW_DEFAULT_HEIGHT + getPaddingTop() + getPaddingBottom();
        }
    }

    private void drawBounds(Canvas canvas) {
        canvas.save();
        if (mBoundRect != null) {
            Log.i("zyq_bound", "drawBounds");
//            canvas.drawRect(mBoundRect,mBoundsPaint);
            canvas.drawRect(mBoundRect.left + mViewPortPosition.x, mBoundRect.top + mViewPortPosition.y, mBoundRect.right + mViewPortPosition.x,
                    mBoundRect.bottom + mViewPortPosition.y, mBoundsPaint);
        }
        canvas.restore();
    }

    private GestureDetector mDetector = new GestureDetector(mContext, new GestureDetector.OnGestureListener() {
        @Override
        public boolean onDown(MotionEvent e) {
            return false;
        }

        @Override
        public void onShowPress(MotionEvent e) {

        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            updateBoundRect(-distanceX, -distanceY);
//            postInvalidateDelayed(50);
            invalidate();
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {

        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return false;
        }
    });

    private void updateBoundRect(float width, float height) {
        Log.i("zyq", "width=" + width + " height=" + height);
        mBoundRect.left = mBoundRect.left + (int) width;
        mBoundRect.right = mBoundRect.right + (int) width;
        mBoundRect.top = mBoundRect.top + (int) height;
        mBoundRect.bottom = mBoundRect.bottom + (int) height;
        if (mBoundRect.left < 0) {
            mBoundRect.left = 0;
            mBoundRect.right = mBoundWidth;
        }
        if (mBoundRect.top < 0) {
            mBoundRect.top = 0;
            mBoundRect.bottom = mBoundHeight;
        }
        if (mBoundRect.right > (mImageWidth)) {
            mBoundRect.right = (mImageWidth);
            mBoundRect.left = (mImageWidth) - mBoundWidth;
        }
        if (mBoundRect.bottom > (mImageHeight)) {
            mBoundRect.bottom = (mImageHeight);
            mBoundRect.top = (mImageHeight) - mBoundHeight;
        }
        if (mListener != null) {
            mListener.deliveryViewAndBoundsRect(mImageWidth, mImageHeight, mBoundRect);
        }
        Log.i("zyq_bound", "reset rect:left" + mBoundRect.left + " top=" + mBoundRect.top + " right=" + mBoundRect.right + " bottom=" + mBoundRect.bottom + "\n" +
                "mViewPortPosition.y+mImageHeight=" + (mViewPortPosition.y + mImageHeight) + " mViewPortPosition.x+mImageWidth" + (mViewPortPosition.x + mImageWidth));
    }
}

圖片顯示View:

package com.example.navigationview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import java.io.IOException;
import java.io.InputStream;

/**
 * Created by zhuyuqiang on 2017/3/14.
 */

public class DecoderView extends View {

    private Context mContext;
    private Paint mBitmapPaint, mBoundPaint;
    private int DEFAULT_BOUND_COLOR = Color.RED;
    private final int DEFAULT_WIDTH = 600;
    private final int DEFAULT_HEIGHT = 600;
    private Rect mViewPort = new Rect();
    private int mOriginWidth, mOriginHeight;
    private BitmapFactory.Options mDecoderOption = new BitmapFactory.Options();
    private InputStream mSourceInputStream = null;
    private String mSourcePath;
    private float mDownX, mDownY;
    private BitmapRegionDecoder mDecoder = null;
    private int mCurrentWidth, mCurrentHeight;
    private onViewPortPositionChangeListener mListener;

    public interface onViewPortPositionChangeListener {
        void getViewPortRect(Rect mViewPortRect);
    }

    public DecoderView(Context context) {
        this(context, null);
    }

    public DecoderView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DecoderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public DecoderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mContext = context;
        initPaints();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getCustomMeasuteWidth(widthMeasureSpec), getCustomMeasuteHeight(heightMeasureSpec));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawPartImage(canvas);
        Log.i("zyq", "width =" + getWidth() + " height=" + getHeight());
    }

    private void drawPartImage(Canvas canvas) {
        Log.i("zyq", "drawPartImage = " + (mSourceInputStream != null));
        if (mSourceInputStream != null) {
            try {
                Log.i("zyq", "mSourceInputStream != null");
                if (mDecoder == null) {
                    mDecoder = BitmapRegionDecoder.newInstance(mSourceInputStream, true);

                }
            } catch (IOException e) {
                Log.i("zyq", "e=" + e.toString());
            }
        }
        if (mSourcePath != null) {
            try {
                Log.i("zyq", "mSourceInputStream != null");
                if (mDecoder == null) {
                    mDecoder = BitmapRegionDecoder.newInstance(mSourceInputStream, true);
                }
            } catch (IOException e) {
                Log.i("zyq", "e=" + e.toString());
            }
        }
        if (mDecoder != null) {
            Bitmap b = mDecoder.decodeRegion(mViewPort, mDecoderOption);
            canvas.drawBitmap(b, getPaddingLeft(), getPaddingTop(), mBitmapPaint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

//        switch (event.getAction()) {
//            case MotionEvent.ACTION_DOWN:
//                Log.i("zyq", "MotionEvent.ACTION_DOWN: mDownX="+mDownX+" mDownY="+mDownY);
//                mDownX = event.getX();
//                mDownY = event.getY();
////                break;
//            case MotionEvent.ACTION_MOVE:
//                float mMoveX = event.getX();
//                float mMoveY = event.getY();
//                Log.i("zyq", "MotionEvent.ACTION_MOVE mMoveX="+mMoveX+" mMoveY="+mMoveY);
//                Log.i("zyq", "mMoveX - mDownX="+(mMoveX - mDownX)+" mMoveY - mDownY="+(mMoveY - mDownY));
//                updateViewPort(-(mMoveX - mDownX), -(mMoveY - mDownY));
//                invalidate();
////                break;
//            case MotionEvent.ACTION_UP:
//                Log.i("zyq", "MotionEvent.ACTION_UP");
////                break;
//        }
        mDetector.onTouchEvent(event);
        return true;
    }

    private void updateViewPort(float width, float height) {
//        Log.i("zyq", "width=" + width + " height=" + height);
        mViewPort.left = mViewPort.left + (int) width;
        mViewPort.right = mViewPort.right + (int) width;
        mViewPort.top = mViewPort.top + (int) height;
        mViewPort.bottom = mViewPort.bottom + (int) height;
        if (mViewPort.left < 0) {
            mViewPort.left = 0;
            mViewPort.right = mCurrentWidth;
        }
        if (mViewPort.top < 0) {
            mViewPort.top = 0;
            mViewPort.bottom = mCurrentHeight;
        }
        if (mViewPort.right > mOriginWidth) {
            mViewPort.right = mOriginWidth;
            mViewPort.left = mOriginWidth - mCurrentWidth;
        }
        if (mViewPort.bottom > mOriginHeight) {
            mViewPort.bottom = mOriginHeight;
            mViewPort.top = mOriginHeight - mCurrentHeight;
        }
        if (mListener != null) {
            mListener.getViewPortRect(mViewPort);
        }

    }

    public void setViewPortChangeListener(onViewPortPositionChangeListener listener) {
        this.mListener = listener;
    }

    public void setImageResource(String filePath) {
        if (mSourceInputStream != null) {
            throw new SecurityException("已經設定過圖片資源");
        }
        mDecoderOption.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, mDecoderOption);
        mOriginHeight = mDecoderOption.outHeight;
        mOriginWidth = mDecoderOption.outWidth;
        Log.i("qqq","width = "+mOriginWidth+" height = "+mOriginHeight);
        mSourcePath = filePath;
        mDecoderOption.inJustDecodeBounds = false;
        mDecoderOption.inPreferredConfig = Bitmap.Config.ARGB_8888;
        invalidate();
    }

    public void setImageResource(InputStream is) {
        if (mSourcePath != null) {
            throw new SecurityException("已經設定過圖片資源");
        }
        mDecoderOption.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is, null, mDecoderOption);
        mOriginHeight = mDecoderOption.outHeight;
        mOriginWidth = mDecoderOption.outWidth;
        Log.i("qqq","width = "+mOriginWidth+" height = "+mOriginHeight);
        mSourceInputStream = is;
        mDecoderOption.inJustDecodeBounds = false;
        mDecoderOption.inPreferredConfig = Bitmap.Config.ARGB_8888;
        Log.i("zyq", "set Image source");
        invalidate();
    }

    public Rect getViewPortRect() {
        return mViewPort;
    }

    public void setViewPortRectPosition(float x, float y) {
        int positionX = (int) (x * mOriginWidth);
        int positionY = (int) (y * mOriginHeight);
        int tran_X = positionX - mViewPort.left;
        int tran_y = positionY - mViewPort.top;
        updateViewPort(tran_X, tran_y);
        invalidate();
    }

    private void initPaints() {
        Log.i("zyq", "init Paints");
        mBitmapPaint = new Paint();
        mBitmapPaint.setAntiAlias(true);
        mBitmapPaint.setDither(true);
        mBitmapPaint.setFilterBitmap(true);

        mBoundPaint = new Paint();
        mBoundPaint.setAntiAlias(true);
        mBoundPaint.setDither(true);
        mBoundPaint.setColor(DEFAULT_BOUND_COLOR);
    }

    private int getCustomMeasuteWidth(int widthMeasureSpec) {
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = MeasureSpec.getSize(widthMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            mViewPort.left = getPaddingLeft();
            mViewPort.right = size - getPaddingRight();
            mCurrentWidth = size - getPaddingRight() - getPaddingLeft();
            Log.i("zyq", "getCustomMeasuteHeight: MeasureSpec.EXACTLY");
            return size;
        } else {
            Log.i("zyq", "getCustomMeasuteHeight: MeasureSpec.*");
            mViewPort.left = getPaddingLeft();
            mViewPort.right = DEFAULT_WIDTH + getPaddingLeft();
            return DEFAULT_WIDTH + getPaddingRight() + getPaddingRight();
        }
    }

    private int getCustomMeasuteHeight(int heightMeasureSpec) {
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            Log.i("zyq", "getCustomMeasuteHeight: MeasureSpec.EXACTLY");
            mViewPort.top = getPaddingTop();
            mViewPort.bottom = size - getPaddingBottom();
            mCurrentHeight = size - getPaddingBottom() - getPaddingTop();
            return size;
        } else {
            Log.i("zyq", "getCustomMeasuteHeight: MeasureSpec.*");
            mViewPort.top = getPaddingTop();
            mViewPort.bottom = DEFAULT_HEIGHT + getPaddingTop();
            return DEFAULT_HEIGHT + getPaddingTop() + getPaddingBottom();
        }
    }

    private GestureDetector mDetector = new GestureDetector(mContext, new GestureDetector.OnGestureListener() {
        @Override
        public boolean onDown(MotionEvent e) {
            return false;
        }

        @Override
        public void onShowPress(MotionEvent e) {

        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            updateViewPort(distanceX, distanceY);
//            postInvalidateDelayed(50);
            invalidate();
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {

        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return false;
        }
    });
}

activity檔案:

package com.example.navigationview;

import android.graphics.Rect;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import java.io.IOException;
import java.io.InputStream;

public class MainActivity extends AppCompatActivity {

    private DecoderView dv;
    private CustomNavigationView cnv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dv = (DecoderView) findViewById(R.id.dv);
        cnv = (CustomNavigationView) findViewById(R.id.cnv);
        InputStream is = null;
        try {
            is = getAssets().open("lol.jpg");
            Log.i("zyq", "(is != null) =" + (is != null));
        } catch (IOException e) {
            Log.i("zyq", "exception = " + e.toString());
            e.printStackTrace();
        }
        dv.setImageResource(is);
        dv.setViewPortChangeListener(new DecoderView.onViewPortPositionChangeListener() {
            @Override
            public void getViewPortRect(Rect mViewPortRect) {
                cnv.setBoundsRect(mViewPortRect);
            }
        });
        cnv.setDrawableId(R.drawable.lol);
        cnv.setOnBoundsRectChangeListener(new CustomNavigationView.onBoundsChangedListener() {
            @Override
            public void deliveryViewAndBoundsRect(int width, int height, Rect mBoundsRect) {
                dv.setViewPortRectPosition(mBoundsRect.left / (float) width, mBoundsRect.top / (float) height);
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        cnv.setBoundsRect(dv.getViewPortRect());
    }
}

有幾個知識點需要稍微提及一下:
1、一般大的檔案資源都在存放在assets目錄下的,在AndroidStudio中新建資源目錄,需要注意目錄的層級,如果目錄層級不對,可能出現無法載入資源情況!!
目錄所在層級如下圖所示:
這裡寫圖片描述

2、在本Demo中可以通過拉動導航View中的紅框或者直接滑動圖片顯示View都可以更新顯示圖片,這一點可能在上面的效果上看的不是很明顯,有興趣的朋友可以自行下載的demo試一下!!!

3、BitmapRegionDecoder物件可以通過newInstance方法獲取,其中第一個引數為圖片資源來源!!至於第二個引數直接設定true就可以了!!其中圖片的資源可以設定為輸入流、路徑等,詳細的還是看一下原始碼吧,在這裡就不解釋了!!

4、導航View的圖片載入需要使用壓縮技術,不然肯定會拋異常的,解析圖片需要使用BitmapFactory,使用起來也很簡單,在這裡就不做更多的介紹了!!!

5、由於可以更過導航欄中的View和圖片顯示的View更新BitmapRegionDecoder解析的區域,需要對兩個view的顯示進行同步,具體的可以看一下程式碼,使用過使用回撥函式實現的,實現過程比較簡單,不詳細介紹來了!!!

6、區域性解析的方法decodeRegion,第一個引數為一個rect引數,代表的是解析的區域,更新的時候改變的就是這個rect的四個頂點的值,詳細的還是看一下程式碼吧,主要還是思路,真正實現起來其實沒有什麼難度的!!!!

好了,關於圖片的區域性解析就介紹到這裡,謝謝大家的關注!!!!

這是我的微信公眾號,如果可以的話,希望您可以幫忙關注一下,這將是對我最大的鼓勵了,謝謝!!

這裡寫圖片描述

程式碼地址: