文章

Fresco规范说明

Fresco规范说明

使用Drawees

在XML中使用LocalSimpleDraweeView

示例给出了可以配置的各种选项

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
<com.example.LocalSimpleDraweeView
  android:id="@+id/my_image_view"
  android:layout_width="20dp"
  android:layout_height="20dp"
  fresco:fadeDuration="300" //显示动画时长
  fresco:actualImageScaleType="focusCrop"  //图片展示的scaleType
  fresco:placeholderImage="@color/wait_color" //占位图
  fresco:placeholderImageScaleType="fitCenter" //占位图的scaleType
  fresco:failureImage="@drawable/error"  //加载失败展示的图片
  fresco:failureImageScaleType="centerInside" //失败图的scaleType
  fresco:retryImage="@drawable/retrying"  //重试重新加载的图片
  fresco:retryImageScaleType="centerCrop"  //重试图片的scaleType
  fresco:progressBarImage="@drawable/progress_bar" //加载时显示的进度图片
  fresco:progressBarImageScaleType="centerInside" //进度图的scaleType
  fresco:progressBarAutoRotateInterval="1000" //跟随进度自动旋转的间隔
  fresco:backgroundImage="@color/blue"      //背景图
  fresco:overlayImage="@drawable/watermark"  //叠加图
  fresco:pressedStateOverlayImage="@color/red" //按压效果
  fresco:roundAsCircle="false"            //设置为圆形
  fresco:roundedCornerRadius="1dp"        //设置圆角弧度
  fresco:roundTopLeft="true"              //设置左上为圆角
  fresco:roundTopRight="false"            //右上圆角
  fresco:roundBottomLeft="false"          //左下圆角
  fresco:roundBottomRight="true"          //右下圆角
  fresco:roundingBorderWidth="2dp"  //设置圆环边框宽度
  fresco:roundingBorderColor="@color/border_color" //设置圆环边框颜色
  />

说明(重视) 0. 项目中统一使用LocalSimpleDraweeView,该类继承自SimpleDraweeView,所以基础api设置不变 1. 你必须声明 android:layout_width 和 android:layout_height。且不支持 wrap_content 属性。如果没有在XML中声明这两个属性,将无法正确加载图像 2. 只有希望显示固定的宽高比时,可以使用wrap_content ,例如 4:3,

可以在XML中指定: fresco:viewAspectRatio="1.33"。

也可以在代码中指定显示比例:mSimpleDraweeView.setAspectRatio(1.33f);

在JAVA代码中使用SimpleDraweeView

设置或更改要显示的图片,最简单的方法就是:

1
mSimpleDraweeView.setImageURI(uri)

规范自定义了LocalSimpleDraweeView,添加了常用设置API

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
//xml显示动画时长
 mSimpleDraweeView.setFadeDuration(200)

//图片展示的scaleType
mSimpleDraweeView.setActualImageScaleType(scaleType)

//占位图,占位图的scaleType
mSimpleDraweeView.setPlaceholderImage(drawable)
mSimpleDraweeView.setPlaceholderImage(drawable, scaleType);

//加载失败展示的图片,失败图的scaleType
mSimpleDraweeView.setFailureImage(drawable)
mSimpleDraweeView.setFailureImage(drawable, scaleType)

//重试重新加载的图片,重试图片的scaleType
mSimpleDraweeView.setRetryImage(drawable)
mSimpleDraweeView.setRetryImage(drawable, scaleType)

//背景图
mSimpleDraweeView.setBackgroundImage(drawable)

//设置为圆形
mSimpleDraweeView.setRoundAsCircle(true)

//设置圆角弧度
mSimpleDraweeView.setCornersRadius(10f)

FrescoUtils使用

利用DraweeHierarchy设置属性

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * 加载图片,并且指定图片大小
 *  draweeView 要设置的drawee控件
 *  uri:  加载图片uri
 *  width: 设置的宽度
 *  height: 设置的高度
 */
fun setImageRoundAsCircle(
    draweeView: SimpleDraweeView?,
    uri: Uri?,
    width: Int,
    height: Int
)

说明 1、对于同一个View,请不要多次调用setHierarchy,即使这个View是可回收的。创建 DraweeHierarchy 的较为耗时的一个过程,应该多次利用,下面为示例 2、一个DraweeHierarchy 是不可以被多个 View 共用的! 3、如果要改变所要显示的图片可使用setController 或者 setImageURI。

运行时修改DraweeHierarchy (重复利用原有DraweeHierarchy) LocalSimpleDraweeView扩展的设置项就是利用该属性复用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 //获取DraweeHierarchy 引用
val hierarchy = mSimpleDraweeView.hierarchy
//修改占位图
hierarchy.setPlaceholderImage(placeholderId)
hierarchy.setPlaceholderImage(placeholderDrawable)

//附加其他相关API
//设置加载失败占位图
hierarchy.setFailureImage(failureDrawable, ScalingUtils.ScaleType.CENTER)

// 改变图像的缩放类型//如果你选择缩放类型为 focusCrop,需要指定一个居中点:hierarchy.setActualImageFocusPoint(point);
hierarchy.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE)

//圆角
val roundingParams: RoundingParams = hierarchy.roundingParams
roundingParams?.setCornersRadius(10f)
//圆形roundingParams.setRoundAsCircle(true)
hierarchy.roundingParams = roundingParams

使用ControllerBuilder

加载图片除了setImageURI方法外,还可以通过设置DraweeController的setUri 来进行设置。

创建一个DraweeController, 然后传递图片加载请求给PipelineDraweeControllerBuilder. 随后就可以控制controller的其他选项了

1
2
3
4
5
6
7
/**
 * 使用ControllerBuilder加载图片,
 * 并更改图片宽高,等比适应屏幕宽度
 *  simpleDraweeView 要设置的drawee控件
 *  imagePath:  加载图片url
 */
fun setControllerListener(simpleDraweeView: SimpleDraweeView, imagePath: String?)

在指定一个新的controller的时候,使用setOldController,这可节省不必要的内存分配。

BlurPostprocessor(进阶用法)

使用后处理器(postprocessor) 进行图片后处理 实现 高斯模糊

1
2
3
4
5
6
/**
 * draweeView加载图片,并设置高斯模糊
 *  draweeView 要设置的drawee控件
 *  uri:  加载图片uri
 */
fun setImageNetworkBlurResource(draweeView: SimpleDraweeView?, uri: Uri?)

使用DataSource获取bitmap

1
2
3
4
5
6
7
/**
 * 使用DataSource获取bitmap
 * 回调结束后自动回收
 * url 加载图片url
 * load
 */
fun loadFrescoBitmap(url: String, loadResult: ((Bitmap?) -> Unit)? = null)

使用BaseBitmapDataSubscriber直接获取bitmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * 只想要Bitmap不想要别的
 * 使用 BaseBitmapDataSubscriber
 * 你可以直接在这里使用Bitmap,没有别的限制要求,也不需要回收(自动回收)
 *
 * 注意,这个数据源无法用来获取动图。
 * 你无法在onNewResultImpl之外的地方使用这个Bitmap。
 * 原因是BaseBitmapDataSubscriber数据源的获取结束之后,
 * image pipeline就会回收这个Bitmap。
 * 如果你此时再用它来显示,会报IllegalStateException!
 *
 */
fun loadFrescoBitmapOnly(
    url: String, loadResult: ((Bitmap?) -> Unit)? = null
)

从Bitmap缓存中立刻取到结果

一般需要先进行Bitmap预加载或者用以上方法加载缓存过Bitmap

1
2
3
4
5
6
7
8
9
10
11
12
/**
 * 预加载
 */
fun cacheFrescoImage(url: String)

/**
 * 预加载
 * cacheType :
 * 0 磁盘缓存
 * 1 内存缓存
 */
fun cacheFrescoImage(url: String, cacheType: Int)

从Bitmap缓存中立刻取到结果

1
2
3
4
5
/**
 * 从Bitmap缓存中立刻取到结果,
 * 不像其他缓存,如果[图片在内存缓存]中有的话,可以在UI线程立刻拿到结果
 */
fun getBitmapFromCache(url: String, loadResult: ((Bitmap?) -> Unit)? = null)

下载存储未解码的图片到本地,比如gif

此方法只回传得到的数据流,可以根据需求自己处理得到的流

1
2
3
4
5
6
7
8
/**
 * 加载未解码的图片,比如gif
 * fetchEncodedImage得到DataSource<CloseableReference<PooledByteBuffer>>
 * 得到数据流可以用来存储
 */
fun fetchEncodedImage(
    context: Context, url: String, saveCallBack: ((ImageFormat, InputStream) -> Unit)? = null
)

附完整FrescoUtils源码以及使用示例

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
import android.graphics.Bitmap
import android.graphics.drawable.Animatable
import android.net.Uri
import android.text.TextUtils
import android.util.Log
import com.facebook.common.executors.CallerThreadExecutor
import com.facebook.common.internal.Closeables
import com.facebook.common.memory.PooledByteBuffer
import com.facebook.common.memory.PooledByteBufferInputStream
import com.facebook.common.references.CloseableReference
import com.facebook.datasource.BaseDataSubscriber
import com.facebook.datasource.DataSource
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.backends.pipeline.PipelineDraweeController
import com.facebook.drawee.controller.BaseControllerListener
import com.facebook.drawee.interfaces.DraweeController
import com.facebook.drawee.view.SimpleDraweeView
import com.facebook.imageformat.ImageFormat
import com.facebook.imageformat.ImageFormatChecker
import com.facebook.imagepipeline.core.DefaultExecutorSupplier
import com.facebook.imagepipeline.image.CloseableAnimatedImage
import com.facebook.imagepipeline.image.CloseableBitmap
import com.facebook.imagepipeline.image.CloseableImage
import com.facebook.imagepipeline.image.ImageInfo
import com.facebook.imagepipeline.request.ImageRequest
import com.facebook.imagepipeline.request.ImageRequestBuilder
import com.facebook.imagepipeline.request.Postprocessor
import jp.wasabeef.fresco.processors.BlurPostprocessor
import java.io.InputStream

/**
 * Created by Akkun on 2023/11/09.
 * Des:
 */
object FrescoUtils {

    /**
     * 使用ControllerBuilder加载图片,url
     * 并更改图片宽高,等比适应屏幕宽度
     * draweeWidth:要显示的宽度,
     */
    @JvmStatic
    fun setDraweeFixedImage(simpleDraweeView: SimpleDraweeView?, imagePath: String?, draweeWidth:Int) {
        if (simpleDraweeView == null || TextUtils.isEmpty(imagePath)) {
            return
        }
        val layoutParams = simpleDraweeView.layoutParams
        val controllerListener = object : BaseControllerListener<ImageInfo?>() {
            override fun onFinalImageSet(id: String, imageInfo: ImageInfo?, anim: Animatable?) {
                if (imageInfo == null) {
                    return
                }
                val height = imageInfo.height
                val width = imageInfo.width
                layoutParams.width = draweeWidth
                layoutParams.height =
                    ((layoutParams.width * height).toFloat() / width.toFloat()).toInt()
                simpleDraweeView.layoutParams = layoutParams
                simpleDraweeView.setImageURI(imagePath)
            }

            override fun onIntermediateImageSet(id: String, imageInfo: ImageInfo?) {
                Log.d("TAG", "Intermediate image received")
            }

            override fun onFailure(id: String, throwable: Throwable) {
                throwable.printStackTrace()
            }
        }
        val controller: DraweeController = Fresco.newDraweeControllerBuilder()
            .setUri(Uri.parse(imagePath))
            .setControllerListener(controllerListener)
            .setOldController(simpleDraweeView.controller)
            .setAutoPlayAnimations(true)
            .build()
        simpleDraweeView.controller = controller
    }

    /**
     * draweeView加载图片,并设置高斯模糊
     */
    @JvmStatic
    fun setImageBlurResource(draweeView: SimpleDraweeView?, uri: Uri?) {
        if (uri == null || draweeView == null) {
            return
        }
        val processor: Postprocessor = BlurPostprocessor(draweeView.context, 25)
        val request = ImageRequestBuilder.newBuilderWithSource(uri)
            .setPostprocessor(processor)
            .build()
        val controller = Fresco.newDraweeControllerBuilder()
            .setImageRequest(request)
            .setOldController(draweeView.controller)
            .setAutoPlayAnimations(true)
            .build() as PipelineDraweeController
        draweeView.controller = controller
    }

    /**
     * 获取bitmap
     * 使用DataSource回调结束后自动回收
     */
    @JvmStatic
    fun loadFrescoBitmap(
        url: String, resolveBitmap: ((Bitmap?) -> Bitmap?)? = null, loadResult: ((Bitmap?) -> Unit)? = null
    ) {
        if (TextUtils.isEmpty(url)) {
            Log.e("FrescoUtils", "loadFrescoBitmap url isEmpty")
            loadResult?.invoke(null)
            return
        }
        Log.e("FrescoUtils", "loadFrescoBitmap cacheFrescoImage: $url")
        try {
            val imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
                .setProgressiveRenderingEnabled(true).build()
            val imagePipeline = Fresco.getImagePipeline()
            val dataSource =
                imagePipeline.fetchDecodedImage(imageRequest, CallerThreadExecutor.getInstance())
            dataSource.subscribe(object : BaseDataSubscriber<CloseableReference<CloseableImage>>() {
                override fun onNewResultImpl(source: DataSource<CloseableReference<CloseableImage>>) {
                    Log.e("FrescoUtils", "loadFrescoBitmap success: $url")
                    if (!source.isFinished) {
                        loadResult?.invoke(null)
                        return
                    }

                    val imageReference = source.result
                    if (imageReference != null) {
                        try {
                            //最终返回的bitmap
                            var outBitmap: Bitmap? = null

                            //初始请求到的bitmap
                            var bitmap: Bitmap? = null

                            val closeableImage = imageReference.get()
                            //动图处理
                            if (closeableImage is CloseableAnimatedImage) {
                                val animatedImageResult = closeableImage.imageResult
                                if (animatedImageResult != null && animatedImageResult.image != null) {
                                    val imageWidth = animatedImageResult.image.width
                                    val imageHeight = animatedImageResult.image.height
                                    val bitmapConfig = Bitmap.Config.ARGB_8888
                                    val tmpBitmap = Bitmap.createBitmap(
                                        imageWidth,
                                        imageHeight,
                                        bitmapConfig
                                    )
                                    animatedImageResult.image.getFrame(0)
                                        .renderFrame(imageWidth, imageHeight, tmpBitmap)
                                    bitmap = tmpBitmap
                                }
                            }
                            //非动图处理
                            if (closeableImage is CloseableBitmap) {
                                bitmap = closeableImage.underlyingBitmap
                            }

                            if (bitmap == null || bitmap.isRecycled || bitmap.height == 0 || bitmap.width == 0) {
                                outBitmap = null
                            } else {
                                // 中间处理过的bitmap
                                if (resolveBitmap != null) {
                                    val bitmap2 = resolveBitmap.invoke(bitmap)
                                    if (bitmap2 == null || bitmap2.isRecycled || bitmap.height == 0 || bitmap.width == 0) {
                                        outBitmap = null
                                    }else {
                                        outBitmap = bitmap2
                                    }
                                } else {
                                    outBitmap = bitmap
                                }
                            }
                            try {
                                loadResult?.invoke(outBitmap)
                            } catch (e1 : Exception) {
                                e1.printStackTrace()
                            }
                        } catch (e: Exception) {
                            loadResult?.invoke(null)
                            e.printStackTrace()
                        } finally {
                            CloseableReference.closeSafely(imageReference);
                        }
                    } else {
                        loadResult?.invoke(null)
                    }
                }

                override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
                    Log.e("FrescoUtils", "loadFrescoBitmap fail: $url")
                    loadResult?.invoke(null)
                }
            }, CallerThreadExecutor.getInstance())
        } catch (e: Exception) {
            loadResult?.invoke(null)
            e.printStackTrace()
        }
    }

    /**
     * 图片预加载
     * cacheType :
     * 0 磁盘缓存
     * 1 内存缓存
     * 不使用此方法
     */
    @JvmStatic
   fun cacheFrescoImage(url: String, cacheType: Int) {
        val imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
            .setProgressiveRenderingEnabled(true).build()
        val imagePipeline = Fresco.getImagePipeline()

        if (cacheType == 1) {
            imagePipeline.prefetchToBitmapCache(imageRequest, CallerThreadExecutor.getInstance())
        } else {
            imagePipeline.prefetchToDiskCache(imageRequest, CallerThreadExecutor.getInstance())
        }
    }

    /**
     * 预加载
     */
    @JvmStatic
    fun cacheFrescoImage(url: String) {
        if (TextUtils.isEmpty(url)) {
            Log.e("FrescoUtils", "cacheFrescoImage url isEmpty")
            return
        }
        Log.e("FrescoUtils", " cacheFrescoImage: $url")
        try {
            val uri = Uri.parse(url)
            val imagePipeline = Fresco.getImagePipeline()
            val imageRequest = ImageRequest.fromUri(uri)
            val source = imagePipeline.fetchDecodedImage(imageRequest, this)
            source.subscribe(object : BaseDataSubscriber<CloseableReference<CloseableImage>>() {
                override fun onNewResultImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
                    Log.e("FrescoUtils", "cacheFrescoImage success: $url")
                    source.close()
                }

                override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
                    Log.e("FrescoUtils", "cacheFrescoImage fail: $url")
                    source.close()
                }
            }, CallerThreadExecutor.getInstance())
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 从Bitmap缓存中立刻取到结果,
     * 不像其他缓存,如果[图片在内存缓存]中有的话,可以在UI线程立刻拿到结果
     */
    @JvmStatic
    fun getBitmapFromCache(
        url: String, resolveBitmap: ((Bitmap?) -> Bitmap?)? = null, loadResult: ((Bitmap?) -> Unit)? = null
    ) {
        if (TextUtils.isEmpty(url)) {
            Log.e("FrescoUtils", "getBitmapFromCache url isEmpty")
            loadResult?.invoke(null)
            return
        }
        val imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
            .setProgressiveRenderingEnabled(true).build()
        val dataSource = Fresco.getImagePipeline()
            .fetchDecodedImage(imageRequest, CallerThreadExecutor.getInstance())

        try {
            val imageReference = dataSource.result
            if (imageReference == null) {
                Log.e("FrescoUtils", "getBitmapFromCache result isEmpty")
                loadResult?.invoke(null)
                return
            }
            try {
                var outBitmap: Bitmap? = null
                val image = imageReference.get() as CloseableBitmap
                val bitmap = image.underlyingBitmap
                if (bitmap.isRecycled || bitmap.height == 0 || bitmap.width == 0) {
                    outBitmap = null
                } else {
                    if (resolveBitmap != null) {
                        val bitmap2 = resolveBitmap.invoke(bitmap)
                        if (bitmap2 == null || bitmap2.isRecycled || bitmap.height == 0 || bitmap.width == 0) {
                            outBitmap = null
                        } else {
                            outBitmap = bitmap2
                        }
                    } else {
                        outBitmap = bitmap
                    }
                }
                try {
                    loadResult?.invoke(outBitmap)
                } catch (e1 : Exception) {
                    e1.printStackTrace()
                }
            } catch (e: Exception) {
                loadResult?.invoke(null)
                e.printStackTrace()
            } finally {
                CloseableReference.closeSafely(imageReference);
            }
        } catch (e: Exception) {
            loadResult?.invoke(null)
            e.printStackTrace()
        } finally {
            dataSource.close()
        }

    }

    /**
     * 加载未解码的图片,比如gif
     * fetchEncodedImage得到DataSource<CloseableReference<PooledByteBuffer>>
     * 得到数据流可以用来存储
     */
    @JvmStatic
    fun fetchEncodedImage(
        url: String, loadResult: ((ImageFormat?, InputStream?) -> Unit)? = null
    ) {
        if (TextUtils.isEmpty(url)) {
            Log.e("FrescoUtils", "fetchEncodedImage url isEmpty")
            loadResult?.invoke(null, null)
            return
        }
        val imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
            .setProgressiveRenderingEnabled(true).build()
        val dataSource = Fresco.getImagePipeline()
            .fetchEncodedImage(imageRequest, CallerThreadExecutor.getInstance())
        dataSource.subscribe(object : BaseDataSubscriber<CloseableReference<PooledByteBuffer>>() {
            override fun onNewResultImpl(dataSource: DataSource<CloseableReference<PooledByteBuffer>>) {
                val imageReference = dataSource.result
                if (imageReference == null) {
                    loadResult?.invoke(null, null)
                    return
                }
                val pooledByteBuffer:PooledByteBuffer = imageReference.get()

                if (pooledByteBuffer == null) {
                    loadResult?.invoke(null, null)
                    return
                }
                val inputStream: InputStream = PooledByteBufferInputStream(pooledByteBuffer)
                try {
                    val imageFormat = ImageFormatChecker.getImageFormat(inputStream)
                    try {
                        loadResult?.invoke(imageFormat, inputStream)
                    } catch (e1 : Exception) {
                        e1.printStackTrace()
                    }
                } catch (e: Exception) {
                    loadResult?.invoke(null, null)
                    e.printStackTrace()
                } finally {
                    Closeables.closeQuietly(inputStream)
                }
            }

            override fun onFailureImpl(dataSource: DataSource<CloseableReference<PooledByteBuffer>>) {
                Log.e("FrescoUtils", "loadSaveGifImg fail: $url")
                loadResult?.invoke(null, null)
            }
        }, DefaultExecutorSupplier(2).forBackgroundTasks())
    }

}

使用示例

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  fun viewLoadUrl(view: View) {
        val url =
            "https://img0.baidu.com/it/u=937072262,2445742246&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800"
        mySimpleDraweeView.setImageURI(url)

    }

    fun viewLoadGifUrl(view: View) {
        val gifUrl = "https://img.soogif.com/EHAUXTeWgQ0QJWDdXG9qcYTh8LSqPzma.gif"
        mySimpleDraweeView.setImageURI(gifUrl)
    }


    fun reset(view: View) {
        mySimpleDraweeView.reset()
    }

    fun frescoPlaceHold(view: View) {
        //为展示效果先重置取消图片展示
        mySimpleDraweeView.hierarchy.reset()

        mySimpleDraweeView.setPlaceholderImage(
            R.mipmap.ic_launcher, ScalingUtils.ScaleType.FIT_CENTER
        )
        mySimpleDraweeView.postDelayed({
             val url = "https://img1.baidu.com/it/u=2357261653,1275119252&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800"
            mySimpleDraweeView.setImageURI(url)
        },1000)
    }

    fun frescoLoadCircle(view: View) {
        val url = "https://img1.baidu.com/it/u=810004027,3534540793&fm=253&fmt=auto&app=138&f=JPEG?w=632&h=269"
        mySimpleDraweeView.setImageURI(url,200,200)
        mySimpleDraweeView.setRoundAsCircle(true)
    }

    private fun dp2px(dpVal: Float): Int {
        return TypedValue.applyDimension(
            1,
            dpVal,
            resources.displayMetrics
        ).toInt()
    }
    fun frescoLoadFixed(view: View) {
        val url = "https://img0.baidu.com/it/u=1188128476,2692382549&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500"
        val widthPixels = resources.displayMetrics.widthPixels - dp2px(10f) * 2
        FrescoUtils.setDraweeFixedImage(mySimpleDraweeView, url, widthPixels)

    }

    fun frescoLoadBlur(view: View) {
        val url = "https://img1.baidu.com/it/u=810004027,3534540793&fm=253&fmt=auto&app=138&f=JPEG?w=632&h=269"
        FrescoUtils.setImageBlurResource(mySimpleDraweeView, Uri.parse(url))
    }

    fun frescoLoadBitmap(view: View) {
        val url = "https://img0.baidu.com/it/u=1525818566,3553142770&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
//        val url =  "https://img.soogif.com/EHAUXTeWgQ0QJWDdXG9qcYTh8LSqPzma.gif"
        FrescoUtils.loadFrescoBitmap(url,null) {
            it?.let {
                runOnUiThread {
                    ivBitmap.setImageBitmap(it)
                }
            }
        }
    }

    val arrayList = ArrayList<ScalingUtils.ScaleType>().apply {
        add(ScalingUtils.ScaleType.FIT_XY)
        add(ScalingUtils.ScaleType.FIT_X)
        add(ScalingUtils.ScaleType.FIT_Y)
        add(ScalingUtils.ScaleType.FIT_START)
        add(ScalingUtils.ScaleType.FIT_CENTER)
        add(ScalingUtils.ScaleType.FIT_END)
        add(ScalingUtils.ScaleType.CENTER)
        add(ScalingUtils.ScaleType.CENTER_INSIDE)
        add(ScalingUtils.ScaleType.CENTER_CROP)
        add(ScalingUtils.ScaleType.FOCUS_CROP)
        add(ScalingUtils.ScaleType.FIT_BOTTOM_START)
    }
    private var count = 0
    fun frescoScaleType(view: View) {
        val urlString =  "https://i5.3conline.com/images/piclib/201103/23/batch/1/89463/13008568150802t0bjcuuwr_medium.jpg"
        mySimpleDraweeView.setImageURI(urlString)
        mySimpleDraweeView.setActualImageScaleType(arrayList[count])
        count++
        count %= (arrayList.size)
    }

    private fun test() {
        //   simpleDraweeView.setImageURI(url)

//        val mp4File = File(externalCacheDir, "a.mp4")
//        simpleDraweeView.setImageURI(Uri.fromFile(mp4File), this)
//
//        simpleDraweeView.setImageURI("https://www.w3school.com.cn/example/html5/mov_bbb.mp4")
//
//        simpleDraweeView.setImageURI("content://media/external/images/media/2440") //图片
//        simpleDraweeView.setImageURI("content://media/external/video/media/2469")  //视频

//        val gifUrl = "content://media/external/video/media/2469"
        val gifUrl = "http://5b0988e595225.cdn.sohucs.com/images/20190116/01728acd564c4850a5b25de9e1d810d9.gif"
//        FrescoUtils.setDraweeViewNetworkResource(simpleDraweeView, Uri.parse(gifUrl))

//      FrescoUtils.setImageRoundAsCircle(this@MainActivity,simpleDraweeView, Uri.parse(highResolutionH),300,240)

    }

    fun frescoCacheBitmap(view: View) {
        var url =
            "https://img1.baidu.com/it/u=2335918048,414691798&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500"
        FrescoUtils.cacheFrescoImage(url)
    }
    fun frescoLoadBitmapCache(view: View) {
        var url = "https://img1.baidu.com/it/u=2335918048,414691798&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500"
        FrescoUtils.getBitmapFromCache(url,null) {
            it?.let {
//                runOnUiThread {
                    ivBitmap.setImageBitmap(it)
//                }
            }
        }
    }
本文由作者按照 CC BY 4.0 进行授权