I'm trying to create a "clear all" button in my app, but it doesn't work. This is the code I use to create and use the canvas:
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
setLayerType(LAYER_TYPE_HARDWARE, null);
startActivity = System.currentTimeMillis();
setupDrawing();
}
public void setDimension (DisplayMetrics displaymetrics) {
height = displaymetrics.heightPixels;
width = displaymetrics.widthPixels;
diameter = width;
if (height < width){
diameter = height;
}
offset = (int) (0.32*diameter);
diameter -= offset;
String imageName = protocol+draw;
}
//setup drawing
private void setupDrawing(){
//prepare for drawing and setup paint stroke properties
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(5);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
//size assigned to view
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
//draw the view - will be called after touch event
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
canvas.drawRect(width/2 - diameter/2 ,
(70),
width/2 + diameter/2,
1100, drawPaint);
}
And this is the code I used to clear the screen, but pressing the button nothing showed up:
public void restoreDraw () {
drawPath = null;
canvasBitmap = Bitmap.createBitmap(width, 350, Bitmap.Config.ARGB_8888);
drawPath = new Path();
}
Should I clear the bitmap canvas, right?
You have to add requestLayout() inside restoreDraw() method.
public void restoreDraw () {
drawPath = null;
canvasBitmap = Bitmap.createBitmap(width, 350, Bitmap.Config.ARGB_8888);
drawPath = new Path();
requestLayout();
}
Related
I want to edit my drawing painted image. I am getting a bitmap image and setting it into a canvas bitmap, but the old image is not appearing. I have tried using the drawingView.refresh() and recycle() methods, but couldn't make it work.
private DrawingView mDrawingView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawing);
if(datadtlimgsItem !=null && datadtlimgsItem.getImageStr()
!=null) {
decodedString = Base64.decode(datadtlimgsItem.getImageStr(),
Base64.DEFAULT);
decodedByte = BitmapFactory.decodeByteArray(decodedString, 0,
decodedString.length);
decodedByte = Util.resize(decodedByte, 400, 100);
mDrawingView.canvasBitmap = decodedByte;
}
}
public class DrawingView extends View{
// To hold the path that will be drawn.
private Path drawPath;
// Paint object to draw drawPath and drawCanvas.
private Paint drawPaint, canvasPaint;
// initial color
private int paintColor = 0xff000000;
private int previousColor = paintColor;
// canvas on which drawing takes place.
private Canvas drawCanvas;
// canvas bitmap
public Bitmap canvasBitmap;
// Brush stroke width
private float brushSize, lastBrushSize;
// To enable and disable erasing mode.
private boolean erase = false;
public DrawingView(Context context, AttributeSet attrs){
super(context, attrs);
setUpDrawing();
}
/**
* Initialize all objects required for drawing here.
* One time initialization reduces resource consumption.
*/
private void setUpDrawing(){
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
// Making drawing smooth.
drawPaint.setAntiAlias(true);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
// Initial brush size is medium.
brushSize = getResources().getInteger(R.integer.medium_size);
lastBrushSize = brushSize;
drawPaint.setStrokeWidth(brushSize);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h,
Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// X and Y position of user touch.
float touchX = event.getX();
float touchY = event.getY();
// Draw the path according to the touch event taking place.
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawPath.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
if (erase){
drawPaint.setXfermode(new
PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();
drawPaint.setXfermode(null);
break;
default:
return false;
}
// invalidate the view so that canvas is redrawn.
invalidate();
return true;
}
public void setColor(String newColor){
// invalidate the view
invalidate();
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
previousColor = paintColor;
}
public void setBrushSize(float newSize){
float pixelAmount =
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
newSize, getResources().getDisplayMetrics());
brushSize=pixelAmount;
drawPaint.setStrokeWidth(brushSize);
}
public void setLastBrushSize(float lastSize){
lastBrushSize=lastSize;
}
public float getLastBrushSize(){
return lastBrushSize;
}
public void setErase(boolean isErase){
//set erase true or false
erase = isErase;
if(erase) {
drawPaint.setColor(Color.WHITE);
//drawPaint.setXfermode(new
PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
else {
drawPaint.setColor(previousColor);
drawPaint.setXfermode(null);
}
}
public void startNew(){
drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
invalidate();
}
}
I have a view like Paint I want to show old image getting from activity in current view and then edit my image.
image is blank but i need to show previous image here
here is saved image want to edit this image
I have a view like Paint I want to show old image getting from activity in current view and then edit my image. I have a view like Paint I want to show old image getting from activity in current view and then edit my image. I have a view like Paint I want to show old image getting from activity in current view and then edit my image. I have a view like Paint I want to show old image getting from activity in current view and then edit my image. I have a view like Paint I want to show old image getting from activity in current view and then edit my image.
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (canvasBitmap == null){
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}
drawCanvas = new Canvas(canvasBitmap);
}
I need help with this thing
I draw line on canvas and i need to be able to modify the position after it's been drawn. I search and try a lot of things, but no one seems that it works
I want to select one of the ends of the line and dragging them in another position
Can someone give me and advice?
Please try this.In this you can draw and edit the line.
class Drawing extends View{
private Canvas mCanvas = null;
private Path mPath = null;
private Paint mBitmapPaint = null;
private Bitmap mBitmap = null;
private Bitmap bit=null;
private Paint mPaint = null;
private MainActivity baseMainActivity = null;
public interface onDrawingViewSingleTap{
void onDrawingViewTap(float x , float y);
}
public Drawing(Context c) {
super(c);
baseMainActivity=(MainActivity) c;
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.YELLOW);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(6);//This sets the width of signature
Display display =baseMainActivity.getWindowManager().getDefaultDisplay();
mBitmap = Bitmap.createBitmap(display.getWidth(), display.getHeight(), Bitmap.Config.ARGB_8888);// 320*480 // For setting size of screen to draw Bitmap
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mCanvas = new Canvas(mBitmap);
onDraw(mCanvas);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
try{
canvas.drawColor(Color.TRANSPARENT);//Color.WHITE //To change background color of Application
if(bit!=null)
canvas.drawBitmap(bit, 0, 0, mBitmapPaint);
else
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
}catch(Exception e){}
if(bit==null)
canvas.drawPath(mPath, mPaint);
bit=null;
}
private float mX, mY;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x+1;
mY = y+1;
}
private void touch_upline(float x,float y) {
mPath.lineTo(mX, mY);
mCanvas.drawLine(mX, mY, x, y, mPaint);
mPath.reset();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
eraseAll();
touch_upline(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_upline(x,y);
invalidate();
break;
}
return true;
}
public void eraseAll()
{
mBitmap.eraseColor(android.graphics.Color.TRANSPARENT);
mCanvas = new Canvas(mBitmap);
}
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
RelativeLayout relativeLayout= (RelativeLayout) (findViewById(R.id.mainLayout));
relativeLayout.addView(new Drawing(this));
}
}
I want to set corner radius to imageview and control the radius on seekbar. As the seekbar progresses the corner radius should increase and vice-versa.
Currently m getting corner radius on increasing seekbar. But its not setting the imageview to its original state when seek bar is moved back.
cornerRadius.setMax(100);
cornerRadius.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
radius= progress;
for (int i = 0; i < IMGS.size(); i++) {
final PhotoView child = IMGS.get(i);
Bitmap viewCapture = null;
child.setDrawingCacheEnabled(true);
viewCapture = Bitmap.createBitmap(child.getDrawingCache());
child.setDrawingCacheEnabled(false);
child.setImageBitmap(getRoundedCornerBitmap(viewCapture,radius));
});
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
Put this class into your java package
public class CustomCornerImageVew extends AppCompatImageView {
private float radius = 20.0f;
private Path path;
private RectF rect;
public CustomCornerImageVew(Context context) {
super(context);
init();
}
public CustomCornerImageVew(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CustomCornerImageVew(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
path = new Path();
}
#Override
protected void onDraw(Canvas canvas) {
rect = new RectF(0, 0, this.getWidth(), this.getHeight());
path.addRoundRect(rect, radius, radius, Path.Direction.CW);
canvas.clipPath(path);
super.onDraw(canvas);
}
}
And Declare imageview in xml file like this
<YourPackageName.CustomCornerImageVew
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:scaleType="fitXY"
android:src="#drawable/mes" />
you can do by XML like this way
<stroke android:width="3dp"
android:color="#ff000000"/>
<padding android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp"/>
<corners android:radius="30px"/>
and pragmatically you can create rounded bitmap and set in ImageView.
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = 12;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
For Universal lazy loader you can use this wat also.
DisplayImageOptions options = new DisplayImageOptions.Builder()
.displayer(new RoundedBitmapDisplayer(25)) // default
.build();
I'm trying to draw on the my .png image, but it works very slow. If I'm drawing on the imageView without .png file it works fine. How can I solve this? As I understand I need to prevent "A LOT of drawings all the time", how can I realise this?
code:
public class Draw
extends Activity{
DrawingView dv ;
private Paint mPaint;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dv = new DrawingView(this);
setContentView(dv);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.GREEN);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
}
public class DrawingView extends View {
public int width;
public int height;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private Paint circlePaint;
private Path circlePath;
public DrawingView(Context c) {
super(c);
context=c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
circlePaint = new Paint();
circlePath = new Path();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + "/MANUAL/workflow" + "/img.png");
int targetWidth = bm.getWidth() / 1;
int targetHeight = bm.getHeight() / 1;
Matrix matrix = new Matrix();
matrix.postScale(0.7f, 0.65f);
Bitmap size = Bitmap.createBitmap(bm, 0, 0, targetWidth, targetHeight, matrix, true);
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawBitmap(size, 0, 0, paint);
canvas.drawBitmap( mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath( mPath, mPaint);
canvas.drawPath( circlePath, circlePaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
circlePath.reset();
circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
circlePath.reset();
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
Your onDraw() method should look like this:
#Override
protected void onDraw(Canvas canvas) {
paint.setColor(Color.RED);
canvas.drawBitmap(size, 0, 0, paint);
canvas.drawBitmap( mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath( mPath, mPaint);
canvas.drawPath( circlePath, circlePaint);
}
All Bitmap decoding and resizing should be done outside (in the constructor or only when the view is resized), there is no need to decode and resize it every time when the result will be same every time.
I am using the following code with the help of 'Android Universal image loader' library, but the quality of the image is very poor and I get too many skipped frames in my logcat,
here is my code, please look and help how can I improve it?
private class DownloadImageTask extends AsyncTask<String, Void,
Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
// Bitmap mIcon11 = null;
ImageLoader imageLoader = ImageLoader.getInstance();
Bitmap bitmap = imageLoader.loadImageSync(urldisplay);
Bitmap circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(shader);
Canvas c = new Canvas(circleBitmap);
c.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint);
//img1.setImageBitmap(circleBitmap);
//bmImage.setImageBitmap(circleBitmap);
return circleBitmap;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
Picasso and Volley are very good for images, I use Volley and I made a class that extends NetworkImageView and there I crop the image and make it round.
public class RoundedNetworkImageView extends NetworkImageView {
private Bitmap frame;
public RoundedNetworkImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public RoundedNetworkImageView(Context context, AttributeSet attrs) {
super(context, attrs);
// frame = BitmapFactory.decodeResource(context.getResources(), R.drawable.chat_list_profile_frame);
}
public RoundedNetworkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// frame = BitmapFactory.decodeResource(context.getResources(), R.drawable.chat_list_profile_frame);
}
#Override
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas);
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
if (b != null) {
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
// canvas.drawBitmap(frame, 0, 0, null);
}
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius)
sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
else
sbmp = bmp;
Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#FFFFFF"));
canvas.drawCircle(sbmp.getWidth() / 2 + 0.7f, sbmp.getHeight() / 2 + 0.7f, sbmp.getWidth() / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
//--------- and when I am using it public
// declaration
public RoundedNetworkImageView user_status_pic;
// getting the image from the url in an list adapter
viewHolder.user_status_pic.setImageUrl(image_url, imageLoader);
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.squareup.picasso.Transformation;
public class CircleTransform implements Transformation {
#Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size/2f;
canvas.drawCircle(r, r, r, paint);
squaredBitmap.recycle();
return bitmap;
}
#Override
public String key() {
return "circle";
}
}
try like this:
Picasso.with(context).load("url").transform(new CircleTransform()).into(target);