2016-08-29 2 views
0

Я пытаюсь нарисовать линию над изображением, она отлично работает, но я столкнулся с некоторой проблемой. Проблема в том, что я хочу рисовать линию только по изображению, а не по пустому пространству. Этот код здесь метод sizechanged, который я объявляю следующим образом.Нарисуйте краску поверх изображения не пустым пространством, используя холст

class DrawingPaint extends View implements View.OnTouchListener { 

private Canvas mCanvas; 
private Path mPath; 
private Paint mPaint, mBitmapPaint; 
public ArrayList<PathPoints> paths = new ArrayList<PathPoints>(); 
private ArrayList<PathPoints> undonePaths = new ArrayList<PathPoints>(); 
private Bitmap mBitmap; 
private int color; 
private int x, y; 
private String textToDraw = null; 
private boolean isTextModeOn = false; 
int lastColor = 0xFFFF0000; 
static final float STROKE_WIDTH = 15f; 
Matrix m; 
int imageHeight,imageWidth; 

public DrawingPaint(Context context/*, int color*/) { 
    super(context); 
    //this.color = color; 
    setFocusable(true); 
    setFocusableInTouchMode(true); 

    this.setOnTouchListener(this); 

    mBitmapPaint = new Paint(Paint.DITHER_FLAG); 
    /*mPaint = new Paint(); 
    mPaint.setAntiAlias(true); 
    mPaint.setDither(true); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStrokeJoin(Paint.Join.ROUND); 
    mPaint.setStrokeCap(Paint.Cap.ROUND); 
    mPaint.setStrokeWidth(STROKE_WIDTH); 
    mPaint.setTextSize(30); 

    mPath = new Path(); 
    paths.add(new PathPoints(mPath, color, false)); 
    mCanvas = new Canvas();*/ 
} 

public void colorChanged(int color) { 
    this.color = color; 
    mPaint.setColor(color); 
} 

public void setColor(int color) { 

    mPaint = new Paint(); 
    this.color = color; 
    mPaint.setAntiAlias(true); 
    mPaint.setDither(true); 
    mPaint.setColor(color); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStrokeJoin(Paint.Join.ROUND); 
    mPaint.setStrokeCap(Paint.Cap.ROUND); 
    mPaint.setStrokeWidth(STROKE_WIDTH); 
    mPaint.setTextSize(30); 

    mPath = new Path(); 
    paths.add(new PathPoints(mPath, color, false)); 
    mCanvas = new Canvas(); 

} 

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 
    // mBitmap = AddReportItemActivity.mPhoto; 
    mBitmap = CustomGalleryHandler.getmInstance().getBitmapSend(); 
    float xscale = (float) w/(float) mBitmap.getWidth(); 
    float yscale = (float) h/(float) mBitmap.getHeight(); 
    if (xscale > yscale) // make sure both dimensions fit (use the 
     // smaller scale) 
     xscale = yscale; 
    float newx = (float) w * xscale; 
    float newy = (float) h * xscale; // use the same scale for both 
    // dimensions 
    // if you want it centered on the display (black borders) 
    /*mBitmap = Bitmap.createScaledBitmap(mBitmap, this.getWidth(), 
      this.getHeight(), true);*/ 
    // mCanvas = new Canvas(mBitmap); 

    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(new File(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen()).getAbsolutePath(), options); 
    imageHeight = options.outHeight; 
    imageWidth = options.outWidth; 

    m = new Matrix(); 
    RectF drawableRect = new RectF(0, 0, imageWidth, imageHeight); 
    //onMeasure(imageWidth,imageHeight); 
    RectF viewRect = new RectF(0, 0, w, h); 
    m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER); 

    mBitmap = Bitmap.createBitmap(mBitmap,0,0,imageWidth, 
      imageHeight, m,true); 

} 

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    int width = MeasureSpec.getSize(widthMeasureSpec); 
    int height = MeasureSpec.getSize(heightMeasureSpec); 

    setMeasuredDimension(width, height); 
    //setMeasuredDimension(this.getWidth(), this.getHeight()); 
    //setMeasuredDimension(560, 100);even though give a ensured size, it can't //anyway. 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    float[] pts = {0, 0}; 
    m.mapPoints(pts); 
    canvas.drawBitmap(mBitmap, pts[0], pts[1], mBitmapPaint); 
    // canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 
    for (PathPoints p : paths) { 
     mPaint.setColor(p.getColor()); 
     Log.v("", "Color code : " + p.getColor()); 
     if (p.isTextToDraw()) { 
      canvas.drawText(p.textToDraw, p.x, p.y, mPaint); 
     } else { 
      canvas.drawPath(p.getPath(), mPaint); 
     } 
    } 
} 

private float mX, mY; 
private static final float TOUCH_TOLERANCE = 0; 

private void touch_start(float x, float y) { 
    mPath.reset(); 
    mPath.moveTo(x, y); 
    mX = x; 
    mY = y; 
} 

private void touch_move(float x, float y) { 
    float dx = Math.abs(x - mX); 
    float dy = Math.abs(y - mY); 
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
     mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); 
     mX = x; 
     mY = y; 
    } 
} 

private void touch_up() { 
    mPath.lineTo(mX, mY); 
    // commit the path to our offscreen 
    mCanvas.drawPath(mPath, mPaint); 
    // kill this so we don't double draw 
    mPath = new Path(); 
    paths.add(new PathPoints(mPath, color, false)); 

} 

private void drawText(int x, int y) { 

    this.x = x; 
    this.y = y; 
    paths.add(new PathPoints(color, textToDraw, true, x, y)); 
    // mCanvas.drawText(textToDraw, x, y, mPaint); 
} 

@Override 
public boolean onTouch(View arg0, MotionEvent event) { 
    float x = event.getX(); 
    float y = event.getY(); 

    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      if (!isTextModeOn) { 
       touch_start(x, y); 
       invalidate(); 
      } 
      break; 
     case MotionEvent.ACTION_MOVE: 
      if (!isTextModeOn) { 
       touch_move(x, y); 
       invalidate(); 
      } 
      break; 
     case MotionEvent.ACTION_UP: 
      if (isTextModeOn) { 
       drawText((int) x, (int) y); 
       invalidate(); 
      } else { 
       touch_up(); 
       invalidate(); 
      } 
      break; 
    } 
    return true; 
} 

public void onClickUndo() { 
    try { 
     if (paths.size() > 0) { 
      undonePaths.add(paths.remove(paths.size() - 1)); 
      invalidate(); 
     } else { 

     } 
    } catch (Exception e) { 
     e.toString(); 
    } 

} 

public void onClickRedo() { 
    try { 

     if (undonePaths.size() > 0) { 
      paths.add(undonePaths.remove(undonePaths.size() - 1)); 
      invalidate(); 
     } else { 

     } 
    } catch (Exception e) { 
     e.toString(); 
    } 
} 


/*class PathPoints { 
    private Path path; 
    // private Paint mPaint; 
    private int color; 
    private String textToDraw; 
    private boolean isTextToDraw; 
    private int x, y; 

    public PathPoints(Path path, int color, boolean isTextToDraw) { 
     this.path = path; 
     this.color = color; 
     this.isTextToDraw = isTextToDraw; 
    } 

    public PathPoints(int color, String textToDraw, boolean isTextToDraw, 
         int x, int y) { 
     this.color = color; 
     this.textToDraw = textToDraw; 
     this.isTextToDraw = isTextToDraw; 
     this.x = x; 
     this.y = y; 
    } 

    public Path getPath() { 
     return path; 
    } 

    public void setPath(Path path) { 
     this.path = path; 
    } 

    public int getColor() { 
     return color; 
    } 

    public void setColor(int color) { 
     this.color = color; 
    } 

    public String getTextToDraw() { 
     return textToDraw; 
    } 

    public void setTextToDraw(String textToDraw) { 
     this.textToDraw = textToDraw; 
    } 

    public boolean isTextToDraw() { 
     return isTextToDraw; 
    } 

    public void setTextToDraw(boolean isTextToDraw) { 
     this.isTextToDraw = isTextToDraw; 
    } 

    public int getX() { 
     return x; 
    } 

    public void setX(int x) { 
     this.x = x; 
    } 

    public int getY() { 
     return y; 
    } 

    public void setY(int y) { 
     this.y = y; 
    } 

}*/ 

}

+0

переопределить 'onMeasure()' и получить точный размер представления перед рисованием растрового изображения. – Abbas

+0

@Abbas, может у меня рассказать больше, PLS это поможет. –

+0

Я думаю, это может помочь вам http://stackoverflow.com/a/39178719/3142611 – Bahu

ответ

0

Может быть, вы хотите расширить свой индивидуальный вид из ImageView это сам.

public class Line extends ImageView { 

private static final String TAG = "Line"; 
private Paint lineDraw = null; 

private int mStartX = 0; 
private int mStartY = 0; 
private int mEndX = 0; 
private int mEndY = 0; 
private float mStrokeWidth = 0; 

public Line(Context context) { 
    super(context); 

    init_Paint(); 
} 

public Line(Context context, AttributeSet attrs) { 
    super(context, attrs); 

    init_Attributes(context, attrs); 

    init_Paint(); 
} 

public Line(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 

    init_Attributes(context, attrs); 

    init_Paint(); 
} 

private void init_Paint() 
{ 
    lineDraw = new Paint(Paint.ANTI_ALIAS_FLAG); 

    lineDraw.setStyle(Paint.Style.FILL); 
    lineDraw.setColor(Color.BLACK); 
    lineDraw.setStrokeWidth(mStrokeWidth); 
} 

private void init_Attributes(Context context, AttributeSet attrs) 
{ 
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Line); 
    mStartX = a.getInteger(R.styleable.Line_startX, 0); 
    mStartY = a.getInteger(R.styleable.Line_startY, 0); 
    mEndX = a.getInteger(R.styleable.Line_endX, 0); 
    mEndY = a.getInteger(R.styleable.Line_endY, 0); 

    mStrokeWidth = a.getDimension(R.styleable.Line_strokeWidth, 0); 

    a.recycle(); 
} 

public void setStartX(int startX) 
{ 
    this.mStartX = startX; 
} 

public void setStartY(int startY) 
{ 
    this.mStartY = startY; 
} 

public void setEndX(int endX) 
{ 
    this.mEndX = endX; 
} 

public void setEndY(int endY) 
{ 
    this.mEndY = endY; 
} 

public void setStrokeWidth(float strokeWidth) 
{ 
    this.mStrokeWidth = strokeWidth; 
} 

@Override 
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
{ 
    int width = MeasureSpec.getSize(widthMeasureSpec); 
    int height = MeasureSpec.getSize(heightMeasureSpec); 

    setMeasuredDimension(width, height); 
} 

@Override 
public void onDraw(Canvas canvas) 
{ 
    //Call ImageView's default onDraw() method. 
    super.onDraw(canvas); 

    // You can instead use canvas.drawPath(); 
    canvas.drawLine(mStartX, mStartY, mEndX, mEndY, lineDraw); 
} 
} 

В вашем attr.xml добавьте следующее.

<resources> 
    <declare-styleable name="Line"> 
     <attr name="startX" format="integer" /> 
     <attr name="endX" format="integer" /> 
     <attr name="startY" format="integer" /> 
     <attr name="endY" format="integer" /> 
     <attr name="strokeWidth" format="dimension" /> 
    </declare-styleable> 
</resources> 

, и вы можете использовать его так.

<views.customview.Line 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:startX="5" 
    app:startY="5" 
    app:endX="500" 
    app:endY="500" 
    app:strokeWidth="15dp" 
    android:src="@drawable/add_bookmark" 
    /> 
+0

спасибо, пожалуйста, проверьте мой исходный код выше. Я пытаюсь измерить это не работает. –

+0

Что не работает? Будьте немного более конкретными. – Abbas

+0

Кстати, почему вы называете 'super.onMeasure()'? И тогда вы вызываете 'setMeasuredDimension' самостоятельно. – Abbas

Смежные вопросы