I would like to know how to draw a rectangle in specific position and size.
I tried a couple of trials and examples here and on web, but nothing worked for me.
I'm using a SurfaceView and SurfaceHolder to hold the camera preview.
I just want to draw a rectangle when the user touch on the screen.
I don't want to use external library and When I'm trying to get the canvas from the holder I'm getting null.
For now there is no code, cause nothing work for me, if someone has a clue how to do it, I will try it.
This is what I've already tried:
Link 1
Link 2
Link 3
Thanks for help!
Ok, Thanks to fadden I found the easiest solution(at least for me).
First I created another Surface view and my XML file look like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:opencv="http://schemas.android.com/apk/res-auto"
android:layout_gravity="left|top">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<SurfaceView
android:layout_alignParentTop="true"
android:id="@+id/CameraView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<SurfaceView
android:layout_alignParentTop="true"
android:id="@+id/TransparentView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
</RelativeLayout>
And than I'm created another holder for the new surface, this is a part of my java code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_capture);
// Create first surface with his holder(holder)
cameraView = (SurfaceView)findViewById(R.id.CameraView);
cameraView.setOnTouchListener(onTouchListner);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// Create second surface with another holder (holderTransparent)
transparentView = (SurfaceView)findViewById(R.id.TransparentView);
holderTransparent = transparentView.getHolder();
holderTransparent.setFormat(PixelFormat.TRANSPARENT);
holderTransparent.addCallback(callBack);
holderTransparent.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
At last I implement a method called 'DrawFocusRect'
private void DrawFocusRect(float RectLeft, float RectTop, float RectRight, float RectBottom, int color)
{
canvas = holderTransparent.lockCanvas();
canvas.drawColor(0,Mode.CLEAR);
//border's properties
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(color);
paint.setStrokeWidth(3);
canvas.drawRect(RectLeft, RectTop, RectRight, RectBottom, paint);
holderTransparent.unlockCanvasAndPost(canvas);
}
As you can see, I clear the canvas every time, if I don't do this, the surface will display in addition more rectangles on each others.
This is how I call to this method from a 'OnTouchListener' event:
OnTouchListener onTouchListner = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
RectLeft = event.getX() - 100;
RectTop = event.getY() - 100 ;
RectRight = event.getX() + 100;
RectBottom = event.getY() + 100;
DrawFocusRect(RectLeft , RectTop , RectRight , RectBottom , Color.BLUE);
}
};
Hope this would be helpfull for someone else.
I customize a new surface and using onTouchEvent and draw my rectangle:
public class MySurface extends SurfaceView {
private Paint mPaint;
private Path mPath;
private Canvas mCanvas;
private SurfaceHolder mSurfaceHolder;
private float mX, mY, newX, newY;
public MSurface(Context context) {
super(context);
initi(context);
}
private void initi(Context context) {
mSurfaceHolder = getHolder();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setTextSize(12);
mPaint.setColor(Color.RED);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mX = event.getX();
mY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
newX = event.getX();
newY = event.getY();
break;
default:
// Do nothing
}
drawRect();
invalidate();
return true;
}
for drawing your rectangle use this function:
private void drawRect() {
mPath = new Path();
mPath.moveTo(mX, mY);
mCanvas = mSurfaceHolder.lockCanvas();
mCanvas.save();
mPath.addRect(mX, mY, newX, newY, Path.Direction.CCW);
mCanvas.drawPath(mPath, mPaint);
mCanvas.restore();
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
mX = newX;
mY = newY;
}
}
Now you can use this customized surface in your XML files like this:
<com.glinter.ir.MySurface
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>