如何使用 canvas drawPath 或 Path 在 Bitmap 上绘画?我尝试了几个教程但失败了
How to paint on Bitmap using canvas drawPath or Path? I tried several tutorials but failed
所以这是我当前使用 canvas drawLine 的代码,我正在尝试将其修改为 drawPath .
我在 Main 中声明的变量 Activity :
ImageView imageResult;
final int RQS_IMAGE1 = 1;
Paint paint;
Uri source;
Bitmap bitmap;
Canvas canvas;
Path path;
我在 On Create 方法中的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawing_board);
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(10);
//result is the ID of imageview
imageResult = findViewById(R.id.result);
//The user will select Images on gallery
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RQS_IMAGE1);
其中选择的图像传递到 imageResult 变量然后转换为位图,并且该位图将被放置到 canvas :
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bitmap tempBitmap;
if (resultCode == RESULT_OK) {
switch (requestCode) {
case RQS_IMAGE1:
source = data.getData();
try {
//tempBitmap is Immutable bitmap,
//cannot be passed to Canvas constructor
tempBitmap = BitmapFactory.decodeStream(
getContentResolver().openInputStream(source));
Bitmap.Config config;
if (tempBitmap.getConfig() != null) {
config = tempBitmap.getConfig();
} else {
config = Bitmap.Config.ARGB_8888;
}
//bitmap is Mutable bitmap
bitmap = Bitmap.createBitmap(
tempBitmap.getWidth(),
tempBitmap.getHeight(),
config);
canvas = new Canvas(bitmap);
canvas.drawBitmap(tempBitmap, 0, 0, null);
imageResult.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
现在,这是我获取用户手指触摸点并将 canvas.drawLine 放入运动事件中的方法。然后,他们可以在放置 Imageview 的 canvas 上绘画:
private float mX,mY;
public void paintOn_Image(){
imageResult.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mX = x;
mY = y;
float ratioWidth = (float)bitmap.getWidth()/(float)v.getWidth();
float ratioHeight = (float)bitmap.getHeight()/(float)v.getHeight();
canvas.drawLine(
mX * ratioWidth,
mY * ratioHeight,
x * ratioWidth,
y * ratioHeight,
paint);
imageResult.invalidate();
break;
case MotionEvent.ACTION_MOVE:
ratioWidth = (float) bitmap.getWidth() / (float) v.getWidth();
ratioHeight = (float)bitmap.getHeight()/(float)v.getHeight();
canvasMaster.drawLine(
mX * ratioWidth,
mY * ratioHeight,
x * ratioWidth,
y * ratioHeight,
paint);
imageResult.invalidate();
mX = x;
mY = y;
break;
case MotionEvent.ACTION_UP:
ratioWidth = (float) bitmapMaster.getWidth() / (float) v.getWidth();
ratioHeight = (float)bitmapMaster.getHeight()/(float)v.getHeight();
canvasMaster.drawLine(
x * ratioWidth,
y * ratioHeight,
x * ratioWidth,
y * ratioHeight,
paint);
imageResult.invalidate();
break;
}
return true;
}
});
这是我到目前为止所做的。
在 motionEvent.ACTION_DOWN、ACTION_MOVE & ACTION_UP 中,我更改为:
canvas.drawLine(
mX * ratioWidth,
mY * ratioHeight,
x * ratioWidth,
y * ratioHeight,
paint);
imageResult.invalidate();
break;
进入这个:
path.moveTo(mX*ratioWidth,mY*ratioHeight);
path.lineTo(x*ratioWidth,y*ratioHeight);
path.moveTo(mX*ratioWidth,y*ratioHeight);
path.lineTo(x*ratioWidth,mY*ratioHeight);
canvas.drawPath(path,paintDraw);
imageResult.invalidate();
canvas.drawPath(path, paint);
imageResult.invalidate();
break;
但是当用户触摸 canvas 时应用程序崩溃了:(
如何使用 Path 在 canvas 上绘画?计算是否不正确?
我试图将其更改为路径的原因是我们无法撤消
drawLine画入后canvas。所以如果你有解决方案
undo/clear/remove drawLine,它也适用于我。谢谢。
在阅读了本论坛中的大量文档、教程和信息之后。
只需创建 DrawableView 和 CustomImageview,而不是停留在 Imageview 上。
Sources
所以这是我当前使用 canvas drawLine 的代码,我正在尝试将其修改为 drawPath .
我在 Main 中声明的变量 Activity :
ImageView imageResult;
final int RQS_IMAGE1 = 1;
Paint paint;
Uri source;
Bitmap bitmap;
Canvas canvas;
Path path;
我在 On Create 方法中的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawing_board);
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(10);
//result is the ID of imageview
imageResult = findViewById(R.id.result);
//The user will select Images on gallery
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RQS_IMAGE1);
其中选择的图像传递到 imageResult 变量然后转换为位图,并且该位图将被放置到 canvas :
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bitmap tempBitmap;
if (resultCode == RESULT_OK) {
switch (requestCode) {
case RQS_IMAGE1:
source = data.getData();
try {
//tempBitmap is Immutable bitmap,
//cannot be passed to Canvas constructor
tempBitmap = BitmapFactory.decodeStream(
getContentResolver().openInputStream(source));
Bitmap.Config config;
if (tempBitmap.getConfig() != null) {
config = tempBitmap.getConfig();
} else {
config = Bitmap.Config.ARGB_8888;
}
//bitmap is Mutable bitmap
bitmap = Bitmap.createBitmap(
tempBitmap.getWidth(),
tempBitmap.getHeight(),
config);
canvas = new Canvas(bitmap);
canvas.drawBitmap(tempBitmap, 0, 0, null);
imageResult.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
现在,这是我获取用户手指触摸点并将 canvas.drawLine 放入运动事件中的方法。然后,他们可以在放置 Imageview 的 canvas 上绘画:
private float mX,mY;
public void paintOn_Image(){
imageResult.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mX = x;
mY = y;
float ratioWidth = (float)bitmap.getWidth()/(float)v.getWidth();
float ratioHeight = (float)bitmap.getHeight()/(float)v.getHeight();
canvas.drawLine(
mX * ratioWidth,
mY * ratioHeight,
x * ratioWidth,
y * ratioHeight,
paint);
imageResult.invalidate();
break;
case MotionEvent.ACTION_MOVE:
ratioWidth = (float) bitmap.getWidth() / (float) v.getWidth();
ratioHeight = (float)bitmap.getHeight()/(float)v.getHeight();
canvasMaster.drawLine(
mX * ratioWidth,
mY * ratioHeight,
x * ratioWidth,
y * ratioHeight,
paint);
imageResult.invalidate();
mX = x;
mY = y;
break;
case MotionEvent.ACTION_UP:
ratioWidth = (float) bitmapMaster.getWidth() / (float) v.getWidth();
ratioHeight = (float)bitmapMaster.getHeight()/(float)v.getHeight();
canvasMaster.drawLine(
x * ratioWidth,
y * ratioHeight,
x * ratioWidth,
y * ratioHeight,
paint);
imageResult.invalidate();
break;
}
return true;
}
});
这是我到目前为止所做的。 在 motionEvent.ACTION_DOWN、ACTION_MOVE & ACTION_UP 中,我更改为:
canvas.drawLine(
mX * ratioWidth,
mY * ratioHeight,
x * ratioWidth,
y * ratioHeight,
paint);
imageResult.invalidate();
break;
进入这个:
path.moveTo(mX*ratioWidth,mY*ratioHeight);
path.lineTo(x*ratioWidth,y*ratioHeight);
path.moveTo(mX*ratioWidth,y*ratioHeight);
path.lineTo(x*ratioWidth,mY*ratioHeight);
canvas.drawPath(path,paintDraw);
imageResult.invalidate();
canvas.drawPath(path, paint);
imageResult.invalidate();
break;
但是当用户触摸 canvas 时应用程序崩溃了:(
如何使用 Path 在 canvas 上绘画?计算是否不正确?
我试图将其更改为路径的原因是我们无法撤消 drawLine画入后canvas。所以如果你有解决方案 undo/clear/remove drawLine,它也适用于我。谢谢。
在阅读了本论坛中的大量文档、教程和信息之后。
只需创建 DrawableView 和 CustomImageview,而不是停留在 Imageview 上。
Sources