關於緩存圖片時出現的Mark has been invalidated 問題

最近學習了一下圖片壓縮,雖然圖片壓縮的框架已經很成熟了,不過我以爲仍是有必要把原理說一下。html

壓縮圖片的原理很簡單,就是從網絡上獲取圖片,而後測量一下圖片的寬和高,而後再根據手機的寬高得出圖片的壓縮比例,而後用BitMapFactory將圖片壓縮就OK啦。數組

 

而後說Mark has been invalidated 問題,先把代碼附上:網絡

?框架

1學習

2url

3spa

43d

5code

6htm

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

URL url = new URL(str);

 

HttpURLConnection connection = (HttpURLConnection) url.openConnection(); //聯網操做

 

connection.setRequestMethod("GET");

 

connection.setConnectTimeout(5000);

 

connection.setReadTimeout(5000);

 

int responseCode = connection.getResponseCode();

 

 

 

InputStream is = connection.getInputStream(); //拿到輸入流

 

BufferedInputStream buf = new BufferedInputStream(is); //把輸入流轉換成Buffer

 

buf.mark(is.available);//由於須要二次讀流,這裏作一下標記

 

is.close();

 

buf.close();

 

data = baos.toByteArray();

 

options = new BitmapFactory.Options();

 

options.inJustDecodeBounds=true;

 

BitmapFactory.decodeStream(is,null,options);

 

outWidth = options.outWidth;

 

outHeight = options.outHeight;

 

System.out.println("寬是"+ outWidth +"高是"+ outHeight);

 

 

 

WindowManager manager = getWindowManager();

 

Display display = manager.getDefaultDisplay();

 

DisplayMetrics metrics = new DisplayMetrics();

 

display.getMetrics(metrics);

 

int heightPixels = metrics.heightPixels;//獲得手機的像素值

 

int widthPixels = metrics.widthPixels;

 

int scale = 1;

 

//拿到縮放比

 

if (outHeight>outWidth&&outHeight>heightPixels) {

 

scale = outHeight/heightPixels;

 

}else if (outWidth>outHeight&&outWidth>widthPixels){

 

scale = outWidth/heightPixels;

 

}else {

 

scale = 1;

 

}

 

buf.reset();//重置輸入流

 

 

 

options.inJustDecodeBounds=false;

 

options.inSampleSize=scale;

 

bitmap = BitmapFactory.decodeStream(buf,null,options);//壓縮圖片

 

iv.setImageBitmap(bitmap);//設置圖片

流程大概就是這個樣子,由於在讀流的時候須要讀兩次輸入流,在第一次讀完若是不mark一下,而且在第二次讀流的時候reset()一下,不然的話會什麼都讀不到圖片也搞不上去。可是寫完以後會出現這個問題。

加載中...

\

 

發現圖片的寬高已經有了,可是在壓縮圖片的時候卻出現了問題,這一句

\

加載中...

Mark has been invalidated.

這個標記已經失效

點到錯誤處

\

加載中...

 

 

發現是在reset()的時候發生了錯誤。

打印了一下is的長度,結果發現。。。。

\

莫名其妙啊,神經病啊,明明都已經聯網成功了圖片的寬高已經獲得了好嗎?搞什麼啊?

so.....我又在mark完成以後直接執行reset()操做,看一下能夠嗎

\加載中...

 

結果是。。。。。

\

加載中...

 

我有點方。。。

那麼。。。苦逼的在百度搜了一下,結果好像是說咱們在使用BitmapFactory.decodeStream()方法的時候會使流的mark方法無效,至因而什麼什麼緣由我也不是 很明 白,但有的人按照上面的代碼寫就能成功我也不是很清楚。。。。因此僅僅限於解決出現這個異常的狀況~說到這我想到了這麼一個圖

加載中...

\

好的言歸正傳。。。解決方法就是咱們在mark的時候直接給一個最大長度,也就是mark(1024*1024),給了一個固定的長度,這樣就能夠解決方法啦,不過僅限 於 1024*1024大小的圖片,若是超過這個大小的話,那麼咱們在獲取流的時候就會不能獲取到其全部的長度,會丟失數據,並且耗時較長,使用的時候須要注意。

 

其實還有另一種方法,就是把流轉換成byte數組,咱們使用BitmapFactory中的decodeByteArray方法,這樣咱們就不須要重置流了,並且數組也很好操做,附 上代 碼~~

\加載中...

加載中...

加載中...

\

 

\

 

醬紫就ok拉,其實使用方法和BufferedInputStream類似,不過不用mark也是感受舒服了好多~~~~

相關文章
相關標籤/搜索