I've followed this tutorial (http://www.mysamplecode.com/2011/11/android-capture-signature-using-canvas.html) to capture a signature using canvas and it's OK.
I made some improvements to the code to save the signature as a Base64 string and it's OK too
I want to "reload" the string back to Canvas and it worked with the following code:
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(StringToBitMap(x), 0, 0, paint); // x = Base64 String PNG
canvas.drawPath(path, paint);
}
I can see the loaded signature, I can draw something over it but I can't clear the loaded signature, it clears all my draws even if they are over the loaded signature but I can't clear the loaded signature. The code I'm using to clear is:
public void clear()
{
path.reset();
invalidate();
}
Try this:
public void clear() {
if (canvas != null) {
canvas.drawColor(Color.WHITE);
mPath.reset();
invalidate();
}
}
Related
I'm trying to draw a Bitmap on a Surface view like this:
private void draw1() {
if (ourHolder.getSurface().isValid()) {
Log.i("View", "drawing...");
canvas = ourHolder.lockCanvas(null);
canvas.drawColor(Color.GREEN, PorterDuff.Mode.CLEAR);
canvas.drawBitmap(playerShip.getBitmap(), 50, 50, paint);
ourHolder.unlockCanvasAndPost(canvas);
} else {
Log.i("View", "surface is not valid");
}
}
But nothing appears. Just a black screen.
But if i add this:
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.GREEN, PorterDuff.Mode.CLEAR);
super.onDraw(canvas);
}
The bitmap is drawn.
Is it required that i clear the canvas, only from it's onDraw() method?
Also, i'm new to Android. Any advice on the style of writing, is welcome.
I am working on a canvas where I draw a text using Path on canvas now i want to add new string over the last string but the new string overwrite the last one, I want to clear last string and then write the new one.
How would i get this any suggestions...
You have to invalidate your canvas to redraw it.
public setText(String text) {
mText = text;
this.invalidate();
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
...
canvas.drawText(mText, x, y, paint);
}
I am learning on canvas and bitmap with paths and currently working on a drawing app where user can draw paths freely on the extended view.
The app also allow allowing user to import bitmap as the background and draw on it.
Extending the View named DoodleView:
public DoodleView(Context context, AttributeSet attrs)
{
super(context, attrs); // pass context to View's constructor
this.context_new=context;
setFocusable(true);
setFocusableInTouchMode(true);
} // end DoodleView constructor
onDraw:
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(bitmap, 0, 0, null);
for (Path p : paths)
{
paintLine.setColor(colorsMap.get(p));
canvas.drawPath(p, paintLine);
}
paintLine.setColor(selectedColor);
canvas.drawPath(mPath, paintLine);
if (ConvertCanvasToBitmap == true)
{
canvas.drawBitmap(bitmap, 0, 0, paintLine);
ConvertCanvasToBitmap = false;
}
}
FlipHorizontally:
public void flipImageHorizontally()
{
ConvertCanvasToBitmap = true;
invalidate();
Matrix flipHorizontalMatrix = new Matrix();
flipHorizontalMatrix.setScale(-1,1);
flipHorizontalMatrix.postTranslate(bitmap.getWidth(),0);
Bitmap HorizontalFlipped = Bitmap.createBitmap
(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), flipHorizontalMatrix, true);
bitmap = HorizontalFlipped;
invalidate();
}
Question:
My goal is that for the paths that are already drawn, when the user tries to flip the image, the paths drawn would also be flipped. (i.e. the paths become part of the image already, and user are disallows to undo the paths anymore).
However, I have tested using the above codes, when the flip button is pressed, the bitmap background can be flipped, yet the drawn would disappear. And then when further drawn on it, the paths will appear again, but stay unflipped.
In short, how to make the paths to become part of the bitmap when the flip button is pressed?
Thanks!
Edit:
Based on the Android 2.1 View's getDrawingCache() method always returns null, I have modified the onDraw with the following code, but got
02-22 21:38:34.685: E/AndroidRuntime(18617): java.lang.NullPointerException
02-22 21:38:34.685: E/AndroidRuntime(18617): at android.graphics.Bitmap.createBitmap(Bitmap.java:455)
02-22 21:38:34.685: E/AndroidRuntime(18617): at com.pearmak.drawing.DoodleView.onDraw(DoodleView.java:148)
Modified code:
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(bitmap, 0, 0, null); // draw the background screen
for (Path p : paths)
{
paintLine.setColor(colorsMap.get(p));
paintLine.setStrokeWidth(widthMap.get(p));
canvas.drawPath(p, paintLine);
}
paintLine.setColor(selectedColor);
paintLine.setStrokeWidth(selectedWidth);
canvas.drawPath(mPath, paintLine);
if (ConvertCanvasToBitmap == true)
{
//Method 1
// RelativeLayout page = (RelativeLayout) findViewById(R.id.doodleView);
// Bitmap screenshot = Bitmap.createBitmap(page.getWidth(), page.getHeight(), Config.ARGB_8888);
// bitmap = screenshot;
// ConvertCanvasToBitmap = false;
//Method 2
Bitmap screenshot2;
layout(0, 0, DoodlzViewWidth, DoodlzViewHeight);
setDrawingCacheEnabled(true);
screenshot2 = Bitmap.createBitmap(getDrawingCache()); // LINE 148
setDrawingCacheEnabled(false);
bitmap = screenshot2;
}
}
you need to create the bitmap from that view
please refer to drawingcache like here
Android 2.1 View's getDrawingCache() method always returns null
now try to flip this bitmap
I'm trying to draw to a Bitmap so I can put my custom view inside an imageView.The code within the onDraw method is:
public void onDraw(Canvas canvas) {
Bitmap drawGraph = Bitmap.createBitmap(canvas.getWidth(),canvas.getHeight(),Bitmap.Config.ARGB_8888);
canvas.setBitmap(drawGraph);
canvas.drawBitmap(drawGraph, 0, 0, bgPaint);
My problem is that if I try to use a Bitmap in this way, I just get a black screen. I know that the rest of my code works as it displays if I don't try to draw to a bitmap.
If I comment out the line
canvas.setBitmap(drawGraph);
Then everything works perfectly, so this is the problem but I dont know why.
where am I going wrong?
Turns out I did have to create a second canvas. My working code is below just for anyone who might need it:
public void onDraw(Canvas canvas) {
Canvas singleUseCanvas = new Canvas();
drawGraph = Bitmap.createBitmap(canvas.getWidth(),canvas.getHeight(),Bitmap.Config.ARGB_8888);
singleUseCanvas.setBitmap(drawGraph);
canvas.drawBitmap(drawGraph, 100, 100, bgPaint);
I think is the canvas and canvas2 dichotomy. Try to use only canvas2 (the parameter) to draw.
AFAIK The most efficient way is to override drawable setters.
#Override
public void setImageBitmap(Bitmap bm) {
bmp = bm;
}
#Override
public void setImageDrawable(Drawable drawable) {
try {
bmp = ((BitmapDrawable) drawable).getBitmap();
} catch (Exception e){
log(e.toString());
}
}
Good Day Everyone
I was hoping if you could help me understand the concepts of understanding how to add an image into a canvas on a OnTouchEvent implemented on a View. So far, this is what i've come up with.
parent is the Activity where in this customized view is instantiated and is added into.
#Override
protected void onDraw(Canvas canvas)
{
// TODO Auto-generated method stub
super.onDraw(canvas);
}
public void insertImage()
{
if (parent.selected_icon.contentEquals("image1"))
{
image = getResources().getDrawable(R.drawable.image1);
}
else if (parent.selected_icon.contentEquals("image1"))
{
image = getResources().getDrawable(R.drawable.image2);
}
else if (parent.selected_icon.contentEquals("iamge3"))
{
image = getResources().getDrawable(R.drawable.image3);
}
Rect srcRect = new Rect(0, 0, image.getIntrinsicWidth(),
image.getIntrinsicHeight());
Rect dstRect = new Rect(srcRect);
Bitmap bitmap = Bitmap.createBitmap(image.getIntrinsicWidth(),
image.getIntrinsicHeight(), Bitmap.Config.ALPHA_8);
Canvas canvas = new Canvas();
canvas.drawBitmap(bitmap, srcRect, dstRect, null);
invalidate();
}
When you want to draw over a view, you have to do that in onDraw(), using the Canvas passed there. That Canvas is already bound to the Bitmap that is the actual drawing of your view.
I had to do something similar and my approach was like this:
I had a list of "things to be drawn over the view" as a member of the class.
whenever I added something to that list, I called invalidate(), so that onDraw() would get called.
My onDraw() looked like this:
...
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // the default drawing
for(ThingToBeDrawn thing : mListOfThingsToBeDrawn) {
thing.drawThing(canvas); // draw each thing over the view
}
}
A Canvas is just a tool used to draw a Bitmap, and it works quite differently than SurfaceView.