I’m making a simple drawing app on Android. I’m using the FingerPaint.java provided with the ApiDemos sample as a base, adding some features and getting rid of others. It basically creates a canvas with a bitmap that you can draw on top.
I’ve added “open” and “save” features. The “save” feature stores the bitmap into a file using the getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) function, and the “open” feature launches startActivityForResult(photoPickerIntent, 1) and loads the selected image.
The problem is that I can’t draw on a bitmap that I’ve opened manually. A trace is shown when drawing with the finger, but once the finger is lifted from the screen the trace disappears. If I save this bitmap, it will show up completely unmodified in the gallery. But when starting the app, I can draw just fine on the canvas.
I’m pretty sure this is a very simple problem due to my lack of understanding of how Canvas and Bitmap work. Anyway, here’s my code.
When creating my custom view:
public MyView(Context c){
super(c);
mBitmap = Bitmap.createBitmap(480, 800, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
The OnDraw Override:
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFAAAAAA);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
My “open” function:
private void open(){
//checkSD: 1 if read only, 2 if RW
if(checkSD()==1 || checkSD()==2){
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, 1);
}
}
And finally my onActivityResult:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//RequestCode:1 image
if (requestCode == 1) {
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = data.getData();
try{
InputStream fIn = getContentResolver().openInputStream(selectedImage);
mBitmap = BitmapFactory.decodeStream(fIn);
fIn.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
}
I think my error is in this code, but if anyone thinks it could be in the way I actually draw, I haven’t modified the touch_xxx and the onTouchEvent from the FingerPaint.java example, so you can take a look at it (or ask me to post it here if you can’t see it for some reason).
Thanks!
Ok, solved it!
I did 2 things. The first one was adding the following line right after “fIn.close();” inside onActivityResult:
I’m still not quite sure why this is necessary but I know that it doesn’t work without this line.
The 2nd thing I did was copying the bitmap I was loading. Turns out that BitmapFactory.decodeStream() returns an inmutable bitmap and in order to create a new canvas a mutable bitmap is needed. I found a good explanation in this blog post:
http://sudarnimalan.blogspot.com.es/2011/09/android-convert-immutable-bitmap-into.html
I used the second method, which is copying the bitmap into a new one, like this:
I know from the post that this is not a safe method, but for now it works.
If only I had used “inmutable bitmap” in my search I’d have come up with an answer by myself. Thank you anyways!