倒霉的菜鸟

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

先看下结果:

 

 

 1 private val IMAGE_WIDTH = 200f.toPx
 2 private val IMAGE_MARGIN = 20f.toPx
 3 class PhotoView(context: Context, attributeSet: AttributeSet): View(context, attributeSet) {
 4 
 5     private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
 6 
 7     private val xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
 8 
 9     private val bonds = RectF(IMAGE_MARGIN,IMAGE_MARGIN,
10         IMAGE_MARGIN+ IMAGE_WIDTH, IMAGE_MARGIN+ IMAGE_WIDTH)
11     override fun onDraw(canvas: Canvas) {
12 
13         //因为下面是一个完全填充的白色的底板  所以看不出效果
14         //所以我们要用到离屏缓冲
15         //离屏缓冲的其中一个作用是帮我们抽出一块区域(透明背景)
16         //我们在离屏缓冲区去画,画完再贴回去
17         //需要提供离屏缓冲的区域,因为离屏缓冲比较消耗资源,所以应该尽可能小
18         val state = canvas.saveLayer(bonds, null)
19 
20         //这是画椭圆的方法, 之所以用这个方法画圆,是因为该方法可以传入矩形作为参数
21         //这样就方便我们让圆和矩形重合
22         canvas.drawOval(IMAGE_MARGIN, IMAGE_MARGIN,
23             IMAGE_MARGIN+ IMAGE_WIDTH, IMAGE_MARGIN+ IMAGE_WIDTH,
24         paint)
25 
26         paint.xfermode = xfermode
27         canvas.drawBitmap(getBitMap(IMAGE_WIDTH.toInt()),
28             IMAGE_MARGIN,
29             IMAGE_MARGIN,
30         paint)
31         paint.xfermode = null
32         //把离屏缓冲放回去, state:要恢复到之前的第几个状态
33         canvas.restoreToCount(state)
34     }
35 
36     //这里对取bitmap做了优化
37     //因为实际的图片像素可能很大,比如,1000, 10000, 像素越大,读取就越慢,越占内存
38     //但是我们需要的图片size是固定的,比如400
39     //options会帮助我们根据需要来读取图片
40     private fun getBitMap(width: Int): Bitmap{
41         //获取options对象
42         val options = BitmapFactory.Options()
43         //如果设置为true,decoder将返回null(没有bitmap),但out…字段仍将被设置,允许调用者查询bitmap而不必为其像素分配内存。
44         options.inJustDecodeBounds = true
45         //Synonym for opening the given resource and calling decodeResourceStream.
46         //相当于打开资源然后call decode, 但是该方法不一定返回Bitmap, 根据options的配置,它可能返回Null或只返回bitmap的size
47         //这一次只读size
48         BitmapFactory.decodeResource(resources,R.drawable.dogs, options)
49         options.inJustDecodeBounds = false
50 
51         //options.outWidth: 位图的结果宽度。如果justdecodebounds设置为false,这将是应用任何缩放后的输出位图的宽度。如果为真,它将是输入图像的宽度,而不考虑任何缩放。
52         //这个图片原来是多大
53         options.inDensity = options.outWidth
54         //我们需要的图片是多大
55         options.inTargetDensity = width
56         return BitmapFactory.decodeResource(resources, R.drawable.dogs, options)
57     }
58 }

 

posted on 2021-10-14 20:08  倒霉的菜鸟  阅读(54)  评论(0编辑  收藏  举报