前言
由于图片每个像素点一般情况下,在android中会占用4个字节。对于一个1024*1024分辨率的图片就会占用4MB内存,可见图片对于内存的使用是非常大的,所以在Android系统中处理图片基本上都会对其进行压缩,比如设置采样率,分辨率等参数。
那么如果有一张特别大的图,如何不压缩进行处理。其实也很简单,可以使用 BitmapRegionDecoder。
原理
通过BitmapRegionDecoder 设置一个输入流,然后动态的取局部区域生成新的bitmap对象就可以了。贴下具体代码:
public class BigImageView extends android.support.v7.widget.AppCompatImageView {
private BitmapRegionDecoder mBitmapRegionDecoder;
private Bitmap mBitmap;
private int mBitmapWidth, mBitmapHeight;
private BitmapFactory.Options mOptions;
private Rect mRect;
public BigImageView(Context context) {
super(context);
}
public BigImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public BigImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 设置大图输入流
*
* @param inputStream
*/
public void decodeInputStream(final InputStream inputStream) {
post(new Runnable() {
@Override
public void run() {
try {
mBitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
mBitmapWidth = mBitmapRegionDecoder.getWidth();
mBitmapHeight = mBitmapRegionDecoder.getHeight();
Log.d(BigImageView.class.getName(), mBitmapWidth + " " + mBitmapHeight);
int left = 0, top = 0, right = 0, bottom = 0;
if (getWidth() < mBitmapWidth) {
right = getWidth();
} else {
right = mBitmapWidth;
}
if (getHeight() < mBitmapHeight) {
bottom = getHeight();
} else {
bottom = mBitmapHeight;
}
mRect = new Rect(left, top, right, bottom);
createRectBitmap(mRect);
setImageBitmap(mBitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
private void createRectBitmap(Rect rect) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize=1;
mBitmap = mBitmapRegionDecoder.decodeRegion(rect, options);
}
int mDownX = 0, mDownY;
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = x;
mDownY = y;
return true;
case MotionEvent.ACTION_MOVE:
int dx = mDownX - x;
int dy = mDownY - y;
if (getWidth() < mBitmapWidth) {
mRect.left += dx;
if (mRect.left < 0)
mRect.left = 0;
if (mRect.left > mBitmapWidth - getWidth())
mRect.left = mBitmapWidth - getWidth();
mRect.right = mRect.left + getWidth();
}
if (getHeight() < mBitmapHeight) {
mRect.top += dy;
if (mRect.top < 0)
mRect.top = 0;
if (mRect.top > mBitmapHeight - getHeight())
mRect.top = mBitmapHeight - getHeight();
mRect.bottom = mRect.top + getHeight();
}
createRectBitmap(mRect);
setImageBitmap(mBitmap);
mDownX = x;
mDownY = y;
break;
}
return super.onTouchEvent(event);
}
}
使用方法:bigImageView.decodeInputStream(assetManager.open(“t2.jpg”));