如何使用画布在ImageView上绘制不受缩放或缩放影响的线条? [英] How to draw lines on an ImageView using canvas which are unaffected by zooming or scaling?

查看:66
本文介绍了如何使用画布在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();
    paint.setColor(Color.RED);
    paint.setStrokeWidth(3f);
    targetCanvas.drawLine(0f,100f, imageBitmap.getWidth(),100f,paint);
    imageView.setImageDrawable(new BitmapDrawable(getResources(),duplicateBitmap));

不放大时看起来还可以。

但当我放大时,线条变粗了。(这是预期行为)

现在,如何在图像视图上绘制线条,以便在用户放大线条粗细时不受影响?

附注:我尝试先放大图像,然后在图像上绘制线条。(在点击按钮或其他事情时)。但这并没有奏效,这条线仍然很粗。

我还发现,当图像的分辨率较低时,绘制的线条会较粗。因此,我假设在图像上绘图也与图像分辨率有关。

我想用高分辨率画布来屏蔽ImageView,但这会降低内存效率。此外,我也不知道如何实际实现这一点。

我不知何故相信this question的答案可以解决我的问题。

推荐答案

正确的方法是使用视图画布动态呈现线条,而不是放入位图本身。

您的实现失败的原因是,如果您将网格直接呈现到位图中,那么您实际上是在更改位图像素,因此从逻辑上讲,如果您缩放位图,则网格像素也将缩放,因为所有位图+网格都变成了相同的单个图像

一种解决方案可以是使用任何现成的缩放图像查看小部件。您将在GitHub中找到许多内容,例如:

ZoomImageView

然后您有两个选择:扩展小部件以创建您自己的子类,或者直接在小部件代码中执行实现。由你决定。

在这两种情况下,您需要做的是覆盖其onDraw回调,并在Super.onDraw(Canvas)调用之后立即执行网格绘制。 无需创建新的位图或新的画布实例。使用该方法的画布执行绘制。

@Override
protected void onDraw(final Canvas canvas) {
    
    super.onDraw(canvas);

    // Render the grid

    final int slotWidth  = this.getWidth() / 3;
    final int slotHeight = this.getHeight() / 3;

    this.paint.setColor(this.gridColor);

    // Horizontal lines
    canvas.drawLine(0, slotHeight, this.getWidth(), slotHeight, this.paint);
    canvas.drawLine(0, (slotHeight * 2), this.getWidth(), (slotHeight * 2), this.paint);

    // Vertical lines
    canvas.drawLine(slotWidth, 0, slotWidth, this.getHeight(), this.paint);
    canvas.drawLine((slotWidth * 2), 0, (slotWidth * 2), this.getHeight(), this.paint);
}

注意,避免在onDraw方法中创建新对象,例如Paint实例等,因为onDraw可以在短时间内被多次调用。无论如何,林特都应该警告你这一点。切勿在onDraw、onMeasure等方法中创建新的对象实例,因为此类方案总是预先缓存/重复使用它们。

一个更简单的替代方法是扩展一个视图并创建一个新的专用网格视图小部件,与实际的Zoom Image View无关。执行相同的操作,因此也覆盖上面的示例中的onDraw方法,并呈现网格,如图所示。然后将此新视图放入布局设计中,恰好放在Zoom Image View控件的顶部,确保两个控件具有相同的度量值。

这篇关于如何使用画布在ImageView上绘制不受缩放或缩放影响的线条?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆