天天看点

RoundImageView圆角图片模糊锯齿问题RoundImageView圆角图片模糊锯齿问题

RoundImageView圆角图片模糊锯齿问题

使用RoundImageView时遇到了显示出来的圆角图片出现模糊锯齿的情况,而这种模糊只会在hdpi的机器上出现。

下面记录一下使用场景和出现问题的路径:

  1. 页面上有一张220x220的图片,源文件放在xxhdpi目录下
  2. 控件使用的是开源库RoundImageView
  3. 控件的宽高做了3种dpi设备的适配,xxhdpi目录下110dp,xhdpi目录下98dp,hdpi目录下87dp
  4. hdpi的设备从xxhdpi目录拿出来的图片资源会压缩一倍,图片大小为110x110
  5. 而控件的大小根据density公式计算实际为 87 * 1.5 = 130.5 即 131x131
  6. 可以看到图片大小实际上比控件大小要小,在RoundImageView渲染圆角时会通过Shader对图片进行放大
  7. 但Shader对图片的放大会造成锯齿模糊效果,网上大多数第三方圆角方法都是在Shader中对图片进行缩放

解决方法:

  1. 对不同dpi设备单独适配资源图片,图片size跟dimens对应,可以避免图片放大压缩导致的失真锯齿问题,图片多的情况下包体积会增大很多
  2. 依然用一套资源图片,xxhdpi的资源图片进行放大处理,对于上述例子只要把图片资源扩大到270x270,在hdpi机器上图片大小为135x135,跟控件大小相差不大,不会出现放大锯齿的问题,缺点依然是会稍微增大包体积,并且不能使用wrap_content作为控件的宽高
  3. 在bitmap传入之前RoundImageView之前对bitmap进行缩放处理,可以避免RoundImageView内部使用shader进行缩放出现锯齿的问题。缺点是依然会稍微模糊,但可以解决锯齿问题。
    float widthScale = outWidth * f / bitmap.getWidth();
    float heightScale = outHeight * f / bitmap.getHeight();
    bitmap = Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * widthScale), (int) (bitmap.getHeight() * heightScale), true);
    //后续使用上面的bitmap继续做圆角图片处理
               
  4. 使用google官方support包的RoundedBitmapDrawable做圆角图片处理,不会出现模糊锯齿问题,且可以使用原生ImageView作为图片控件,推荐使用该方法。
    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.test);
    RoundedBitmapDrawable roundedDrawable = RoundedBitmapDrawableFactory.create(getResources(),bmp);
    // 设置图片圆角
    roundedDrawable.setCornerRadius();
    imageView.setImageDrawable(R.id.image, roundedDrawable);