如何在低分辨率 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
}
}
我正在通过执行以下操作在 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
}
}