How to paint on Image and save that image in to Android? - android

I am new to canvas. I want to use the My already saved Image and want some paint on that image. after that i want to save it.
I know that with using Canvas it is possible. I can able to do painting on the Image but while i am going to store that image it only saved the painting. Not the Image with painting.
So can anybudy tell me code of how to paint on image and save that image ?
Thanks.
Here is my Code that use to do paint on the SurfaceView.
Source Code:
#Override
public void run() {
//Canvas canvas = null;
while (_run){
try{
canvas = mSurfaceHolder.lockCanvas(null);
if(mBitmap == null){
mBitmap = Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888);
}
final Canvas c = new Canvas (mBitmap);
//canvas.drawColor(0, PorterDuff.Mode.CLEAR);
c.drawColor(0, PorterDuff.Mode.CLEAR);
canvas.drawColor(Color.WHITE);
// Bitmap kangoo = BitmapFactory.decodeResource(getResources(),R.drawable.icon);
// if(!(DrawingActivity.imagePath==null)){
// canvas.drawBitmap(DrawingActivity.mBitmap, 0, 0, null);
// }
commandManager.executeAll(c);
canvas.drawBitmap (mBitmap, 0, 0,null);
} finally {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
I am using mBitmap to save the Bitmap to the SDCard.

Your problem is your drawing over and over on your entire canvas:
final Canvas c = new Canvas (mBitmap); // creates a new canvas with your image is painted background
c.drawColor(0, PorterDuff.Mode.CLEAR); // this makes your whole Canvas transparent
canvas.drawColor(Color.WHITE); // this makes it all white on another canvas
canvas.drawBitmap (mBitmap, 0, 0,null); // this draws your bitmap on another canvas
Use logic roughly like this:
#Override
public void run() {
Canvas c = new Canvas(mBitmap);
/* Paint your things here, example: c.drawLine()... Beware c.drawColor will fill your canvas, so your bitmap will be cleared!!!*/
...
/* Now mBitmap will have both the original image & your painting */
String path = Environment.getExternalStorageDirectory().toString(); // this is the sd card
OutputStream fOut = null;
File file = new File(path, "MyImage.jpg");
fOut = new FileOutputStream(file);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.flush();
fOut.close();
}
Also don't forget to add necessary permission to save your file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
outside <application></application> in your manifest file.

Related

Saving a canvas in Android does not work every time

I'm having this code:
public void saveimage() {
Bitmap bitmap = Bitmap.createBitmap(colorGFX.getWidth(),
colorGFX.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
canvas = colorGFX.canvas;
canvas.setBitmap(bitmap);
saveBitmap(bitmap);
}
colorGFX object extends a SurfaceView.
saveBitmap actually writes the image on the file.
The problem is that most of the times a WHITE image is saved, other times the correct image is saved.
Did I missed something, or why does the image saves only let's say 1/5 of the times?
This worked for me:
Bitmap bitmap = Bitmap.createBitmap(colorGFX.getWidth(),
colorGFX.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(colorGFX.bitmap, 0f, 0f, null);
canvas.drawBitmap(colorGFX.pictureBitmap, 0f, 0f, null);
saveBitmap(bitmap);
Try this:
public void saveimage() {
Bitmap bitmap = Bitmap.createBitmap(colorGFX.getWidth(),
colorGFX.getHeight(), Bitmap.Config.ARGB_8888);
colorGFX.draw(new Canvas(bitmap))
saveBitmap(bitmap);
}

Save canvas to jpeg while canvas is not visible

I am programmatically drawing to a canvas using data entered by the user. Once all of the data is entered, the user can flip through the images and they will be drawn to the canvas. The user has the option to save all of the images(could be several hundred). I use a runnable that runs on the UI thread that will draw and save each image(since you can't draw to a canvas from an AsyncTask). This works, but the problem I am having is if while the saving is going on, the user turns off the screen or minimizes the app. This causes the jpegs to just be black. I would like the saving to be something that could run in the background and still work.
Code used to draw to canvas and save image:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap bitmap;
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
canvas.setBitmap(bitmap);
// draw everything here
OutputStream stream = new FileOutputStream(imageName + ".jpg");
bitmap.compress(CompressFormat.JPEG, 100, stream);
stream.close();
}
So, is there a way for images to be drawn and saved to a file in the background while the canvas is not visible? Any help would be appreciated!
I think you can use this:
signLayout.setDrawingCacheEnabled(true); //signLayout is layout that contains image you want to save
// Save image from layout
String path = "sdcard0/test/test.jpg"; //file path you want to save
gestureSign.save(signLayout, path);
SAVE METHOD
//Save to path
public void save(View v, String SavePath)
{
if(mBitmap == null)
{
mBitmap = Bitmap.createBitmap (layoutSign.getWidth(), layoutSign.getHeight(), Bitmap.Config.RGB_565);;
}
Canvas canvas = new Canvas(mBitmap);
try
{
FileOutputStream mFileOutStream = new FileOutputStream(SavePath);
v.draw(canvas); //Lay toan bo layout
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, mFileOutStream);
mFileOutStream.flush();
mFileOutStream.close();
}
catch(Exception e)
{
Log.v("log_tag", e.toString());
}
}

Saving Bitmap drawn on Canvas

In my application I extended the ImageView and overriden its onDraw() method. I am using a color filter to manipulate the bitmap for adding some effects like invert, grayscale etcc. After drawing the bitmap I am trying to save it but I am only able to save the original bitmap with no added effects. Here is the code for onDraw() and save method:
protected void onDraw(Canvas canvas)
{
Paint paint = mPaint;
//cmf is the color matrix filter
paint.setColorFilter(cmf);
if(mBitmap != null)
{
canvas.drawBitmap(mBitmap, offsetW, offsetH, paint);
}
}
code for saving the bitmap:
try
{
FileOutputStream fout = new FileOutputStream(path);
mBitmap.compress(CompressFormat.JPEG, 100, fout);
} catch (FileNotFoundException e)
{
e.printStackTrace();
}
Am I doing something wrong? Any help will be appretiated.
You are painting on the canvas that is displayed, original bitmap is not changed. You should create a new bitmap and paint on it. When color matrix filter changes do this:
Bitmap tmp = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), mBitmap.getConfig())
Canvas canvas = new Canvas(tmp)
cnvas.drawBitmap(tmp, 0, 0, paint);
Then, you can use this tmp bitmap to draw it and save it.
Instead of using customized ImageView use a normal one and set its image to this new bitmap:
imageView.setImageBitmap(tmp)

How to set the Image to appear behind the current canvas?

I am using canvas to draw the Different colour.
I want to set the Image that should be appear as the background of the canvas. And while i am drawing on that image it should be drawn on the Image not behind the image.
Right now with below code it is drawing behind the Image.
#Override
public void run() {
Canvas canvas = null;
while (_run){
try{
canvas = mSurfaceHolder.lockCanvas(null);
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
commandManager.executeAll(canvas);
} finally {
Bitmap kangoo = BitmapFactory.decodeResource(getResources(),R.drawable.icon);
canvas.drawBitmap(kangoo, 130, 100, null);
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
So what should i have to do to make drawing on the image ???
As you redrawing the canvas in While(1) loop you can put the statement canvas.drawBitmap(kangoo, 130, 100, null) at the top inside the loop so that its drawn again and again then do you painting over top of it.
If you want to save the drawn part to you do something like converting the Canvas to bitmap like:
Bitmap bitmapToBeDrawnFromNextTime = Bitmap.createBitmap( canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
Canvas imageCanvas = new Canvas(bitmapToBeDrawnFromNextTime);
imageCanvas.draw(canvas);
No one have giving me answer.
But i got solution, I have to set the image after clearing canvas.
code:
#Override
public void run() {
//Canvas canvas = null;
while (_run){
try{
canvas = mSurfaceHolder.lockCanvas(null);
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
Bitmap kangoo = BitmapFactory.decodeResource(getResources(),R.drawable.icon);
canvas.drawBitmap(kangoo, 130, 100, null);
commandManager.executeAll(canvas);
} finally {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}

Use canvas for the GestureOverlayView

I have a GestureOverlayView on which the user can draw gesture stokes, I want to save these strokes in a PNG file.
I have tried the public void draw (Canvas canvas) ,and I get a PNG file as an output of my following code, but I was not able get any strokes in that, can any one help me with this....
thanks in advance.
My code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.create_gesture);
bitmap= Bitmap.createBitmap(12, 12, Bitmap.Config.RGB_565);
can=new Canvas(bitmap);
GestureOverlayView overlay = (GestureOverlayView) findViewById(R.id.gestures_overlay);
overlay.addOnGestureListener(new GesturesProcessor());
overlay.draw(can);
}
Code to save the strokes as PNG
bm=mGesture.toBitmap(313, 343, 8,3);
can.drawBitmap(bm, 0, 0, null);
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator+"Strokes");
out = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG,100, out);
Toast.makeText(this, "PNG file Created "+mGesture, Toast.LENGTH_LONG).show();
Modification as specified by Dr.J
Paint paint=new Paint();
Bitmap bitmap=Bitmap.createBitmap(412, 412, Bitmap.Config.ARGB_4444);
Canvas can=new Canvas(bitmap);
Path path = new Path();
paint.setColor(255);
.
.
.
.
private class GesturesProcessor implements GestureOverlayView.OnGestureListener {
public void onGestureEnded(final GestureOverlayView overlay, MotionEvent event) {
new Thread(new Runnable() {
public void run() {
mGesture = overlay.getGesture();
try{
path=overlay.getGesturePath();
can.drawPath(path, paint);
can.drawBitmap(bitmap, 0, 0, null);
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator+"Strokes");
out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG,100, out);
Toast.makeText(getBaseContext(), "Created gesture 12:56 section active "+mGesture, Toast.LENGTH_LONG).show();
}catch(Exception exp){exp.printStackTrace();}
}
}).start();
}
You need to capture the gestures from the user directly, the Canvas given to you from Draw(Canvas canvas) is for you to draw on, it doesn't hold data for you to capture from.
You should use:
public Path getGesturePath (Path path)
Then if you want to save it use the Canvas's drawPath AndDev Docs
. It can be drawn with canvas.drawPath(path, paint), either filled or stroked (based on the paint's Style), or it can be used for clipping or to draw text on a path.

Categories

Resources