Android 一個Imageview加載長圖

有些APP可能爲了省事和界面美觀會把不少內容作成一張高清圖片交給移動端去加載(咱們的項目就是...),若是圖片較小那還OK,可是若是圖片過大(咱們的有2M還多,MMP)要麼不顯示,要麼很是模糊。那咱們應該怎麼辦呢?用BitmapRegionDecoder將圖片進行切分而後再進行拼接就能夠了。android

 

大圖展現.gifcanvas

以本文圖片爲例,高是6543,以3000爲單位進行切分,那麼要生成2個3000的加上1個543的bitmapide

String url = "http://bmob-cdn-15177.b0.upaiyun.com/2018/08/23/8fa7f1c2404bafbd808bde10ff072ceb.jpg";
Glide.with(this).load(url)
                .asBitmap()
                .into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                        setBitmapToImg(resource);
                    }
                });

private void setBitmapToImg(Bitmap resource) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            resource.compress(Bitmap.CompressFormat.PNG, 100, baos);

            InputStream isBm = new ByteArrayInputStream(baos.toByteArray());

            //BitmapRegionDecoder newInstance(InputStream is, boolean isShareable)
            //用於建立BitmapRegionDecoder,isBm表示輸入流,只有jpeg和png圖片才支持這種方式,
            // isShareable若是爲true,那BitmapRegionDecoder會對輸入流保持一個表面的引用,
            // 若是爲false,那麼它將會建立一個輸入流的複製,而且一直使用它。即便爲true,程序也有可能會建立一個輸入流的深度複製。
            // 若是圖片是逐步解碼的,那麼爲true會下降圖片的解碼速度。若是路徑下的圖片不是支持的格式,那就會拋出異常
            BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(isBm, true);

            final int imgWidth = decoder.getWidth();
            final int imgHeight = decoder.getHeight();

            BitmapFactory.Options opts = new BitmapFactory.Options();

            //計算圖片要被切分紅幾個整塊,
            // 若是sum=0 說明圖片的長度不足3000px,不進行切分 直接添加
            // 若是sum>0 先添加整圖,再添加多餘的部分,不然多餘的部分不足3000時底部會有空白
            int sum = imgHeight/3000;

            int redundant = imgHeight%3000;

            List<Bitmap> bitmapList = new ArrayList<>();

            //說明圖片的長度 < 3000
            if (sum == 0){
                //直接加載
                bitmapList.add(resource);
            }else {
                //說明須要切分圖片
                for (int i = 0; i < sum; i++) {
                    //須要注意:mRect.set(left, top, right, bottom)的第四個參數,
                    //也就是圖片的高不能大於這裏的4096
                    mRect.set(0, i*3000, imgWidth, (i+1) * 3000);
                    Bitmap bm = decoder.decodeRegion(mRect, opts);
                    bitmapList.add(bm);
                }

                //將多餘的不足3000的部分做爲尾部拼接
                if (redundant > 0){
                    mRect.set(0, sum*3000, imgWidth, imgHeight);
                    Bitmap bm = decoder.decodeRegion(mRect, opts);
                    bitmapList.add(bm);
                }

            }

            Bitmap bigbitmap = Bitmap.createBitmap(imgWidth, imgHeight, Bitmap.Config.ARGB_8888);
            Canvas bigcanvas = new Canvas(bigbitmap);

            Paint paint = new Paint();
            int iHeight = 0;

            //將以前的bitmap取出來拼接成一個bitmap
            for (int i = 0; i < bitmapList.size(); i++) {
                Bitmap bmp = bitmapList.get(i);
                bigcanvas.drawBitmap(bmp, 0, iHeight, paint);
                iHeight += bmp.getHeight();

                bmp.recycle();
                bmp = null;
            }

            mImageView1.setImageBitmap(bigbitmap);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

佈局文件佈局

<ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
            <ImageView
                android:id="@+id/iv_big"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"
                android:scaleType="fitXY"/>
</ScrollView>

須要注意:mRect.set(left, top, right, bottom)的第四個參數, 不能大於4096,最後儘可能把圖片壓縮下this



做者:iot_xc
連接:https://www.jianshu.com/p/ef44310cfe72
來源:簡書
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。url

相關文章
相關標籤/搜索