15 votes

Dessiner sur Canvas et enregistrer l'image

Je suis nouveau dans la classe Android Graphics. Je veux dessiner une image (en fait une sorte de signature) en utilisant les événements tactiles et je veux la sauvegarder sur la carte SD quand je veux l'enregistrer. J'ai parcouru le web à la recherche de tutoriels similaires mais je n'en ai pas trouvé. Est-ce que quelqu'un peut me dire comment dessiner sur un canvas en utilisant les événements tactiles et le sauvegarder.

Des tutoriels ou des exemples de code seraient d'une grande aide.

28voto

Belovoj Points 315

J'ai vu un très bon code sur les développeurs Android, mais je ne le trouve plus... Sa sortie est des courbes de Bézier donc ce sera assez lisse. Voici le code que j'ai édité:

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

ensuite dans le onCreate de l'activité dans laquelle vous voulez l'utiliser, il vous suffit d'écrire quelque chose comme ceci:

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

Ce composant est transparent et utilise de la peinture noire pour dessiner avec votre doigt. Donc si vous voulez voir ce que vous avez dessiné, il suffit de dessiner une image blanche ou grise en arrière-plan de ce composant (vous ajoutez simplement une ligne au début de onDraw), ou vous pouvez utiliser l'arrière-plan du parent.

Ensuite, lorsque vous voulez créer une image de ce que vous avez dessiné, il vous suffit d'appeler

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

Cela dépend de ce que vous voulez obtenir comme résultat, vous pouvez utiliser ce code ou au lieu de parent vous pouvez le faire avec myDrawView et vous n'obtiendrez que l'image que vous avez dessinée sans arrière-plan (puisque nous avons notre arrière-plan myDrawView transparent).

J'espère que cela vous aidera. N'hésitez pas à laisser vos commentaires.

23voto

DonGru Points 6677

la chose de dessin

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 points = new ArrayList();
    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:

..vous donnera quelque chose comme ça:

texte alternatif

Vous pouvez vouloir dessiner des lignes au lieu de pixels

la chose d'enregistrer

Pour implémenter l'enregistrement, vous pouvez passer un Bitmap dans le constructeur Canvas, puis utiliser la méthode compress de Bitmap pour créer un OutputStream qui peut être écrit sur la carte SD

EDITEZ pour répondre à votre commentaire:
Bien sûr, vous pouvez utiliser XML pour définir votre mise en page car DrawView étend View, vous pouvez l'utiliser dans votre fichier de disposition xml. Un exemple pour le fichier de mise en page main.xml

cela vous donnera quelque chose comme ça:
entrer la description de l'image ici
Vous aurez juste besoin d'un constructeur supplémentaire public DrawView(Context context, AttributeSet attrSet)

0voto

brando f Points 33

J'avais une classe de vue de dessin configurée, et ce que Belovoj a suggéré a également fonctionné dans cette classe :

    setDrawingCacheEnabled(true); //dans l'init de la classe

    //quand je voulais obtenir l'image pour l'enregistrer
    Bitmap b = this.getDrawingCache();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X