j'ai la classe suivante ci-dessous qui se prolonge Voir et a la méthode onDraw de substitution pour dessiner cirles sur un bitmap qui a été chargé dans.enregistrement d'une toile, bitmap avec des cercles dessinés
Les charges bitmap avec succès et est affiché sur l'écran. Lorsque l'utilisateur touche l'écran, un cercle est dessiné.
J'ai un bouton d'action flottant qui compresse l'image bitmap dans un octet []. Cet octet [] est ensuite envoyé à une autre activité à afficher. Malheureusement, le bitmap résultant n'a aucun cercle en place. Canvas est un objet local dans onDraw et mCBitmap et tCanvas sont des variables globales de sorte que la méthode saveImage peut accéder aux données.
Quelqu'un peut-il me dire pourquoi aucun des cercles n'est copié dans le bitmap résultant?
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Environment;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
import org.apache.commons.io.IOUtils;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.graphics.PointF;
/**
* Created by MatthewW on 14/06/2017.
*/
public class TouchView extends View {
private static final String TAG = TouchView.class.getSimpleName();
Bitmap bgr;
File tempFile;
private byte[] imageArray;
private Paint pTouch;
Context context;
private SparseArray<ColouredCircle> mPointers;
public int x;
public int y;
int circleCount;
int radius;
protected byte [] data;
Bitmap mCBitmap;
Canvas tCanvas;
public TouchView(Context context) {
super(context);
this.context = context;
}
public TouchView(Context context, AttributeSet attr) {
super(context,attr);
Log.e(TAG, "inside touchview constructor");
this.context = context;
radius = 70;
circleCount = 0;
copyReadAssets();
imageArray = new byte[(int)tempFile.length()];
Log.e(TAG, "imageArray has length = " + imageArray.length);
try{
InputStream is = new FileInputStream(tempFile);
BufferedInputStream bis = new BufferedInputStream(is);
DataInputStream dis = new DataInputStream(bis);
int i = 0;
while (dis.available() > 0) {
imageArray[i] = dis.readByte();
i++;
}
dis.close();
} catch (Exception e) {
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length);
if(bm == null){
Log.e(TAG, "bm = null");
}else{
Log.e(TAG, "bm = not null");
}
mPointers = new SparseArray<ColouredCircle>();
bgr = bm.copy(bm.getConfig(), true);
bm.recycle();
pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);
// pTouch.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));
pTouch.setColor(Color.RED);
pTouch.setStyle(Paint.Style.STROKE);
pTouch.setStrokeWidth(5);
}// end of touchView constructor
private void copyReadAssets() {
AssetManager assetManager = context.getAssets();
InputStream in = null;
OutputStream out = null;
tempFile = new File(context.getFilesDir(), "bodymap.jfif");
try {
in = assetManager.open("bodymap.jfif");
out = context.openFileOutput(tempFile.getName(), Context.MODE_WORLD_READABLE);
IOUtils.copy(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
@Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
Log.e(TAG, "about to draw bgr ");
// canvas.drawBitmap(bgr, 0, 0, null);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
Rect frameToDraw = new Rect(0, 0, width, height);
RectF whereToDraw = new RectF(0, 0, width, height - 300);
canvas.drawBitmap(bgr,frameToDraw,whereToDraw, null);
if(mPointers != null) {
Log.e(TAG, "mPointers.size() = " + mPointers.size());
for (int i = 0; i < mPointers.size(); i++) {
PointF p = mPointers.get(i).getPointF();
x = (int) p.x;
y = (int) p.y;
pTouch.setColor(mPointers.get(i).getColour());
canvas.drawCircle(x, y, radius, pTouch);
mCBitmap = Bitmap.createBitmap(bgr.getWidth(), bgr.getHeight(), bgr.getConfig());
tCanvas = new Canvas(mCBitmap);
tCanvas.drawBitmap(bgr, 0, 0, null);
tCanvas.drawCircle(x, y, radius, pTouch);
tCanvas.drawBitmap(mCBitmap, 0, 0, null);
}
}
}//end of onDraw
@Override
public boolean onTouchEvent(MotionEvent me) {
switch (me.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN: {
/*int ai = me.getActionIndex();
PointF pt = new PointF(me.getX(ai), me.getY(ai));
mPointers.put(me.getPointerId(ai), pt);
Log.e(TAG, "mPointers.size() = " + mPointers.size() + "me.getPointerId(ai) = "
+ me.getPointerId(ai) + " me.getX(ai) = " + me.getX(ai) + " me.getY(ai) = " + me.getY(ai));*/
int ai = me.getActionIndex();
PointF pt = new PointF(me.getX(ai), me.getY(ai));
ColouredCircle cc = new ColouredCircle(pTouch.getColor(),pt);
mPointers.put(circleCount, cc);
circleCount++;
invalidate();
return true;
}
case MotionEvent.ACTION_UP: {
}
case MotionEvent.ACTION_POINTER_UP: {
/*int pid = me.getPointerId(me.getActionIndex());
mPointers.remove(pid);*/
return true;
}
case MotionEvent.ACTION_MOVE: {
/*for (int i = 0; i < me.getPointerCount(); ++i) {
PointF pt = mPointers.get(me.getPointerId(i));
pt.set(me.getX(i), me.getY(i));
invalidate();
}*/
return true;
}
}
return false;
}
public void showToastMessage(String mess){
Toast.makeText(TouchView.this.getContext(), mess.toString(), Toast.LENGTH_SHORT).show();
}
public int getRadius() {
return radius;
}
public void setRadius(int r) {
radius = r;
invalidate();
}
public void setCircleColour(String colourMode){
if(colourMode.equalsIgnoreCase("RED")){
pTouch.setColor(Color.RED);
}else if(colourMode.equalsIgnoreCase("BLUE")){
pTouch.setColor(Color.BLUE);
}else if(colourMode.equalsIgnoreCase("GREY")){
pTouch.setColor(Color.GRAY);
}
}
public byte[] saveImage(){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
mCBitmap.compress(Bitmap.CompressFormat.JPEG, 100 /*ignored for PNG*/, bos);
data = bos.toByteArray();
try {
bos.flush();
bos.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
bos.flush();
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (data == null){
Log.e(TAG, "data in touchview before save clicked is null");
}else{
Log.e(TAG, "data in touchview before saved clicked is not null and has length + " + data.length);
}
return data;
}
}//end of class
[EDIT1]
J'ai changé mes méthodes onDraw() et SaveImage() à ce qui suit ci-dessous. L'image est maintenant enregistrée avec les cercles en place. Cependant, l'image bgr est très petite et en haut à gauche de l'écran (le reste de l'écran est noir). Les cercles sont à la bonne place car ils sont dans l'original, c'est juste l'image bg dans la taille de l'écran.
Comment est-ce que je peux rendre la copie de l'image bg au Bitmap résultant en pleine taille?
@Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
Log.e(TAG, "about to draw bgr ");
// canvas.drawBitmap(bgr, 0, 0, null);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
Rect frameToDraw = new Rect(0, 0, width, height);
RectF whereToDraw = new RectF(0, 0, width, height - 300);
canvas.drawBitmap(bgr,frameToDraw,whereToDraw, null);
if(mPointers != null) {
Log.e(TAG, "mPointers.size() = " + mPointers.size());
for (int i = 0; i < mPointers.size(); i++) {
PointF p = mPointers.get(i).getPointF();
x = (int) p.x;
y = (int) p.y;
pTouch.setColor(mPointers.get(i).getColour());
canvas.drawCircle(x, y, radius, pTouch);
}
}
}//end of onDraw
.
public byte[] saveImage(){
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels - 300;
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
//Bitmap bitmap = Bitmap.createBitmap(bgr.getWidth(), bgr.getHeight(), bgr.getConfig());
Canvas canvas = new Canvas(bitmap);
this.draw(canvas);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100 /*ignored for PNG*/, bos);
data = bos.toByteArray();
try {
bos.flush();
bos.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
bos.flush();
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (data == null){
Log.e(TAG, "data in touchview before save clicked is null");
}else{
Log.e(TAG, "data in touchview before saved clicked is not null and has length + " + data.length);
}
return data;
}
.
Voici une photo de l'activité qui permet à l'utilisateur de placer des cercles sur l'image. L'image bg est en plein écran.
Voici une image de la sortie dans l'activité suivante où l'image avec des cercles est transformé en un octet [] et affiché. Comme vous pouvez le voir, l'image bg n'est pas en plein écran mais les cercles sont dans les bonnes positions.
Salut, Merci pour une réponse si détaillée. Je pense que je dois faire beaucoup plus de lecture sur les graphiques android. Cela fonctionne bien maintenant! Je vais également faire ces changements pour placer les objets dans le constructeur. Merci encore! – turtleboy