Android 如何实现大图 不压缩原样加载

本文探讨了Android中处理大图时如何避免压缩,指出未经压缩的大图可能导致内存问题。通过介绍BitmapRegionDecoder,说明如何利用该类动态获取图片局部区域,生成新的bitmap对象,以实现大图不压缩的加载方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

由于图片每个像素点一般情况下,在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”));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值