hear is the example which explain how to create like painter program, which provide functionality to draw image using pencil and also functionality of erase image and save the image in png format.
Layout File : canvas_activity.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:id="@+id/rlTitleCanvas" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/darker_gray" android:layout_alignParentTop="true"> <TextView android:id="@+id/tvTitleCanvas" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Shared Canvas" android:textSize="14dp" android:textColor="@android:color/white" android:layout_centerHorizontal="true" android:padding="5dp"/> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.materialexample.DrawingView android:id="@+id/drawing" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFFFFFFF" /> <LinearLayout android:id="@+id/llButtonsBottom" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="@android:color/white" android:orientation="horizontal" android:padding="5dp"> <ImageView android:id="@+id/imgPen" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:scaleType="centerInside" android:src="@drawable/pen_can_" /> <ImageView android:id="@+id/imgErase" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:scaleType="centerInside" android:src="@drawable/eraser_can" /> <ImageView android:id="@+id/imgDoneCanvas" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:scaleType="centerInside" android:src="@drawable/done_bt" /> </LinearLayout> </RelativeLayout> </LinearLayout>
Create Main Activity Class : DrawSign.java
package com.materialexample; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ImageView; import java.io.File; import java.io.FileOutputStream; import in.co.materialexample.R; /** * Created by windws on 09-Dec-15. */ public class DrawSign extends Activity { private DrawingView mDrawingView = null; private ImageView imgPen, imgDone, imgErase; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.canvas_activity); initializeObject(); eventListeners(); } private void initializeObject() { imgPen = (ImageView) findViewById(R.id.imgPen); imgErase = (ImageView) findViewById(R.id.imgErase); imgDone = (ImageView) findViewById(R.id.imgDoneCanvas); mDrawingView = (DrawingView) findViewById(R.id.drawing); } private void eventListeners() { imgPen.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { imgPen.setImageResource(R.drawable.pen_can); imgErase.setImageResource(R.drawable.eraser_can); mDrawingView.setErase(false); mDrawingView.setBrushSize(5); mDrawingView.setLastBrushSize(5); } }); imgDone.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mDrawingView.setDrawingCacheEnabled(true); String imagePath = store_image(mDrawingView.getDrawingCache(), "/mnt/sdcard/Painter/", Math.random() + "image.jpg"); Intent intent = new Intent(); intent.putExtra("drawPath", imagePath); setResult(13, intent); finish(); } }); imgErase.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { imgPen.setImageResource(R.drawable.pen_can_); imgErase.setImageResource(R.drawable.eraser_can_); mDrawingView.setErase(true); mDrawingView.setBrushSize(15); } }); } public String store_image(Bitmap _bitmapScaled, String dirPath, String fileName) { //you can create a new file name "test.jpg" in sdcard folder. File f = new File(dirPath, fileName); if (f.exists()) { f.delete(); } try { FileOutputStream out = new FileOutputStream(f); _bitmapScaled.compress(Bitmap.CompressFormat.JPEG, 100, out); out.flush(); out.close(); Log.d("mypath****************", dirPath + File.separator + fileName); return dirPath + fileName; } catch (Exception e) { e.printStackTrace(); } return ""; } }
Class for View : DrawingView.java
package com.materialexample; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Shader; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class DrawingView extends View { //drawing path private Path drawPath, circlePath, mPath; //drawing and canvas paint private Paint drawPaint, canvasPaint, circlePaint, mBitmapPaint; //initial color private int paintColor = 0xFF000000, paintAlpha = 255; //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 = 5; lastBrushSize = brushSize; drawPath = new Path(); mPath = 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); mBitmapPaint = new Paint(Paint.DITHER_FLAG); circlePaint = new Paint(); circlePath = new Path(); circlePaint.setAntiAlias(true); circlePaint.setColor(Color.parseColor("#f4802b")); circlePaint.setStyle(Paint.Style.STROKE); circlePaint.setStrokeJoin(Paint.Join.MITER); circlePaint.setStrokeWidth(1f); } //size assigned to view @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); canvasBitmap.eraseColor(Color.TRANSPARENT); drawCanvas = new Canvas(canvasBitmap); // drawCanvas.drawColor(Color.BLACK); } //draw the view - will be called after touch event @Override protected void onDraw(Canvas canvas) { if(erase) { canvas.drawBitmap(canvasBitmap, 0, 0, mBitmapPaint); // canvas.drawPath(mPath, drawPaint); canvas.drawPath(circlePath, circlePaint); } else { canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint); canvas.drawPath(drawPath, drawPaint); } } float mX, mY; private static final float TOUCH_TOLERANCE = 1; //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: if(erase) { mPath.reset(); mPath.moveTo(touchX, touchY); mX = touchX; mY = touchY; drawPaint.setStyle(Paint.Style.FILL); drawPaint.setColor(Color.BLACK); drawCanvas.drawCircle(touchX, touchY, 25, drawPaint); } else { drawPath.moveTo(touchX, touchY); } break; case MotionEvent.ACTION_MOVE: if(erase) { float dx = Math.abs(touchX - mX); float dy = Math.abs(touchY - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mPath.quadTo(mX, mY, (touchX + mX)/2, (touchY + mY)/2); mX = touchX; mY = touchY; circlePath.reset(); circlePath.addCircle(mX, mY, 30, Path.Direction.CW); } drawPaint.setStyle(Paint.Style.FILL); drawPaint.setColor(Color.BLACK); drawCanvas.drawCircle(touchX, touchY, 25, drawPaint); } else { drawPath.lineTo(touchX, touchY); } break; case MotionEvent.ACTION_UP: drawPath.lineTo(touchX, touchY); drawCanvas.drawPath(drawPath, drawPaint); circlePath.reset(); drawPath.reset(); break; default: return false; } //redraw invalidate(); return true; } //update color public void setColor(String newColor){ invalidate(); //check whether color value or pattern name if(newColor.startsWith("#")){ paintColor = Color.parseColor(newColor); drawPaint.setColor(paintColor); drawPaint.setShader(null); } else { //pattern int patternID = getResources().getIdentifier(newColor, "drawable", "com.thots"); //decode Bitmap patternBMP = BitmapFactory.decodeResource(getResources(), patternID); //create shader BitmapShader patternBMPshader = new BitmapShader(patternBMP,Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); //color and shader drawPaint.setColor(0xFFFFFFFF); drawPaint.setShader(patternBMPshader); } } //set brush size public void setBrushSize(float newSize){ // float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,newSize, getResources().getDisplayMetrics()); // brushSize=pixelAmount; brushSize=newSize; 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.setStyle(Paint.Style.FILL); drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); } else { drawPaint.setStyle(Paint.Style.STROKE); drawPaint.setColor(paintColor); drawPaint.setXfermode(null); } } //start new drawing public void startNew() { drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR); invalidate(); } //return current alpha public int getPaintAlpha(){ return Math.round((float)paintAlpha/255*100); } //set alpha public void setPaintAlpha(int newAlpha){ paintAlpha=Math.round((float)newAlpha/100*255); drawPaint.setColor(paintColor); drawPaint.setAlpha(paintAlpha); } }
Note : Please don't miss to change class path in layout file.
No comments:
Post a Comment