Fresco结合PhotoView实现手势缩放
2016-05-25 本文已影响3999人
盛夏的阳光
项目中需要用到手势缩放,所以查找了一些Demo,特作此笔记。
(第一次写正式的笔记,文笔不佳,请见谅(~ ̄▽ ̄)~)
笔者查看到的几个项目,都是使用自定义控件,一个是ImagePipeline结合PhotoView,一个是使用SimpleDraweeView结合PhotoView,因此下文主要介绍这两种方法。
1. ImagePipeline结合PhotoView
-
自定义PhotoView继承ImageView:如PhotoView.java
显示图片的主要代码块:
public void setImageUri(Uri uri) {ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(uri).build(); ImagePipeline imagePipeline = Fresco.getImagePipeline(); final DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, this); DraweeController controller = Fresco.newDraweeControllerBuilder() .setOldController(mDraweeHolder.getController()) .setImageRequest(imageRequest) .setControllerListener(new BaseControllerListener<ImageInfo>() { @Override public void onFinalImageSet(String s, @Nullable ImageInfo imageInfo, @Nullable Animatable animatable) { try { // Do something with the image, but do not keep the reference to it! // The image may get recycled as soon as the reference gets closed below. // If you need to keep a reference to the image, read the following sections. imageReference = dataSource.getResult(); if (imageReference != null) { CloseableImage image = imageReference.get(); if (image != null && image instanceof CloseableStaticBitmap) { CloseableStaticBitmap closeableStaticBitmap = (CloseableStaticBitmap) image; Bitmap bitmap = closeableStaticBitmap.getUnderlyingBitmap(); if (bitmap != null) { //这里可以对bitmap进行操作 setImageBitmap(bitmap); } } } } finally { dataSource.close(); CloseableReference.closeSafely(imageReference); } } }) .setTapToRetryEnabled(true) .build(); mDraweeHolder.setController(controller);}
- 在.xml文件中使用
<com.carrie.fresco.PhotoView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
/> - 在Activity中
PhotoView photoView = (PhotoView) findViewById(R.id.iv_img);
photoView.setImageUri("http://chinaplasonline.com/CPS15/Files/image/CPS16_Overall_Layout_Plan_20150825.jpg");
这样就实现了手势缩放。
参考
2. SimpleDraweeView结合PhotoView
- 自定义PhotoDraweeView继承SimpleDraweeView,实现IAttacher接口
- 在xml中
<me.relex.photodraweeview.PhotoDraweeView
android:id="@+id/photo_drawee_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/> - 在Activity中
PipelineDraweeControllerBuilder controller = Fresco.newDraweeControllerBuilder();
controller.setUri(Uri.parse("res:///" + R.drawable.panda));
controller.setOldController(mPhotoDraweeView.getController());
// You need setControllerListener
controller.setControllerListener(new BaseControllerListener<ImageInfo>() {
@Override
public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
super.onFinalImageSet(id, imageInfo, animatable);
if (imageInfo == null || mPhotoDraweeView == null) {
return;
}
mPhotoDraweeView.update(imageInfo.getWidth(), imageInfo.getHeight());
}
});
mPhotoDraweeView.setController(controller.build());
这样就实现了SimpleDraweeView的手势缩放。
参考Demo:
PhotoDraweeView
3.修改图片,实现缩放
由于笔者项目中需要实现的是,一张图片上添加另一张小图片,再实现缩放,见如下效果:
QQ截图20160525163243.png需要修改Demo中的代码,Fresco的文档中写到修改图片的方法如下:
Modifying the Image (Postprocessing) QQ截图20160525163645.png
主要修改图片的操作在process()方法中
因此,修改上述两种方法中的图片:
1. ImagePipeline
- 在自定义的PhotoView类中:
找到上面让图片显示的代码,添加:
但是在部分机型上会报IllegalStateException错误,解决办法:
bitmap=bitmap.copy(Config.ARGB_4444, true);
不过这样的话,图片占用内存又增大了,Google一下,有一种解决方法是直接在JNI操作,但是我自己没有仔细研究AndroidJniBitmapOperations
2.SimpleDraweeView
- 自定义的控件无需更改,直接在Activity中修改:
mPhotoDraweeView = (PhotoDraweeView) findViewById(R.id.photo_drawee_view);
Postprocessor redMeshPostprocessor = new BasePostprocessor() {
@Override
public String getName() {
return "redMeshPostprocessor";
}
@Override
public void process(Bitmap bitmap) {
Bitmap blueBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_blue);
Bitmap redBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_red);
Bitmap adBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_star);
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(blueBitmap, 50, 50, null);
canvas.drawBitmap(redBitmap, 200,200, null);
canvas.drawBitmap(adBitmap, 300, 300, null);
}
};
其余代码不变。这样就完成了 修改图片+手势缩放。用这种方法,即使在第一种方法中报IllegalStateException错的2.3.7机型,也没有报错。
题外话
写了几个小时,终于把这篇篇幅不长的文章磕磕绊绊写完了y(๑•̀ㅂ•́)و✧
手生,还是得多写多记录,看花容易画花难呀~( ̄▽ ̄~)(~ ̄▽ ̄)~