I'm creating an app where the user draws a letter on canvas and it gets validated if the draw is an actual letter. I'm using a GestureOverlayView with a canvas inside to capture both the gesture and the path, the problem is that the canvas is not drawing the whole path/gesture i do with my hands. I need help to find the solution. I need the path/gesture to be fully drawn.
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.gesture.GestureOverlayView
android:id="#+id/gestures"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:eventsInterceptionEnabled="true"
android:gestureStrokeType="multiple"
android:layout_alignParentRight="true"
android:fadeOffset="500"
android:background="#000000">
<cohen.projetoTEA.com.DrawLetter
android:id="#+id/drawing"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_height="wrap_content"
android:background="#FFFFFF"
/>
</android.gesture.GestureOverlayView>
</RelativeLayout>
Activity
public class Reconhecimento extends Activity implements OnGesturePerformedListener {
GestureLibrary mLibrary;
private final File mStoreFile = new File(Environment.getExternalStorageDirectory(), "gestures");
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.reconhecimento);
//mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
mLibrary = GestureLibraries.fromFile(mStoreFile);
if (!mLibrary.load()) {
finish();
}
GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
gestures.addOnGesturePerformedListener(this);
gestures.setGestureVisible(false);
}
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = mLibrary.recognize(gesture);
if (predictions.size() > 0 && predictions.get(0).score > 1.0) {
String result = predictions.get(0).name;
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
if ("open".equalsIgnoreCase(result)) {
Toast.makeText(this, "Opening the document", Toast.LENGTH_LONG).show();
} else if ("save".equalsIgnoreCase(result)) {
Toast.makeText(this, "Saving the document", Toast.LENGTH_LONG).show();
}
}
}
}
DrawLetter app
public class DrawLetter extends View {
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
private boolean erase=false;
public DrawLetter(Context context, AttributeSet attrs){
super(context, attrs);
setupDrawing();
}
private void setupDrawing(){
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(5);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
public void setErase(boolean isErase){
erase=isErase;
if(erase){
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
drawPaint.setStrokeWidth(10);
}
else{
drawPaint.setXfermode(null);
drawPaint.setStrokeWidth(5);
}
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//view given size
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
//draw view
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
//detect user touch
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
break;
default:
return false;
}
invalidate();
return true;
}
public boolean getErase(){ return erase; }
}
You can do it in another way.
Like this
<android.gesture.GestureOverlayView
android:id="#+id/g1"
android:layout_width="fill_parent"
android:layout_height="200dp"
android:background="#ffffff"
android:fadeOffset="999999"
android:gestureColor="#0000FF"
android:gestureStrokeType="multiple"
android:gestureStrokeWidth="5" >
<android.gesture.GestureOverlayView
android:id="#+id/g2"
android:layout_width="fill_parent"
android:layout_height="200dp"
android:gestureStrokeType="multiple"
android:fadeOffset="001"
android:gestureColor="#000"
android:gestureStrokeAngleThreshold="0.0"
android:gestureStrokeLengthThreshold="0.0"
android:gestureStrokeSquarenessThreshold="0.0"
>
</android.gesture.GestureOverlayView>
</android.gesture.GestureOverlayView>
Here GestureOverlayView g2 is within g1.
g2 is used to recognize letters and it fades once the letter is written.
But g1 does not fades.
If you don't want the letter you can clear the GestureOverlayView.
Related
I have a custom ImageView where user can draw using some colors.
I load image from server then allow user to draw on top of it.
When i load the next image , i want the previously drawn colors to be gone before user can draw again.
I tried many thing from internet but not able to achieve the same.
below is code for custom ImageView:
public class DrawingView extends androidx.appcompat.widget.AppCompatImageView {
//drawing path
static Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
static int paintColor = 0xFFFFFFFF;
//stroke width
private float STROKE_WIDTH = 5f;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
//eraser mode
private boolean erase = false;
private boolean cc = false;
//constructor
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
setupDrawing();
setErase(erase);
}
private void setupDrawing() {
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(STROKE_WIDTH);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
//*************************************** View assigned size ****************************************************
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
public void setPaintColor(int paintColor) {
this.paintColor = paintColor;
setupDrawing();
}
public void setImageOnImageview(Bitmap canvasBitmap) {
this.canvasBitmap = canvasBitmap;
}
#Override
public void setImageResource(int resId) {
super.setImageResource(resId);
}
public void setErase(boolean isErase) {
erase = isErase;
drawPaint = new Paint();
if (erase) {
setupDrawing();
int srcColor = getResources().getColor(R.color.white);
PorterDuff.Mode mode = PorterDuff.Mode.CLEAR;
PorterDuffColorFilter porterDuffColorFilter = new PorterDuffColorFilter(srcColor, mode);
drawPaint.setColorFilter(porterDuffColorFilter);
drawPaint.setColor(srcColor);
drawPaint.setXfermode(new PorterDuffXfermode(mode));
} else {
setupDrawing();
}
}
//************************************ draw view *************************************************************
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (cc) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
cc = false;
} else {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
}
public void clearCanvas() {
setupDrawing();
setErase(false);
cc = true;
invalidate();
}
//*************************** respond to touch interaction **************************************************
#Override
public boolean onTouchEvent(MotionEvent event) {
canvasPaint.setColor(paintColor);
float touchX = event.getX();
float touchY = event.getY();
//respond to down, move and up events
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
break;
default:
return false;
}
//redraw
invalidate();
return true;
}
//*********************************** return current alpha ***********************************************
public int getPaintAlpha() {
return Math.round((float) STROKE_WIDTH / 255 * 100);
}
//************************************** set alpha ******************************************************
public void setPaintAlpha(int newAlpha) {
STROKE_WIDTH = Math.round((float) newAlpha / 100 * 255);
drawPaint.setStrokeWidth(newAlpha);
}
}
I tried many solutions like clear path or clear paint.
Could any please help me with this ?
I assume you want to remove the drawn color on first image upon loading the new image
I think you can draw the color over canvas
Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
or reset the path itself
Path.reset();
EDIT:
I initialized canvasBitmap = Bitmap.createBitmap(500,300, Bitmap.Config.RGB_565); drawCanvas = new Canvas(canvasBitmap); app does not crash but also does not draw anything.. i test it with canvas.drawcolor(Color.RED) inside the HOVER MOVE case. Now,learning from the crash I KNOW it is recognizing my hover movement.. so why nothing happens now? any idea?
I have an android 5.1 development board with a usb mouse connected. I need to perform some drawing operation when mouse is moved inside view window.
I am aware that the android studio emulator does not work with hover so all of my testing is on the development board itself
I added a hover listener to my OnCreate method. I basically have a transparent view sitting on top of the camera2 video (textureview). Trying to listen to it.
As soon as I move the mouse inside app, it crashes. so it IS detecting the hover. need some help with the reason for the crash. here are all relevant code: Activit containing the Oncreate, my CustomView, and my XML
public class CameraActivity extends Activity {
private Canvas drawCanvas;
private Bitmap canvasBitmap;
private Paint canvasPaint;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
if (null == savedInstanceState) {
getFragmentManager().beginTransaction()
.replace(R.id.container, Camera2BasicFragment.newInstance())
.commit();
}
View container = findViewById(R.id.container);
canvasPaint = new Paint(Paint.DITHER_FLAG);
container.setOnHoverListener(new View.OnHoverListener() {
#Override
public boolean onHover(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_HOVER_ENTER:
break;
case MotionEvent.ACTION_HOVER_MOVE:
drawCanvas.drawCircle(50,50,100,canvasPaint);
break;
case MotionEvent.ACTION_HOVER_EXIT:
break;
}
return false;
}
});
}
}
customview:
public class CustomView extends View{
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xff00ff00;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
//constructor
public CustomView(Context context){
super(context);
setupDrawing();
}
public CustomView(Context context, AttributeSet attrs){
super(context, attrs);
setupDrawing();
}
//prepare drawing
private void setupDrawing(){
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(10);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
//view assigned size
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
//draw view
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
//respond to touch interaction
#Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
//respond to down, move and up events
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);
new Timer().schedule(new TimerTask() {
#Override
public void run() {
// this code will be executed after 2 seconds
drawCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
}
}, 2000);
drawPath.reset();
break;
default:
return false;
}
//redraw
invalidate();
return true;
}
}
xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.android.camera2basic.AutoFitTextureView
android:id="#+id/texture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<com.example.android.camera2basic.CustomView
android:id="#+id/texture2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<FrameLayout
android:id="#+id/control"
android:layout_width="match_parent"
android:layout_height="112dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:background="#color/control_background">
<Button
android:id="#+id/picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/picture" />
<ImageButton
android:id="#+id/info"
android:contentDescription="#string/description_info"
style="#android:style/Widget.Material.Light.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:padding="20dp"
android:src="#drawable/ic_action_info" />
</FrameLayout>
</RelativeLayout>
I have the following xml setup:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/content"
android:orientation="vertical">
</LinearLayout>
<ListView
android:id="#+id/navList"
android:layout_width="250dp"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:background="#cccccc"/>
</android.support.v4.widget.DrawerLayout>
I now would like to draw a canvas in that linear layout, therefore I do that:
Radar radar = new Radar(this, this.width);
content.addView(radar);
and here is the radar class:
private int width;
public Radar(Context context, int width){
super(context);
this.width = width;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint circlePaint = new Paint();
circlePaint.setColor(0xFF00FF00);
circlePaint.setStyle(Paint.Style.FILL);
Rect rect = new Rect();
rect.set(0, 0, canvas.getWidth(), canvas.getHeight() / 2);
canvas.drawRect(rect, circlePaint);
//canvas.drawCircle(0, 0, this.width, circlePaint);
}
The problem I encounter is that the canvas doesn't show up
How can I fix that?
I found the answer by adding setWillNotDraw(false);
It worked below code for me. you can also try similarly.
1) Add layout
<com.example.canvas.DrawingArea
android:id="#+id/drawing"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_marginBottom="3dp"
android:layout_weight="1"
android:background="#FFFFFFFF" />
2) Code
public class DrawingArea extends View {
private Path drawPath;
private Paint drawPaint, canvasPaint;
private int paintColor = 0xFF660000;
private Canvas drawCanvas;
private Bitmap canvasBitmap;
private boolean erase = false;
public DrawingArea(Context context) {
super(context);
setupDrawing();
}
public DrawingArea(Context context, AttributeSet attrs) {
super(context, attrs);
setupDrawing();
}
public void setupDrawing() {
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(20);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
public void setColor(String newColor) {
invalidate();
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(eventX, eventY);
break;
case MotionEvent.ACTION_MOVE:
drawPath.lineTo(eventX, eventY);
break;
case MotionEvent.ACTION_UP:
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
break;
default:
return false;
}
// Makes our view repaint and call onDraw
invalidate();
return true;
}
public void setErase() {
canvasBitmap.eraseColor(Color.TRANSPARENT);
drawPath.reset();
invalidate();
}
public void startNew() {
drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
invalidate();
}
}
3) create drawing object
DrawingArea mDrawView = (DrawingArea) findViewById(R.id.drawing);
I have created my own custom edittext class so that i can draw in it and also add text...
Everything is working fine regarding the drawing part but when i type no text is visible,,,,,,
How can i fix this
my customview
public class MyCustomView extends View
{
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
private float brushSize ;
private boolean erase=false;
public MyCustomView(Context c, AttributeSet attr){
super(c,attr);
setupdraw();
}
public MyEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void setupdraw()
{
drawPath = new Path();
drawPaint = new Paint();
brushSize = 15;
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);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//view given size
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
//draw view
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
//detect user touch
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
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 void setBrushSize(float newSize){
//update size
float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
newSize, getResources().getDisplayMetrics());
brushSize=pixelAmount;
drawPaint.setStrokeWidth(brushSize);
}
}
}
my main activity
public class MainActivity extends Activity
{
private MyCustomView myView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MyCustomView myView = (MyCustomView) findViewById(R.id.myCustomView);
}
}
main.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:padding="10dp"
android:background="#D06C65">
<com.mycompany.myapp.MyCustomView
android:id="#+id/myCustomView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#EAEAEA"/>
<Button
android:layout_height="wrap_content"
android:text="T"
android:layout_width="wrap_content"
android:layout_gravity="bottom|center"/>
</FrameLayout>
You should call super.onDraw(canvas) after drawing your background stuff. The TextView drawing methods will subsequently handle all the drawing text features (you don't want to recode that).
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
super.onDraw(canvas);
}
I want to be able to edit photos, allowing a user to put annotations on a photo they have captured. I am fine with Portrait photos, but Landscape photos are causing me major problems. The problem is that the drawing area ends up being the entire layout and I just want the photo boundaries to be editable (drawable). How do I do this? Portrait is ok since it fills up the layout.
Here is what it looks like:
And here is the code XML def:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical"
tools:context=".MainActivity" >
<!-- Top Buttons -->
<LinearLayout
android:id="#+id/drawToolbar"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="center"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/new_btn"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="#drawable/new_pic" />
<!--
<ImageButton
android:id="#+id/existing_btn"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="#drawable/new_pic" />
-->
<ImageButton
android:id="#+id/draw_btn"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="#drawable/brush" />
<ImageButton
android:id="#+id/erase_btn"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="#drawable/eraser" />
</LinearLayout>
<!-- Custom View -->
<RelativeLayout
android:id="#+id/imgStack"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="0dp">
<ImageView
android:id="#+id/imgBackground"
android:layout_alignParentTop="true"
android:layout_marginBottom="3dp"
android:layout_height="fill_parent"
android:layout_width="fill_parent"/>
<com.invocore.fastfield.views.DrawingView
android:id="#+id/drawing"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="3dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="3dp"
android:background="#android:color/transparent" />
</RelativeLayout>
<!-- Color Palette -->
... removed buttons to save space...
</LinearLayout>
The Activity code looks like this (have removed stuff to save space):
public class PhotoCaptureEditActivity extends Activity implements OnClickListener {
//custom drawing view
private DrawingView drawView;
private ImageView imgBackground;
private RelativeLayout imgStack;
// toolbars
private LinearLayout drawToolbar, drawColors;
//buttons
private ImageButton currPaint, drawBtn, eraseBtn, newBtn; //, saveBtn, existingBtn;
//sizes
private float smallBrush, mediumBrush, largeBrush;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo_capture_edit);
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
// reset all pending values
GlobalState.getInstance().pendingFieldKey = null;
GlobalState.getInstance().pendingFieldValue = null;
//get drawing view
drawView = (DrawingView)findViewById(R.id.drawing);
drawView.setVisibility(View.VISIBLE);
imgBackground = (ImageView)findViewById(R.id.imgBackground);
imgStack = (RelativeLayout)findViewById(R.id.imgStack);
// toolbars
drawToolbar = (LinearLayout)findViewById(R.id.drawToolbar);
drawColors = (LinearLayout)findViewById(R.id.drawColors);
//get the palette and first color button
LinearLayout paintLayout = (LinearLayout)findViewById(R.id.paint_colors);
currPaint = (ImageButton)paintLayout.getChildAt(0);
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
[removed button and other code to save space]
enableDrawing();
// Must be a PNG for editing
Bitmap image = Utilities.loadImageByPath(filename);
if (image != null) {
imgBackground.setImageBitmap(image);
}
}
//user clicked paint
public void paintClicked(View view){
//use chosen color
setModeText("Draw Mode");
//set erase false
drawView.setErase(false);
drawView.setBrushSize(drawView.getLastBrushSize());
if(view!=currPaint){
ImageButton imgView = (ImageButton)view;
String color = view.getTag().toString();
drawView.setColor(color);
//update ui
imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
currPaint=(ImageButton)view;
}
}
[Lots of other code...]
}
And the DrawingView class:
public class DrawingView extends View {
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
//brush sizes
private float brushSize, lastBrushSize;
//erase flag
private boolean erase=false;
public DrawingView(Context context, AttributeSet attrs){
super(context, attrs);
setupDrawing();
}
//setup drawing
private void setupDrawing(){
//prepare for drawing and setup paint stroke properties
brushSize = getResources().getInteger(mycompany.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);
}
//size assigned to view
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if(canvasBitmap == null) {
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);
}
drawCanvas = new Canvas(canvasBitmap);
drawCanvas.drawColor(Color.TRANSPARENT);
}
//draw the view - will be called after touch event
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
//register user touches as drawing action
#Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
//respond to down, move and up events
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
if(erase == true) {
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
drawPath.moveTo(touchX, touchY);
}
else {
drawPath.lineTo(touchX, touchY);
}
break;
case MotionEvent.ACTION_UP:
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
break;
default:
return false;
}
//redraw
invalidate();
return true;
}
//update color
public void setColor(String newColor){
invalidate();
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
// set into draw mode if color was clicked
setBrushSize(getLastBrushSize());
setErase(false);
}
//set brush size
public void setBrushSize(float newSize){
float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
newSize, getResources().getDisplayMetrics());
brushSize=pixelAmount;
drawPaint.setStrokeWidth(brushSize);
}
//get and set last brush size
public void setLastBrushSize(float lastSize){
lastBrushSize=lastSize;
}
public float getLastBrushSize(){
return lastBrushSize;
}
//set erase true or false
public void setErase(boolean isErase){
erase=isErase;
if(erase) drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
else drawPaint.setXfermode(null);
}
public void startExisting(String path) {
File file = new File(path);
if(file.exists() == true) {
Bitmap captured = BitmapFactory.decodeFile(file.toString());
canvasBitmap = captured.copy(Bitmap.Config.ARGB_8888, true);
drawCanvas = new Canvas(canvasBitmap);
drawCanvas.drawColor(Color.TRANSPARENT);
invalidate();
}
}
public void startNew() {
if(drawCanvas != null) {
drawCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
invalidate();
}
// setting a solid background color
//drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
//drawCanvas.drawColor(Color.GREEN, PorterDuff.Mode.CLEAR);
}
public Bitmap getImage() {
return canvasBitmap;
}
}
Thanks!
Uri currImageURI = intent.getData();
String s= getRealPathFromURI(currImageURI);
File file = new File(s);
if (file.exists()) {
Drawable drawImg = Drawable.createFromPath(file.getAbsolutePath());
drawView.setBackground(drawImg);
}
else {
// file does not exist
}