国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Android保存多張圖片到本地

thursday / 3623人閱讀

摘要:如果用戶點擊保存按鈕,則保存若干張圖片到本地。這個時候,如果點擊保存控件,則循環遍歷圖片資源集合保存到本地文件夾。如果是線程套線程的話,第一個子線程結束了,嵌套在該子線程的循環內的子線程還沒結束,從而主線程獲取不到子線程里獲取的圖片。

目錄介紹

01.實際開發保存圖片遇到的問題

02.直接用http請求圖片并保存本地

03.用glide下載圖片保存本地

04.如何實現連續保存多張圖片

05.關于其他介紹

好消息

博客筆記大匯總【16年3月到至今】,包括Java基礎及深入知識點,Android技術博客,Python學習筆記等等,還包括平時開發中遇到的bug匯總,當然也在工作之余收集了大量的面試題,長期更新維護并且修正,持續完善……開源的文件是markdown格式的!同時也開源了生活博客,從12年起,積累共計N篇[近100萬字,陸續搬到網上],轉載請注明出處,謝謝!

鏈接地址:https://github.com/yangchong2...

如果覺得好,可以star一下,謝謝!當然也歡迎提出建議,萬事起于忽微,量變引起質變!

01.實際開發保存圖片遇到的問題

業務需求

在素材list頁面的九宮格素材中,展示網絡請求加載的圖片。如果用戶點擊保存按鈕,則保存若干張圖片到本地。具體做法是,使用glide加載圖片,然后設置listener監聽,在圖片請求成功onResourceReady后,將圖片資源resource保存到集合中。這個時候,如果點擊保存控件,則循環遍歷圖片資源集合保存到本地文件夾。

具體做法代碼展示

這個時候直接將請求網絡的圖片轉化成bitmap,然后存儲到集合中。然后當點擊保存按鈕的時候,將會保存該組集合中的多張圖片到本地文件夾中。

//bitmap圖片集合
private ArrayList bitmapArrayList = new ArrayList<>();


RequestOptions requestOptions = new RequestOptions()
        .transform(new GlideRoundTransform(mContext, radius, cornerType));
GlideApp.with(mIvImg.getContext())
        .asBitmap()
        .load(url)
        .listener(new RequestListener() {
            @Override
            public boolean onLoadFailed(@Nullable GlideException e, Object model,
                                        Target target, boolean isFirstResource) {
                return true;
            }

            @Override
            public boolean onResourceReady(Bitmap resource, Object model, Target target,
                                           DataSource dataSource, boolean isFirstResource) {
                bitmapArrayList.add(resource);
                return false;
            }
        })
        .apply(requestOptions)
        .placeholder(ImageUtils.getDefaultImage())
        .into(mIvImg);
        
        
        
//循環遍歷圖片資源集合,然后開始保存圖片到本地文件夾
mBitmap = bitmapArrayList.get(i);
savePath = FileSaveUtils.getLocalImgSavePath();
FileOutputStream fos = null;
try {
    File filePic = new File(savePath);
    if (!filePic.exists()) {
        filePic.getParentFile().mkdirs();
        filePic.createNewFile();
    }
    fos = new FileOutputStream(filePic);
    // 100 圖片品質為滿
    mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (IOException e) {
    e.printStackTrace();
    return null;
} finally {
    if (fos != null) {
        try {
            fos.flush();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //刷新相冊
    if (isScanner) {
        scanner(context, savePath);
    }
}

遇到的問題

保存圖片到本地后,發現圖片并不是原始的圖片,而是展現在view控件上被裁切的圖片,也就是ImageView的尺寸大小圖片。

為什么會遇到這種問題

如果你傳遞一個ImageView作為.into()的參數,Glide會使用ImageView的大小來限制圖片的大小。例如如果要加載的圖片是1000x1000像素,但是ImageView的尺寸只有250x250像素,Glide會降低圖片到小尺寸,以節省處理時間和內存。

在設置into控件后,也就是說,在onResourceReady方法中返回的圖片資源resource,實質上不是你加載的原圖片,而是ImageView設定尺寸大小的圖片。所以保存之后,你會發現圖片變小了。

那么如何解決問題呢?

第一種做法:九宮格圖片控件展示的時候會加載網絡資源,然后加載圖片成功后,則將資源保存到集合中,點擊保存則循環存儲集合中的資源。這種做法只會請求一個網絡。由于開始

第二種做法:九宮格圖片控件展示的時候會加載網絡資源,點擊保存九宮格圖片的時候,則依次循環請求網絡圖片資源然后保存圖片到本地,這種做法會請求兩次網絡。

02.直接用http請求圖片并保存本地

http請求圖片

/**
 * 請求網絡圖片
 * @param url                       url

 */
private static long time = 0;
public static InputStream HttpImage(String url) {
    long l1 = System.currentTimeMillis();
    URL myFileUrl = null;
    Bitmap bitmap = null;
    HttpURLConnection conn = null;
    InputStream is = null;
    try {
        myFileUrl = new URL(url);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    try {
        conn = (HttpURLConnection) myFileUrl.openConnection();
        conn.setConnectTimeout(10000);
        conn.setReadTimeout(5000);
        conn.setDoInput(true);
        conn.connect();
        is = conn.getInputStream();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (is != null) {
                is.close();
                conn.disconnect();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        long l2 = System.currentTimeMillis();
        time = (l2-l1) + time;
        LogUtils.e("毫秒值"+time);
        //保存
    }
    return is;
}
```

保存到本地

InputStream inputStream = HttpImage(
        "https://img1.haowmc.com/hwmc/material/2019061079934131.jpg");
String localImgSavePath = FileSaveUtils.getLocalImgSavePath();
File imageFile = new File(localImgSavePath);
if (!imageFile.exists()) {
    imageFile.getParentFile().mkdirs();
    try {
        imageFile.createNewFile();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
FileOutputStream fos = null;
BufferedInputStream bis = null;
try {
    fos = new FileOutputStream(imageFile);
    bis = new BufferedInputStream(inputStream);
    byte[] buffer = new byte[1024];
    int len;
    while ((len = bis.read(buffer)) != -1) {
        fos.write(buffer, 0, len);
    }
} catch (Exception e) {
    e.printStackTrace();
} finally {
    try {
        if (bis != null) {
            bis.close();
        }
        if (fos != null) {
            fos.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

03.用glide下載圖片保存本地

glide下載圖片

File file = Glide.with(ReflexActivity.this)
        .load(url.get(0))
        .downloadOnly(500, 500)
        .get();

保存到本地

String localImgSavePath = FileSaveUtils.getLocalImgSavePath();
File imageFile = new File(localImgSavePath);
if (!imageFile.exists()) {
    imageFile.getParentFile().mkdirs();
    imageFile.createNewFile();
}
copy(file,imageFile);

/**

 *
 * @param source 輸入文件
 * @param target 輸出文件
 */
public static void copy(File source, File target) {
    FileInputStream fileInputStream = null;
    FileOutputStream fileOutputStream = null;
    try {
        fileInputStream = new FileInputStream(source);
        fileOutputStream = new FileOutputStream(target);
        byte[] buffer = new byte[1024];
        while (fileInputStream.read(buffer) > 0) {
            fileOutputStream.write(buffer);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (fileInputStream != null) {
                fileInputStream.close();
            }
            if (fileOutputStream != null) {
                fileOutputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
```


04.如何實現連續保存多張圖片

思路:循環子線程

可行(不推薦), 如果我要下載9個圖片,將子線程加入for循環內,并最終呈現。

有嚴重缺陷,線程延時,圖片順序不能做保證。如果是線程套線程的話,第一個子線程結束了,嵌套在該子線程f的or循環內的子線程還沒結束,從而主線程獲取不到子線程里獲取的圖片。

還有就是如何判斷所有線程執行完畢,比如所有圖片下載完成后,吐司下載完成。

不建議的方案

創建一個線程池來管理線程,關于線程池封裝庫,可以看線程池簡單封裝

這種方案不知道所有線程中請求圖片是否全部完成,且不能保證順序。

ArrayList images = new ArrayList<>();
for (String image : images){
    //使用該線程池,及時run方法中執行異常也不會崩潰
    PoolThread executor = BaseApplication.getApplication().getExecutor();
    executor.setName("getImage");
    executor.execute(new Runnable() {
        @Override
        public void run() {
            //請求網絡圖片并保存到本地操作
        }
    });
}

推薦解決方案

ArrayList images = new ArrayList<>();
ApiService apiService = RetrofitService.getInstance().getApiService();
//注意:此處是保存多張圖片,可以采用異步線程
ArrayList> observables = new ArrayList<>();
final AtomicInteger count = new AtomicInteger();
for (String image : images){
    observables.add(apiService.downloadImage(image)
            .subscribeOn(Schedulers.io())
            .map(new Function() {
                @Override
                public Boolean apply(ResponseBody responseBody) throws Exception {
                    saveIo(responseBody.byteStream());
                    return true;
                }
            }));
}
// observable的merge 將所有的observable合成一個Observable,所有的observable同時發射數據
Disposable subscribe = Observable.merge(observables).observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Consumer() {
            @Override
            public void accept(Boolean b) throws Exception {
                if (b) {
                    count.addAndGet(1);
                    Log.e("yc", "download is succcess");

                }
            }
        }, new Consumer() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                Log.e("yc", "download error");
            }
        }, new Action() {
            @Override
            public void run() throws Exception {
                Log.e("yc", "download complete");
                // 下載成功的數量 和 圖片集合的數量一致,說明全部下載成功了
                if (images.size() == count.get()) {
                    ToastUtils.showRoundRectToast("保存成功");
                } else {
                    if (count.get() == 0) {
                        ToastUtils.showRoundRectToast("保存失敗");
                    } else {
                        ToastUtils.showRoundRectToast("因網絡問題 保存成功" + count + ",保存失敗" + (images.size() - count.get()));
                    }
                }
            }
        }, new Consumer() {
            @Override
            public void accept(Disposable disposable) throws Exception {
                Log.e("yc","disposable");
            }
        });
        
        
        
private void saveIo(InputStream inputStream){
    String localImgSavePath = FileSaveUtils.getLocalImgSavePath();
    File imageFile = new File(localImgSavePath);
    if (!imageFile.exists()) {
        imageFile.getParentFile().mkdirs();
        try {
            imageFile.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    FileOutputStream fos = null;
    BufferedInputStream bis = null;
    try {
        fos = new FileOutputStream(imageFile);
        bis = new BufferedInputStream(inputStream);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = bis.read(buffer)) != -1) {
            fos.write(buffer, 0, len);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (bis != null) {
                bis.close();
            }
            if (fos != null) {
                fos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        //刷新相冊代碼省略……
    }
}

其他介紹 01.關于博客匯總鏈接

1.技術博客匯總

2.開源項目匯總

3.生活博客匯總

4.喜馬拉雅音頻匯總

5.其他匯總

02.關于我的博客

github:https://github.com/yangchong211

知乎:https://www.zhihu.com/people/...

簡書:http://www.jianshu.com/u/b7b2...

csdn:http://my.csdn.net/m0_37700275

喜馬拉雅聽書:http://www.ximalaya.com/zhubo...

開源中國:https://my.oschina.net/zbj161...

泡在網上的日子:http://www.jcodecraeer.com/me...

郵箱:yangchong211@163.com

阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV

segmentfault頭條:https://segmentfault.com/u/xi...

掘金:https://juejin.im/user/593943...

項目案例:https://github.com/yangchong2...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77733.html

相關文章

  • 小程序—九宮格心形拼圖

    摘要:而微信小程序中也剛好有進度條這個組件。推薦和意見反饋推薦給朋友意見反饋這個兩個功能就是用了,微信小程序的組件,這里需要注意的就是,在清除的默認樣式時,需要把的偽元素的邊框也去掉??偨Y這次做的這個九宮格心形拼圖的小程序,第一版已經上線了。 說明 前幾天在朋友圈看到好幾次這種圖片。 showImg(https://segmentfault.com/img/bVbeAoX?w=321&h=3...

    myeveryheart 評論0 收藏0

發表評論

0條評論

thursday

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<