【问题标题】:How to draw "crisp and sharp" lines on an low resolution ImageView?如何在低分辨率 ImageView 上绘制“清晰锐利”的线条?
【发布时间】:2020-09-29 00:38:19
【问题描述】:

我正在通过以下方式在 ImageView 上画线:

Bitmap imageBitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
Bitmap duplicateBitmap = Bitmap.createBitmap(imageBitmap.getWidth(),imageBitmap.getHeight(),Bitmap.Config.RGB_565);

Canvas targetCanvas = new Canvas(duplicateBitmap);
targetCanvas.drawBitmap(imageBitmap,0,0,null);
Paint paint = new Paint();
targetCanvas.drawLine(0f,100f, imageBitmap.getWidth(),100f,paint);
imageView.setImageDrawable(new BitmapDrawable(getResources(),duplicateBitmap));

这很好用when the Image has a decent or good resolution

但它看起来像这样when the image has a low resolution。 (这是一种糟糕的体验)

现在,如何在低分辨率图像上绘制清晰明快的线条?

有一次我认为我应该用高分辨率画布遮盖图像。但后来我对如何继续这个想法一无所知。此外,这可能是内存效率低下的实现。

【问题讨论】:

    标签: android canvas imageview paint resolution


    【解决方案1】:

    我终于想通了@D。 Karchnak 的指导......

    假设您的手机屏幕为 1080x1920,您创建的布局包含 全屏 ImageView,因此这个 ImageView 也是 1080x1920。现在 您将 .png 图像加载为 BitmapDrawable。这个PNG图像有一个 分辨率为 400x400,因此 BitmapDrawable 中的位图为 也是400x400。如果您将此“小”位图绘制到全屏 ImageView,它会因为分辨率低而变得模糊。如果你 在这个 400x400 位图上画一条线,这条线也会变得模糊 出去。这也是为什么它可以以体面或良好的分辨率工作的原因。

    我需要做的就是创建一个 android ImageView 的子类,然后将我的绘图逻辑转移到 onDraw 方法中(当然是在覆盖它之后)。像这样:

    public class FineLineImageView extends AppCompatImageView {
    
        public FineLineImageView(Context context) {
            this(context, null);
        }
    
        public FineLineImageView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public FineLineImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        protected void onDraw(final Canvas canvas) {
            super.onDraw(canvas);
            // logic for drawing goes here
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果您确实需要一个带有结果的位图,请确保 duplicateBitmap 的大小与您绘制它的 ImageView 的大小相同。

      如果您只需要在 ImageView 上绘制网格,我将创建一个自定义类,扩展 ImageView。覆盖它的draw(Canvas) 方法并使用提供的Canvas 来绘制网格。

      此代码如下所示:

      class GridImageView(context: Context....): ImageView(...) {
          val gridPaint = Paint() //Set color, strokeWidth etc...
      
          @Override
          fun onDraw(canvas: Canvas) {
             super.onDraw(canvas)
      
             //TODO - complex grid drawing here...
             canvas.drawLine(x1, y1, x2, y2, paint)
          }
      }
      

      【讨论】:

      • Bitmap duplicateBitmap = Bitmap.createBitmap(imageBitmap.getWidth(),imageBitmap.getHeight(),Bitmap.Config.RGB_565); 已经证明duplicateBitmap 与我正在绘制的ImageView 的大小相同。
      • 我不是 100% 确定 tbh,但我认为不会。它将新创建的位图大小(duplicateBitmap)设置为ImageView的位图drawable使用的位图大小,即原始位图图像的大小。
      • 那么您认为位图的大小与在图像上绘制“清晰”线条有何关系?
      • 假设你的手机屏幕是 1080x1920,你创建了一个全屏 ImageView 的布局,因此这个 ImageView 也是 1080x1920。现在您将 .png 图像加载为 BitmapDrawable。这个PNG图像的分辨率是400x400,因此BitmapDrawable里面的位图也是400x400。如果将这个“小”位图绘制到全屏 ImageView,由于分辨率低,它会变得模糊。如果你在这个 400x400 位图上画一条线,这条线也会变得模糊。这也是为什么它可以以体面或良好的分辨率工作的原因。
      • 该死,这样一个惊人的解释@D。卡奇纳克。脱帽致敬!!那么您认为我的用例可能的解决方案是什么?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 2017-05-28
      • 1970-01-01
      相关资源
      最近更新 更多