如何在低分辨率 ImageView 上绘制 "crisp and sharp" 条线?

How to draw "crisp and sharp" lines on an low resolution ImageView?

我正在通过执行以下操作在 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。 (这是一次糟糕的经历)

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

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

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

如果您只需要在 ImageView 上绘制网格,我会创建一个自定义 class,扩展 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)
    }
}

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

Let's say your phone's screen is 1080x1920, you create a layout with a fullscreen ImageView, therefore this ImageView is also 1080x1920. Now you load a .png image as a BitmapDrawable. This PNG image has a resolution of 400x400, therefore the bitmap inside BitmapDrawable is also 400x400. If you draw this "small" bitmap to a fullscreen ImageView, it will get blurred out, because of low resolution. If you draw a line to this 400x400 bitmap, this line will also get blurred out. That's also why it works with decent or good resolution.

我需要做的就是,创建一个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
    }
}