文档章节

关于缓存图片时出现的Mark has been invalidated 问题

shzwork
 shzwork
发布于 01/15 10:31
字数 1001
阅读 7
收藏 0

最近学习了一下图片压缩,虽然图片压缩的框架已经很成熟了,不过我觉得还是有必要把原理说一下。

压缩图片的原理很简单,就是从网络上获取图片,然后测量一下图片的宽和高,然后再根据手机的宽高得出图片的压缩比例,然后用BitMapFactory将图片压缩就OK啦。

 

然后说Mark has been invalidated 问题,先把代码附上:

?

1

2

3

4

5

6

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也是感觉舒服了好多~~~~

本文转载自:https://www.2cto.com/kf/201607/529640.html

shzwork

shzwork

粉丝 15
博文 958
码字总数 19235
作品 0
厦门
私信 提问
使用InputStream的markSupported、mark和reset

使用InputStream的markSupported、mark和reset mark用于标记地方,以后再调用reset时就可以再回到这个mark过的地方。 mark方法有个整型参数,意思是,在读出这么多个字符之前,保持mark有效。...

放个屁
2015/07/16
2.3K
0
Android开发高手课之内存优化

内存问题 异常 卡顿 :Java内存不足会导致频繁GC Android Bitmap内存分配的变化 Android 3.0之前,Bitmap放在Java堆,而像素数据放在Native内存中,如果不手动调用recycle,Bitmap Native内存...

小菜鸟程序媛
2019/03/06
0
0
访问日志静态文件,访问日志切割,静态元素过期时间

[toc] 一 访问日志不记录静态文件 很多网站大多为静态网页,网页内部的图片、css文件等同样有其网址链接,如果不设置,这些无效的信息也将被存入访问日志中,会导致访问日志文件大小快速增加...

夏为的Linux
2018/11/19
4
0
Universal-image-loader图片加载开源框架基本使用

universal-imageloader加载图片的特点: 基本特点如下, 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等 支持随意的配置ImageLoader,例如线程池,图片...

肖朝胜
2016/03/21
500
0
Android 图片三级缓存机制工具类封装

Android 图片三级缓存机制工具类封装 三级缓存分别是: 软引用SoftReference,cache在内存中 文件缓存在本地SDcard文件夹中,遇到文件名相同的图片则从本地取,且加入软引用中 从网络下载,并...

会飞柚子
2016/02/24
152
0

没有更多内容

加载失败,请刷新页面

加载更多

jsp web 大文件上传源代码

我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用。 首先我们需要了解的是上传文件三要素: 1.表单提交方式:post (get方式提...

东方雨
2分钟前
0
0
读懂这一篇,集群节点不下线

作者 | 声东 阿里云售后技术专家 导读:排查完全陌生的问题、完全不熟悉的系统组件,是售后工程师的一大工作乐趣,当然也是挑战。今天借这篇文章,跟大家分析一例这样的问题。排查过程中,需...

阿里巴巴云原生
8分钟前
31
0
如何让scss变量能够当做js变量来使用

如何让scss变量能够当做js变量来使用 当前我们使用scss变量有两个痛点: 需要手动导入 无法与js建立联系或者很难,后续不能在此基础上做一些骚操作 为了解决这两个问题,我们以创建js文件以j...

念其蔚蓝
18分钟前
43
0
Java日期加减

public static String getDate(String dateGiven,Integer day) throws Exception{ SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd"); Date date=sdf.parse(dateGiven);......

那个猩猩很亮
27分钟前
27
0
创龙TI TMS320C6748定点/浮点DSP C674xSD卡接口、拓展IO信号

TL138/1808/6748-EVM是广州创龙基于SOM-TL138/1808/6748核心板开发的一款开发板。由于SOM-TL138/1808/6748核心板管脚兼容,所以此三个核心板共用同一个底板。开发板采用核心板+底板的设计方式...

Tronlong创龙
27分钟前
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部