淘先锋技术网

首页 1 2 3 4 5 6 7

Fresco相信大家都不陌生,是个很不错的图片加载器

最近做的需求有查看大图保存图片,保存图片很简单,但是保存gif图就需要处理一下了。

之前google了好久,也没有找到靠谱的答案,(还是API看的不够仔细 ~)

原理在Fresco 数据源和数据订阅者

因为是查看大图的时候保存图片,所以其实没有必要非从网络去下载图片了,内存or磁盘中可能已经有缓存,再去网络下载,显然是浪费用户的流量,所以我是这样做的。。。

情况一:

如果你的应用只有静态图片,那么

DataSource> dataSource1 = imagePipeline.fetchDecodedImage(imageRequest, null);dataSource1.subscribe(new BaseBitmapDataSubscriber() { @Override protected void onNewResultImpl(Bitmap bitmap) { //get bitmap } @Override protected void onFailureImpl(DataSource> dataSource) { }}, CallerThreadExecutor.getInstance());

情况二:

如果你的应用有静态图片也有动态图片(GIF)

DataSource> dataSource =

imagePipeline.fetchEncodedImage(imageRequest, null);

dataSource.subscribe(newBaseDataSubscriber>() {

@Override

protected voidonNewResultImpl(DataSource> dataSource) {

if(!dataSource.isFinished()) {

saveFail();

return;

}

CloseableReference ref = dataSource.getResult();

if(ref !=null) {

try{

PooledByteBuffer result = ref.get();

InputStream is =newPooledByteBufferInputStream(result);

try{

ByteArrayOutputStream bos =newByteArrayOutputStream(1000);

byte[] b =new byte[1000];

intn;

while((n = is.read(b)) != -1) {

bos.write(b,0,n);

}

is.close();

bos.close();

savePic(url,bos.toByteArray());//通过byte文件头,判断是否是gif,再做相应的命名处理

}catch(Exception e) {

}finally{

Closeables.closeQuietly(is);

}

}finally{

CloseableReference.closeSafely(ref);

ref =null;

}

}

}

@Override

protected voidonFailureImpl(DataSource> dataSource) {

saveFail();

}

},CallerThreadExecutor.getInstance());

总结

现在开源项目特别多,大家也都尽可能的不去重复造轮子,但是使用一个好的开源框架,最好还是了解一下源码的实现,这样在使用的过程中,遇到的任何问题,都有解释的依据。

情况一中,对图片做了解码处理,如果不想要解码,直接使用情况二的方式也是可以的。

8df12d7a0932

null是什么鬼

上图中的null是什么鬼

其实是需要传递的是context但是我们看源码

8df12d7a0932

simpleDraweeView.setImageURI(getImageUri(path)

发现我们在调用设置图片是,底层传递的就是null,所以为了避免我们的context被无法控制的第三方框架一直引用而引发内存泄露,我们这里还是不要把context传递过去了(毕竟不传,也没发现什么问题),至于为什么会有这个参数,还是要多看源码分析了。

保存到系统相册的问题

前面的保存,我们是保存到sd卡中我们自己的目录,但是如果要保存到系统相册,大部分使用的方式:

File file =newFile(filePath);

String uri =null;

String systemFilepath = filePath;

try{

uri = MediaStore.Images.Media.insertImage(context.getContentResolver(),file.getAbsolutePath(),"","");

systemFilepath =getFilePathByContentResolver(context,Uri.parse(uri));

MediaScannerConnection.scanFile(context, newString[]{systemFilepath}, null, null);

FileHelper.DataDir.deleteFileOrDir(file);

returnsystemFilepath;

}catch(Throwable e) {

}

这里有个问题,看源码

8df12d7a0932

insertImage

系统默认存储的是jpeg格式,这样如果保存GIF图就悲剧了。。。

开始我是想,拿到系统相册路径,手动保存,但是有两个问题

1、系统相册路径如何获取(不同rom存储的位置都不一样)

2、自己保存,缩略图怎么生成(系统保存到相册的的insertImage默认会保存一份缩略图)

目前这块我还没找到更好的方式处理,找到后一定要记录下来。。。

好了,我去写代码了。。。