Android画布覆盖图像

时间:2015-04-19 14:44:13

标签: android canvas android-bitmap

我正在尝试将图像添加到Android画布,并能够使用手指绘画来注释图像。我修改了它 from this tutorial at tuts plus

我能够从我的drawables文件夹中硬编码一个图像并在所述图像上绘画。我现在的问题是在我的图像上覆盖一个画布,它超出了图像本身。我们的想法是能够注释图像并在图像边界之外做笔记。

这里我们有笔动作的截图  enter image description here

在这里,我尝试了几次笔动作后的渲染输出。     enter image description here

这是我的代码。我为整个事情道歉,我对机器人是极端的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在画布下呈现为兄弟,但当作为画布的子画面放置时,它是不可见的。这是当前代码实现的屏幕截图:

enter image description here

2 个答案:

答案 0 :(得分:0)

你检查过帆布的尺寸吗?  对我来说,看起来画布大小设置为位图大小,因此绘制的注释仅在位图内可见

答案 1 :(得分:0)

我能够通过使用画布drawBitmap来解决这个问题,它使用源和目标矩形(仍然如此)并将其设置为我想要显示的矩形。

宣布为private Rect imgRect;

应用程序首次打开时会调用onSizeChanged,而给予onSizeChanged的参数是屏幕宽度和高度,所以我用它来获取startNew中使用的大小

@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();
}

enter image description here