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);
}
}
Android-BitmapRegionDecoder區(qū)域解碼器的使用
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
相關閱讀更多精彩內容
- 前面一章我們講解了解復用的實現(xiàn)流程,但并沒有詳細講解解碼器部分的處理,這一章我們將會介紹音頻解碼器以及視頻解碼器的...
- Mac和iOS支持使用VideoToolBox硬件編解碼H264和H265的視頻流,這次使用FFmpeg解封裝使用...