关于缓存图片时出现的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也是感受舒服了好多~~~~

相关文章
相关标签/搜索