2011-09-13 17 views
10

Jestem nowy w klasie Android Graphics. Chcę narysować obrazek (właściwie rodzaj podpisu) za pomocą zdarzeń dotykowych i chcę go zapisać na karcie SD, kiedy chcę go zapisać. Przeskanowałem przez Internet takie samouczki, ale nie znalazłem żadnych. Czy każdy może mi powiedzieć, jak rysować na płótnie za pomocą zdarzeń dotykowych i zapisać go.Rysowanie na płótnie i zapisywanie obrazu

Wszelkie samouczki lub przykładowy kod będą bardzo pomocne.

Odpowiedz

20

Widziałem naprawdę dobry kod na Android deweloperów, ale Nie mogę go już znaleźć ... Jego wyjście to krzywe Beziera, więc będzie całkiem gładko. Oto kod, który I edycja:

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

następnie w onCreate aktywności chcesz użyć go po prostu napisać coś takiego:

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

Ten widok jest przejrzysty i używa czarną farbą czerpaka Twój palec. Jeśli chcesz zobaczyć, co narysujesz, po prostu narysuj białą lub szarą bitmapę w tle tego widoku (wystarczy dodać jedną linię na początku programu onDraw) lub możesz użyć tła rodzica.

Potem, gdy chcesz utworzyć obraz z tego, co zostało sporządzone po prostu zadzwonić

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); 

To zależy co chcesz mieć na wyjściu, można użyć tego kodu lub zamiast rodzic cię może to zrobić z myDrawView, a otrzymasz obraz, który narysowałeś bez tła (ponieważ mamy przezroczyste tło myDrawView).

Mam nadzieję, że to pomoże. Możesz zostawić opinię.

+0

Fantastyczny kod ... !!! – Manjunath

+0

Dzięki, to jest to, czego potrzebuję. – lucasjmatias

+1

Co zrobić, jeśli mam TextView, który chcę uczynić z deski kreślarskiej, aby umożliwić darmowe losowanie? –

19

rzeczą rysunek

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 daje coś takiego:

alt text

może chcesz rysować linie zamiast pikseli

oszczędzania rzeczą

Aby wdrożyć oszczędności można przekazać do Bitmap konstruktor Canvas, a następnie użyj metody compress do utworzenia OutputStream, która może być zapisana na karcie SD

EDYTUJ, aby odpowiedzieć na Twój komentarz:
Z pewnością możesz użyć XML do zdefiniowania swojego układu od DrawView extends View możesz go użyć w swoim pliku xml układu. Przykładem pliku main.xml układu

<?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> 

że daje coś takiego:
enter image description here
Będziesz wystarczy dodatkowy contstructor public DrawView(Context context, AttributeSet attrSet)

+0

Czy muszę utworzyć przyciski i etykiety z kodu, jeśli chcę wstawić któryś z komponentów interfejsu użytkownika? Czy mogę użyć pliku układu XML dla składników interfejsu użytkownika? Przy użyciu powyższego przykładu rysunek nie jest ciągły. Co należy zrobić, aby uzyskać ciągły rysunek bez pęknięć? –

+0

Właśnie zredagowałem odpowiedź, aby odpowiedzieć na Twój komentarz – DonGru

+0

Dzięki za Edit Martin. Ostatnia rzecz. Jak osiągnąć gładki rysunek bez pęknięć? –

Powiązane problemy