2011-09-13 66 views
10

Tôi mới vào lớp Đồ họa Android. Tôi muốn vẽ một hình ảnh (thực sự là một loại chữ ký) bằng cách sử dụng các sự kiện cảm ứng và muốn nó được lưu trên SDcard khi tôi muốn lưu nó. Tôi đã quét qua web cho bất kỳ hướng dẫn như vậy nhưng tôi đã không tìm thấy bất kỳ. Bất cứ ai có thể xin vui lòng cho tôi biết làm thế nào để vẽ trên vải bằng cách sử dụng các sự kiện liên lạc và lưu nó.Vẽ trên Canvas và lưu hình ảnh

Bất kỳ hướng dẫn hoặc mã mẫu nào cũng sẽ hữu ích.

Trả lời

20

tôi thấy mã thực sự tốt trên các nhà phát triển Android, nhưng Tôi không thể tìm thấy nó nữa ... Đó là đầu ra là đường cong bezier vì vậy nó sẽ được khá trơn tru. Đây là mã mà tôi chỉnh sửa:

public class MyDrawView extends View { 

private Bitmap mBitmap; 
private Canvas mCanvas; 
private Path mPath; 
private Paint mBitmapPaint; 
private Paint mPaint; 

public MyDrawView(Context c) { 
    super(c); 

    mPath = new Path(); 
    mBitmapPaint = new Paint(Paint.DITHER_FLAG); 

    mPaint = new Paint(); 
    mPaint.setAntiAlias(true); 
    mPaint.setDither(true); 
    mPaint.setColor(0xFF000000); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStrokeJoin(Paint.Join.ROUND); 
    mPaint.setStrokeCap(Paint.Cap.ROUND); 
    mPaint.setStrokeWidth(3); 
} 

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 
    mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
    mCanvas = new Canvas(mBitmap); 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 

    canvas.drawPath(mPath, mPaint); 
} 

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

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

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    float x = event.getX(); 
    float y = event.getY(); 

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

public void clear(){ 
    mBitmap.eraseColor(Color.TRANSPARENT); 
    invalidate(); 
    System.gc(); 
}} 

sau đó trong onCreate của hoạt động bạn muốn sử dụng nó trong bạn chỉ cần viết một cái gì đó như thế này:

RelativeLayout parent = (RelativeLayout) findViewById(R.id.signImageParent); 
myDrawView = new MyDrawView(this); 
parent.addView(myDrawView); 

Quan điểm này là minh bạch và sử dụng sơn màu đen để vẽ với ngón tay của bạn. Vì vậy, nếu bạn muốn xem những gì bạn vẽ chỉ đơn giản là vẽ một bitmap màu trắng hoặc màu xám trên nền của khung nhìn này (bạn chỉ cần thêm một dòng trong startnig của onDraw), hoặc bạn có thể sử dụng nền của phụ huynh.

Sau đó, khi bạn muốn tạo một hình ảnh từ những gì bạn đã vẽ bạn chỉ cần gọi

parent.setDrawingCacheEnabled(true); 
Bitmap b = parent.getDrawingCache(); 

FileOutputStream fos = null; 
try { 
fos = new FileOutputStream(getFileName()); 
} catch (FileNotFoundException e) { 
e.printStackTrace(); 
} 

b.compress(CompressFormat.PNG, 95, fos); 

Nó phụ thuộc vào những gì bạn muốn có như đầu ra, bạn có thể sử dụng mã này hoặc thay mẹ bạn có thể làm điều này với myDrawView và bạn chỉ nhận được hình ảnh bạn đã vẽ mà không có nền (vì chúng tôi có nền myDrawView trong suốt).

Hy vọng điều này sẽ hữu ích. Hãy để lại phản hồi.

+0

Mã tuyệt vời ... !!! – Manjunath

+0

Cảm ơn, đó là những gì tôi cần. – lucasjmatias

+1

Điều gì sẽ xảy ra nếu tôi có một TextView mà tôi muốn biến nó thành một bảng vẽ để cho phép vẽ miễn phí? –

19

điều vẽ

Scribbler.java:

package org.yourpackage.scribble; 

import android.app.Activity; 
import android.graphics.Color; 
import android.os.Bundle; 

public class Scribbler extends Activity { 
    DrawView drawView; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     drawView = new DrawView(this); 
     drawView.setBackgroundColor(Color.WHITE); 
     setContentView(drawView); 
     drawView.requestFocus(); 

    } 
} 

DrawView.java:

package org.yourpackage.scribble; 

import java.util.ArrayList; 
import java.util.List; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 

public class DrawView extends View implements OnTouchListener { 
    List<Point> points = new ArrayList<Point>(); 
    Paint paint = new Paint(); 

    public DrawView(Context context) { 
     super(context); 
     setFocusable(true); 
     setFocusableInTouchMode(true); 
     this.setOnTouchListener(this); 
     paint.setColor(Color.BLACK); 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 
     for (Point point : points) { 
      canvas.drawCircle(point.x, point.y, 2, paint); 
     } 
    } 

    public boolean onTouch(View view, MotionEvent event) { 
     Point point = new Point(); 
     point.x = event.getX(); 
     point.y = event.getY(); 
     points.add(point); 
     invalidate(); 
     return true; 
    } 
} 

class Point { 
    float x, y; 
} 

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="org.yourpackage.scribble" 
     android:versionCode="1" 
     android:versionName="1.0"> 
    <application> 
     <activity android:name=".Scribbler"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 
    <uses-sdk android:minSdkVersion="3" /> 
</manifest> 

..will cung cấp cho bạn một cái gì đó như thế:

alt text

Bạn có thể muốn vẽ đường thay vì pixel

điều tiết kiệm

Để thực hiện tiết kiệm, bạn có thể vượt qua một Bitmap vào các nhà xây dựng Canvas, sau đó sử dụng phương pháp compress của Bitmap để tạo một OutputStream có thể được ghi vào thẻ SD

EDIT để trả lời nhận xét của bạn:
Chắc chắn bạn có thể sử dụng XML để xác định bố cục của mình từ DrawView mở rộng Xem bạn có thể sử dụng nó trong tệp xml bố cục của mình. Một ví dụ cho các tập tin main.xml bố trí

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:id="@+id/linearLayout" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="@drawable/gradient" 
    > 

    <Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> 
    <org.yourpackage.scribble.DrawView android:id="@+id/drawView1" android:layout_width="wrap_content" android:layout_height="wrap_content">  </at.gru.android.drawdemo.DrawView> 
</LinearLayout> 

cung cấp cho bạn một cái gì đó như thế:
enter image description here
Bạn chỉ cần một contstructor thêm public DrawView(Context context, AttributeSet attrSet)

+0

Tôi có cần tạo các nút và nhãn từ mã nếu tôi muốn chèn bất kỳ thành phần giao diện người dùng nào không? Tôi có thể sử dụng tệp Bố cục XML cho các thành phần giao diện người dùng không? Sử dụng ví dụ trên bản vẽ không phải là liên tục. Cần làm gì để đạt được bản vẽ liên tục mà không bị vỡ? –

+0

Tôi vừa chỉnh sửa câu trả lời để giải quyết nhận xét của bạn – DonGru

+0

Cảm ơn bạn đã chỉnh sửa Martin. Một điều cuối cùng. Làm thế nào có thể đạt được bản vẽ trơn tru mà không bị vỡ? –

Các vấn đề liên quan