我正在尝试将图像添加到Android画布,并能够使用手指绘画来注释图像。我修改了它 from this tutorial at tuts plus
我能够从我的drawables文件夹中硬编码一个图像并在所述图像上绘画。我现在的问题是在我的图像上覆盖一个画布,它超出了图像本身。我们的想法是能够注释图像并在图像边界之外做笔记。
这里我们有笔动作的截图
在这里,我尝试了几次笔动作后的渲染输出。
这是我的代码。我为整个事情道歉,我对机器人是极端的n00b所以我不确定要附加什么。我只是在调用'startNew()'方法时试图隔离我的动作,当我点击我的FAB按钮上的加号图标时调用该方法。在没有图像的原始画布中,笔渲染并保留在整个空白区域上。我保留了Log.i消息,以便在控制台中查看调用哪些方法进行自我意识。
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
public class DrawingView extends ViewGroup {
//drawing path
private Path drawPath;
//ImageView choosenImageView;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
private Bitmap bmp;
private Bitmap mutableBitmap;
private Bitmap newBitmap;
private float brushSize, lastBrushSize;
private boolean erase=false;
private boolean theCanvas=false;
private void setUpDrawing(){
Resources res = getResources();
Log.i("SETUP","OMG SO MUCH SETUP");
brushSize = getResources().getInteger(R.integer.medium_size);
lastBrushSize = brushSize;
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(brushSize);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
public void startNew(){
Log.i("NEW","SO NEWW");
drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
Resources res=getResources();
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inScaled=false;
bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeResource(res, R.drawable.jupiter, bmpFactoryOptions);
mutableBitmap=bmp.copy(Bitmap.Config.ARGB_8888, true);
drawCanvas.drawBitmap(mutableBitmap,0,0,drawPaint);
canvasBitmap=mutableBitmap;
theCanvas=true;
drawCanvas = new Canvas(canvasBitmap);
invalidate();
}
public void putOverlay(Bitmap bitmap, Bitmap overlay) {
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(overlay, 0, 0, paint);
}
public void setErase(boolean isErase){
//set erase true or false
erase=isErase;
if(erase) drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
else drawPaint.setXfermode(null);
}
public void setBrushSize(float newSize){
//update size
float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
newSize, getResources().getDisplayMetrics());
brushSize=pixelAmount;
drawPaint.setStrokeWidth(brushSize);
}
public void setLastBrushSize(float lastSize){
lastBrushSize=lastSize;
}
public float getLastBrushSize(){
return lastBrushSize;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//view given size
super.onSizeChanged(w, h, oldw, oldh);
Log.i("SIZEE", "THE ISZEE IS CHANGES");
bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mutableBitmap = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
//draw view
if(theCanvas){
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}else {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
final int count = getChildCount();
Log.i("onlayout","hello shouldn't come heres");
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//detect user touch
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("onDown","hello onpen DOWN");
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
//Log.i("onMOVINGS","hello ondraw");
drawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
Log.i("line","drew some shitty line");
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
break;
default:
return false;
}
invalidate();
return true;
}
public void setColor(String newColor){
//set color
invalidate();
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
}
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
setUpDrawing();
Log.i("someshintg","context1");
}
public DrawingView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
Log.i("someshintg","context2");
}
public DrawingView(Context context) {
super(context);
Log.i("someshintg","context3");
}
}
更新:
public void startNew(){
Log.i("NEW","SO NEWW");
drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
Resources res=getResources();
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inScaled=false;
bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeResource(res, R.drawable.jupiter, bmpFactoryOptions);
mutableBitmap=bmp.copy(Bitmap.Config.ARGB_8888, true);
drawCanvas.drawBitmap(mutableBitmap,0,0,drawPaint);
//canvasBitmap=mutableBitmap;
theCanvas=true;
//drawCanvas = new Canvas(canvasBitmap);
invalidate();
}
我编辑了我的代码,试图不修改drawCanvas对象,只是让可变位图成为与图像本身相关的位图。结果是图像占用了太多空间,我认为这很奇怪,因为我使用inScaled=false;
来使它与之前的父级不匹配。我曾尝试在以前的尝试中使用我的XML布局中的ImageView占位符,但我不能让它们在画布本身中呈现; imageView在画布下呈现为兄弟,但当作为画布的子画面放置时,它是不可见的。这是当前代码实现的屏幕截图:
答案 0 :(得分:0)
你检查过帆布的尺寸吗? 对我来说,看起来画布大小设置为位图大小,因此绘制的注释仅在位图内可见
答案 1 :(得分:0)
我能够通过使用画布drawBitmap来解决这个问题,它使用源和目标矩形(仍然如此)并将其设置为我想要显示的矩形。
宣布为private Rect imgRect;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//view given size
super.onSizeChanged(w, h, oldw, oldh);
Log.i("SIZEE", "THE ISZEE IS CHANGES");
imgRect = new Rect(0,0,w*2,h*2);
bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mutableBitmap = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
public void startNew(){
Log.i("NEW","SO NEWW");
drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
Resources res=getResources();
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inScaled=false;
bmpFactoryOptions.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeResource(res, R.drawable.jupiter, bmpFactoryOptions);
mutableBitmap=bmp.copy(Bitmap.Config.ARGB_8888, true);
drawCanvas.drawBitmap(mutableBitmap,imgRect,imgRect,drawPaint);
//canvasBitmap=mutableBitmap;
theCanvas=true;
invalidate();
}