问题描述
我通过执行以下操作在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,null);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setstrokeWidth(3f);
targetCanvas.drawLine(0f,100f,imageBitmap.getWidth(),paint);
imageView.setimageDrawable(new BitmapDrawable(getResources(),duplicateBitmap));
未放大时看起来还可以。
但是当我放大时,线条变粗了。 (这是预期的行为)
现在,如何在图像视图上绘制线条,以使用户放大时线条的粗细不受影响?
P.S:我先尝试“放大”图像,然后在图像上绘制线条。 (点击按钮或其他方式)。但这没有用,线仍然很粗。
我还发现,当图像分辨率较低时,绘制的线条会更粗。因此,我认为在图像上绘图也与图像分辨率有关。
我当时想用高分辨率画布遮盖ImageView,但这会降低内存效率。另外,我对如何真正实现这一点一无所知。
我以某种方式相信this question的答案可以解决我的问题。
解决方法
正确的方法是使用View画布动态渲染线条,而不是渲染到位图本身。
实现失败的原因是,如果直接将栅格渲染到位图中,则实际上是在更改位图像素,因此从逻辑上讲,如果缩放位图,则栅格像素也将缩放,如所有的位图+网格都变成了同一张图片。
解决方案可以是使用任何现成的缩放图像视图小部件。您会在GitHub中找到很多东西,例如:
然后,您有2个选项,可以扩展小部件以创建自己的子类,或直接在小部件代码中执行实现。由您决定。
在这两种情况下,您都需要覆盖其 onDraw 回调,并在 super.onDraw(canvas)调用之后立即执行网格绘制。 无需创建新的位图或新的画布实例。使用方法的画布执行绘制。
Error: disk: duplicate SCSI unit_number 0
请注意,避免在onDraw方法内部创建新对象,例如Paint实例等,因为onDraw可以在短时间内多次调用。无论如何,皮棉应该警告您。切勿在诸如onDraw,onMeasure等方法中创建新的对象实例,因为此类情况始终要预先缓存/重用它们。
一种更简单的选择,是扩展视图并创建一个新的专用网格视图小部件,该窗口小部件与实际的“缩放图像视图”无关。执行相同的操作,因此,也要覆盖上面示例中的 onDraw 方法,并如图所示渲染网格。然后,将这个新的View放在布局设计中,恰好在Zoom Image View控件的顶部,以确保两个控件具有相同的指标。
,使用此TouchImageView库进行缩放,并通过OnTouchImageViewListener
和isZoomed()
检测缩放。如果已缩放,请使用缩放区域重新绘制画布。这是代码:
touchImageView.setOnTouchImageViewListener(() -> {
if (touchImageView.isZoomed()){
//gets the zoomed area
Bitmap result = Bitmap.createBitmap(touchImageView.getWidth(),touchImageView.getHeight(),Bitmap.Config.RGB_565);
Canvas c = new Canvas(result);
touchImageView.draw(c);
}
});