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.
Related
i want to convert canvas to image and save it on device. But when I set bitmap to canvas I get error java.lang.UnsupportedOperationException.
My full code:
public class SingleTouchEventView extends View {
private Paint paint = new Paint();
private Path path = new Path();
public SingleTouchEventView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setAntiAlias(true);
paint.setStrokeWidth(6f);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.BEVEL);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(path, paint);
canvas.drawCircle(50, 50, 3, paint);
Bitmap bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
canvas.setBitmap(bitmap);
try {
File file = new File(Environment.getExternalStorageDirectory() + "/image.jpg");
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(file));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Maybe someone could help me to solve this problem?
That isn't how you draw to a bitmap. You do NOT use the canvas that draws to the screen. You create a second canvas, passing in the bitmap you want to draw to as a parameter in the constructor. Then any draw commands to that canvas will draw the bitmap. Then you draw that bitmap to the screen. Something like this:
Canvas myCanvas = new Canvas(myBitmap);
myCanvas.drawLine();
myCanvas.drawCircle();
//Insert all the rest of the drawing commands here
screenCanvas.drawBitmap(myBitmap, 0, 0);
I also would not write it to the file system in onDraw - I'd expect drawing performance to suffer badly if you do. A separate function call can do that. If you keep myBitmap around in a variable, you can just compress it anytime to write out the last draw to disk.
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());
}
}
I am trying to save a canvas on an sdcard. Basically I am drawing two bitmaps (one on top of another) in the onDraw(Canvas canvas) method. But when I save the file, only the bottom layered Bitmap is stored. I am posting the code for the onDraw method here:
Paint paint = new Paint();
paint.setColor(Color.BLACK);
//rectangle for the first image
rct = new Rect(10, 10, canvas.getWidth(), canvas.getHeight());
// rectangle for the second image, the secong image is drawn where the user touches the screen
new_image = new RectF(touchX, touchY, touchX + secondBitmap.getWidth(),
touchY + secondBitmap.getHeight());
//this is the bitmap that is drawn first
canvas.drawBitmap(firstBitmap, null, rct, paint);
//this is the bitmap drawn on top of the first bitmap on user touch
canvas.drawBitmap(secondBitmap, null, new_image, paint);
canvas.save();
the code for saving the canvas on the SDcard written on the MainActivity is:
Bitmap bm = canvas.getDrawingCache() // canvas in an object of the class I extended from View
String path = Environment.getExternalStorageDirectory()
.getAbsolutePath();
boolean exists = (new File(path)).exists();
OutputStream outStream = null;
File file = new File(path, "drawn_image" + ".jpg");
try {
outStream = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
The problem is that only the base image(firstBitmap of the onDraw() method) is saved on the SDCard instead of the entire canvas(with both the images). I am new to canvas...So any help would be very appreciated
when getDrawingcache() is called it invalidates the view to get the full cache. so debug your code and check if it is going through each and every line of your onDraw() method in view.
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)
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.