I am trying to create app for Display testing .Redmi Mobile- Display test screenShot
For that, I am using Canvas. You can check below code for more details.
I am trying to use this function but app stuck during execution of this code
boolean CheckPixelColor() {
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
if (bitmapData.getPixel(i, j) == Color.MAGENTA) {
System.out.println("Not Done");
return false;
}
}
}
return true;
}
This code is working. This code is for create path during initialization and erase that later.
public class DrawingView extends View {
private static final float TOUCH_TOLERANCE = 4;
private Bitmap bitmap;
private Canvas canvas;
private Path path;
private Paint bitmapPaint;
private Paint paint;
private boolean drawMode;
private float x, y;
private float penSize = 20;
private float eraserSize = 50;
private Bitmap bitmapData;
Context context;
public DrawingView(Context c) {
this(c, null);
}
public DrawingView(Context c, AttributeSet attrs) {
this(c, attrs, 0);
}
public DrawingView(Context c, AttributeSet attrs, int defStyle) {
super(c, attrs, defStyle);
this.context = c;
init();
}
private void init() {
path = new Path();
bitmapPaint = new Paint(Paint.DITHER_FLAG);
paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(penSize);
drawMode = true;
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
this.setDrawingCacheEnabled(true);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (bitmap == null) {
bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}
canvas = new Canvas(bitmap);
canvas.drawColor(Color.TRANSPARENT);
Init();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
canvas.drawPath(path, paint);
bitmapData = this.getDrawingCache(true);
}
private void touchStart(float x, float y) {
path.reset();
path.moveTo(x, y);
this.x = x;
this.y = y;
canvas.drawPath(path, paint);
}
private void touchMove(float x, float y) {
float dx = Math.abs(x - this.x);
float dy = Math.abs(y - this.y);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
path.quadTo(this.x, this.y, (x + this.x) / 2, (y + this.y) / 2);
this.x = x;
this.y = y;
}
canvas.drawPath(path, paint);
}
private void touchUp() {
path.lineTo(x, y);
canvas.drawPath(path, paint);
path.reset();
if (drawMode) {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
} else {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!drawMode) {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
} else {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
}
touchStart(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touchMove(x, y);
if (!drawMode) {
path.lineTo(this.x, this.y);
path.reset();
path.moveTo(x, y);
}
canvas.drawPath(path, paint);
invalidate();
break;
case MotionEvent.ACTION_UP:
touchUp();
invalidate();
break;
default:
break;
}
return true;
}
public void initializePen() {
drawMode = true;
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(penSize);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
}
public void initializeEraser() {
drawMode = false;
paint.setColor(Color.parseColor("#f4f4f4"));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(eraserSize);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
public void clear() {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
invalidate();
}
#Override
public void setBackgroundColor(int color) {
if (canvas == null) {
canvas = new Canvas();
}
canvas.drawColor(color);
super.setBackgroundColor(color);
}
public void setEraserSize(float size) {
eraserSize = size;
initializeEraser();
}
public void setPenSize(float size) {
penSize = size;
initializePen();
}
public float getEraserSize() {
return eraserSize;
}
public float getPenSize() {
return penSize;
}
public void setPenColor(#ColorInt int color) {
paint.setColor(color);
}
public #ColorInt
int getPenColor() {
return paint.getColor();
}
public void loadImage(Bitmap bitmap) {
this.bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
canvas.setBitmap(this.bitmap);
bitmap.recycle();
invalidate();
}
public boolean saveImage(String filePath, String filename, Bitmap.CompressFormat format,
int quality) {
if (quality > 100) {
Log.d("saveImage", "quality cannot be greater that 100");
return false;
}
File file;
FileOutputStream out = null;
try {
switch (format) {
case PNG:
file = new File(filePath, filename + ".png");
out = new FileOutputStream(file);
return bitmap.compress(Bitmap.CompressFormat.PNG, quality, out);
case JPEG:
file = new File(filePath, filename + ".jpg");
out = new FileOutputStream(file);
return bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out);
default:
file = new File(filePath, filename + ".png");
out = new FileOutputStream(file);
return bitmap.compress(Bitmap.CompressFormat.PNG, quality, out);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
void Init() {
initializePen();
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
System.out.println("height: " + height);
System.out.println("width: " + width);
path.reset();
path.moveTo(0, 0);
path.lineTo(0, height);
path.lineTo(width, height);
path.lineTo(width, 0);
path.lineTo(0, 0);
path.lineTo(width, height);
path.moveTo(width, 0);
path.lineTo(0, height);
canvas.drawPath(path, paint);
invalidate();
initializeEraser();
}
boolean CheckPixelColor() {
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
if (bitmapData.getPixel(i, j) == Color.MAGENTA) {
System.out.println("Not Done");
}
}
}
return false;
}
}
Now I want to check that all path has been erased.
Thanks #Radhey , As per your suggestion now i am comparing complete bitmap with starting bitmap and now it s working .
Working code :
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (bitmap == null) {
bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
bitmapSateSave = bitmap;
}
canvas = new Canvas(bitmap);
canvas.drawColor(Color.TRANSPARENT);
Init();
}
private void init() {
path = new Path();
bitmapPaint = new Paint(Paint.DITHER_FLAG);
paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(penSize);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
this.setDrawingCacheEnabled(true); // Enable Cache
}
#Override
protected void onDraw(Canvas canvas)
{ super.onDraw(canvas);
canvas.drawBitmap(bitmap,0,0,bitmapPaint);
canvas.drawPath(path,paint);
bitmapData = this.getDrawingCache(true); // Save Bitmap data
}
boolean CompareBitmap() {
if (bitmapData.sameAs(bitmapSateSave)) {
System.out.println("Same");
} else {
System.out.println("Different"); }
return false;
}
Related
How can we Convert Bitmap to Path and draw on canvas in Android
I want to create a mask using the path that we get and overlay it over another image, I dont want another bitmap, but a canvas where we have the bitmap as a path and then use the drawingview to edit it .
I have an Image ,
I want to convert it to a Path and draw it on a Canvas in in Android Like this
The Drawing view is a custom view Like this
public class DrawingView extends View {
private static final float TOUCH_TOLERANCE = 4;
private Bitmap bitmap;
private Canvas canvas;
private Path path;
private Paint bitmapPaint;
private Paint paint;
private boolean drawMode;
private float x, y;
private float penSize = 10;
private float eraserSize = 10;
public DrawingView(Context c) {
this(c, null);
}
public DrawingView(Context c, AttributeSet attrs) {
this(c, attrs, 0);
}
public DrawingView(Context c, AttributeSet attrs, int defStyle) {
super(c, attrs, defStyle);
init();
}
private void init() {
path = new Path();
bitmapPaint = new Paint(Paint.DITHER_FLAG);
paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(penSize);
drawMode = true;
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
}
#Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (bitmap == null) {
bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}
canvas = new Canvas(bitmap);
canvas.drawColor(Color.TRANSPARENT);
}
#Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
canvas.drawPath(path, paint);
}
private void touchStart(float x, float y) {
path.reset();
path.moveTo(x, y);
this.x = x;
this.y = y;
canvas.drawPath(path, paint);
}
private void touchMove(float x, float y) {
float dx = Math.abs(x - this.x);
float dy = Math.abs(y - this.y);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
path.quadTo(this.x, this.y, (x + this.x) / 2, (y + this.y) / 2);
this.x = x;
this.y = y;
}
canvas.drawPath(path, paint);
}
private void touchUp() {
path.lineTo(x, y);
canvas.drawPath(path, paint);
path.reset();
if (drawMode) {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
} else {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
}
#Override public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!drawMode) {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
} else {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
}
touchStart(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touchMove(x, y);
if (!drawMode) {
path.lineTo(this.x, this.y);
path.reset();
path.moveTo(x, y);
}
canvas.drawPath(path, paint);
invalidate();
break;
case MotionEvent.ACTION_UP:
touchUp();
invalidate();
break;
default:
break;
}
return true;
}
public void initializePen() {
drawMode = true;
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(penSize);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
}
public void initializeEraser() {
drawMode = false;
paint.setColor(Color.parseColor("#f4f4f4"));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(eraserSize);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
public void clear() {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
invalidate();
}
#Override public void setBackgroundColor(int color) {
if (canvas == null) {
canvas = new Canvas();
}
canvas.drawColor(color);
super.setBackgroundColor(color);
}
public void setEraserSize(float size) {
eraserSize = size;
initializeEraser();
}
public void setPenSize(float size) {
penSize = size;
initializePen();
}
public float getEraserSize() {
return eraserSize;
}
public float getPenSize() {
return penSize;
}
public void setPenColor(#ColorInt int color) {
paint.setColor(color);
}
public #ColorInt int getPenColor() {
return paint.getColor();
}
public void loadImage(Bitmap bitmap) {
this.bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
canvas.setBitmap(this.bitmap);
bitmap.recycle();
invalidate();
}
public boolean saveImage(String filePath, String filename, Bitmap.CompressFormat format,
int quality) {
if (quality > 100) {
Log.d("saveImage", "quality cannot be greater that 100");
return false;
}
File file;
FileOutputStream out = null;
try {
switch (format) {
case PNG:
file = new File(filePath, filename + ".png");
out = new FileOutputStream(file);
return bitmap.compress(Bitmap.CompressFormat.PNG, quality, out);
case JPEG:
file = new File(filePath, filename + ".jpg");
out = new FileOutputStream(file);
return bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out);
default:
file = new File(filePath, filename + ".png");
out = new FileOutputStream(file);
return bitmap.compress(Bitmap.CompressFormat.PNG, quality, out);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
}
The main problem is converting the image to path to draw it on canvas which can be used by the drawing view
I've create an Activity for draw a sign, save it into internal storage, reaload it and continue to draw starting from Bitmap saved.
At first launch the file is not loaded because it doesn't exists. So I draw and when I click back to previos Activity I save the Bitmap in file. From second launch the file exists and it is correctly loaded (I view image from debug in android studio). The problem is that the canvas appear blank. I have not Exception. Any ideas?
public class PhysicalSignatureActivity extends AppCompatActivity {
DrawingView dv ;
private Paint mPaint;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitle("Physical sign");
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(3);
if (!(getIntent().getStringExtra("filename") == null)){
try {
InputStream inputStream = getApplicationContext().openFileInput(getIntent().getStringExtra("filename"));
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
Bitmap bitmap_mutable = bitmap.copy(Bitmap.Config.ARGB_8888, true);
dv = new DrawingView(this,bitmap_mutable);
} catch (FileNotFoundException ex) {
}
} else {
dv = new DrawingView(this);
}
setContentView(dv);
}
#Override
public void onBackPressed() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);
builder.setMessage("Save sign?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String filename = UUID.randomUUID().toString()+".png";
FileOutputStream outputStream = null;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
dv.buildDrawingCache();
Bitmap bitmap = dv.getDrawingCache();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.close();
} catch (FileNotFoundException ex) {
} catch (IOException e) {
e.printStackTrace();
} finally {
Intent i = new Intent(PhysicalSignatureActivity.this, PerformanceActivity.class);
i.putExtra("performance_id",getIntent().getStringExtra("performance_id"));
i.putExtra("authentication_token",getIntent().getStringExtra("authentication_token"));
i.putExtra("filename",filename);
startActivity(i);
finish();
}
}
});
builder.setNegativeButton("No",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
AlertDialog alert=builder.create();
alert.show();
}
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);
}
public DrawingView(Context c, Bitmap b) {
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);
mBitmap = b;
mCanvas = new Canvas();
mCanvas.drawBitmap(mBitmap,0,0,mBitmapPaint);
}
#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);
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;
}
}
}
I am trying draw on the image. Now I am using following class.
public class DrawingPaint extends View implements View.OnTouchListener {
private Canvas mCanvas;
private Path mPath;
private Paint mPaint, mBitmapPaint;
public ArrayList<PathPoints> paths = new ArrayList<PathPoints>();
private ArrayList<PathPoints> undonePaths = new ArrayList<PathPoints>();
private Bitmap mBitmap;
private int color;
private int x, y;
private String textToDraw = null;
private boolean isTextModeOn = false;
int lastColor = 0xFFFF0000;
static final float STROKE_WIDTH = 15f;
public DrawingPaint(Context context/*, int color*/) {
super(context);
//this.color = color;
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
/*mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(STROKE_WIDTH);
mPaint.setTextSize(30);
mPath = new Path();
paths.add(new PathPoints(mPath, color, false));
mCanvas = new Canvas();*/
}
public void colorChanged(int color) {
this.color = color;
mPaint.setColor(color);
}
public void setColor(int color) {
mPaint = new Paint();
this.color = color;
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(color);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(STROKE_WIDTH);
mPaint.setTextSize(30);
mPath = new Path();
paths.add(new PathPoints(mPath, color, false));
mCanvas = new Canvas();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// mBitmap = AddReportItemActivity.mPhoto;
mBitmap = CustomGalleryHandler.getmInstance().getBitmapSend();
float xscale = (float) w / (float) mBitmap.getWidth();
float yscale = (float) h / (float) mBitmap.getHeight();
if (xscale > yscale) // make sure both dimensions fit (use the
// smaller scale)
xscale = yscale;
float newx = (float) w * xscale;
float newy = (float) h * xscale; // use the same scale for both
// dimensions
// if you want it centered on the display (black borders)
mBitmap = Bitmap.createScaledBitmap(mBitmap, this.getWidth(),
this.getHeight(), true);
// mCanvas = new Canvas(mBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
for (PathPoints p : paths) {
mPaint.setColor(p.getColor());
Log.v("", "Color code : " + p.getColor());
if (p.isTextToDraw()) {
canvas.drawText(p.textToDraw, p.x, p.y, mPaint);
} else {
canvas.drawPath(p.getPath(), mPaint);
}
}
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 0;
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;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath = new Path();
paths.add(new PathPoints(mPath, color, false));
}
private void drawText(int x, int y) {
this.x = x;
this.y = y;
paths.add(new PathPoints(color, textToDraw, true, x, y));
// mCanvas.drawText(textToDraw, x, y, mPaint);
}
#Override
public boolean onTouch(View arg0, MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!isTextModeOn) {
touch_start(x, y);
invalidate();
}
break;
case MotionEvent.ACTION_MOVE:
if (!isTextModeOn) {
touch_move(x, y);
invalidate();
}
break;
case MotionEvent.ACTION_UP:
if (isTextModeOn) {
drawText((int) x, (int) y);
invalidate();
} else {
touch_up();
invalidate();
}
break;
}
return true;
}
public void onClickUndo() {
try {
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size() - 1));
invalidate();
} else {
}
} catch (Exception e) {
e.toString();
}
}
public void onClickRedo() {
try {
if (undonePaths.size() > 0) {
paths.add(undonePaths.remove(undonePaths.size() - 1));
invalidate();
} else {
}
} catch (Exception e) {
e.toString();
}
}
}
The following method is used in Activity extended class
public class GalleryImageFullScreen extends Activity implements View.OnClickListener {
private ImageView mFullScreenImage;
private ImageView /*mWhiteColor,*//* mGreenColor, mSkyBlueColor, mYellowColor, mRedColor, mBlackColor,*/ mUndoIcon,
mPaintImageSave, mPaintImageDelete, mRedoIcon;
RoundedImageView mWhiteColor, mGreenColor, mSkyBlueColor, mYellowColor, mRedColor, mBlackColor;
// private Signature mSignature;
private RelativeLayout mDrawLayout;
private DrawingPaint mDrawViewSignature;
private AlertDialog mAlertDialog = null;
Bitmap bitmapss;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.gallery_fullscreen);
super.onCreate(savedInstanceState);
mUndoIcon =(ImageView)findViewById(R.id.erase_icon);
mFullScreenImage=(ImageView)findViewById(R.id.img_fullscreen);
mDrawLayout=(RelativeLayout)findViewById(R.id.img_fullscreen_layout);
mPaintImageSave=(ImageView)findViewById(R.id.paint_img_save);
mPaintImageDelete=(ImageView)findViewById(R.id.paint_img_delete);
mRedoIcon=(ImageView)findViewById(R.id.img_redo);
mWhiteColor.setOnClickListener(this);
mGreenColor.setOnClickListener(this);
mSkyBlueColor.setOnClickListener(this);
mYellowColor.setOnClickListener(this);
mRedColor.setOnClickListener(this);
mBlackColor.setOnClickListener(this);
mUndoIcon.setOnClickListener(this);
mPaintImageSave.setOnClickListener(this);
mPaintImageDelete.setOnClickListener(this);
mRedoIcon.setOnClickListener(this);
// mSignature = new Signature(GalleryImageFullScreen.this, null);
try {
Intent i=getIntent();
Bitmap image = null;
image = BitmapFactory.decodeFile(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
CustomGalleryHandler.getmInstance().setBitmapSend(image);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(new File(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen()).getAbsolutePath(), options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
mDrawLayout.getLayoutParams().width = imageWidth;
mDrawLayout.getLayoutParams().height = imageHeight;
//RelativeLayout.LayoutParams layout_description = new RelativeLayout.LayoutParams(imageWidth,imageHeight);
// mDrawLayout.setLayoutParams(layout_description);
Bitmap mSignatureBitmapImage = Bitmap.createBitmap(imageWidth,
imageHeight, Bitmap.Config.ARGB_8888);
mDrawViewSignature = new DrawingPaint(GalleryImageFullScreen.this/*, lastColor*/);
mDrawViewSignature.setDrawingCacheEnabled(true);
mDrawViewSignature.measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
mDrawViewSignature.layout(0, 0, mDrawViewSignature.getMeasuredWidth(),
mDrawViewSignature.getMeasuredHeight());
mDrawViewSignature.buildDrawingCache(true);
Canvas canvas = new Canvas(mSignatureBitmapImage);
Drawable bgDrawable = mDrawLayout.getBackground();
if (bgDrawable != null) {
bgDrawable.draw(canvas);
} else {
canvas.drawColor(Color.WHITE);
}
mDrawLayout.draw(canvas);
ByteArrayOutputStream bs = new ByteArrayOutputStream();
mSignatureBitmapImage.compress(Bitmap.CompressFormat.PNG, 50, bs);
}
catch (Exception e)
{
Logger.d("", "" + e.toString());
}
mDrawViewSignature.setColor(getResources().getColor(R.color.black));
mDrawLayout.addView(mDrawViewSignature);
}
#Override
public void onClick(View v) {
switch (v.getId())
{
case R.id.paint_img_save:
try {
Bitmap editedImage = Bitmap.createBitmap(mDrawViewSignature
.getDrawingCache());
editedImage = Bitmap.createScaledBitmap(editedImage, mDrawViewSignature.getWidth(), mDrawViewSignature.getHeight(),
true);
if(editedImage!=null) {
final Bitmap finalEditedImage = editedImage;
mAlertDialog = Alerts.getInstance().createConfirmationDialog(this, this.getResources().getString(R.string.painting_image_save), new View.OnClickListener() {
#Override
public void onClick(View v) {
/*Bitmap editedImage = Bitmap.createBitmap(mDrawViewSignature
.getDrawingCache());
editedImage = Bitmap.createScaledBitmap(editedImage, mDrawViewSignature.getWidth(), mDrawViewSignature.getHeight(),
true);*/
//saveImageToInternalStorage(finalEditedImage);
storeImage(finalEditedImage);
PreferenceForCustomCamera.getInstance().setEditedURL(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
callToGalleyActivity();
mAlertDialog.dismiss();
}
});
mAlertDialog.show();
}
}
catch (Exception e)
{
Logger.d("paint_img_save",""+e.toString());
}
break;
case R.id.paint_img_delete:
try {
if (!PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen().equals("") && !PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen().equals("null")) {
mAlertDialog = Alerts.getInstance().createConfirmationDialog(this, this.getResources().getString(R.string.painting_image_path_delete), new View.OnClickListener() {
#Override
public void onClick(View v) {
// DatabaseHelper.getInstance().deleteParticularVideoPath(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
CustomGalleryHandler.getmInstance().deleteParticularImages(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
CustomGalleryHandler.getmInstance().deleteParticularImageFromInternalStorage(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
callToGalleyActivity();
mAlertDialog.dismiss();
}
});
}
mAlertDialog.show();
}
catch (Exception e)
{
Logger.d("paint_img_delete",""+e.toString());
}
break;
case R.id.img_redo:
mDrawViewSignature.onClickRedo();
break;
}
}
private void saveImageToInternalStorage(Bitmap finalBitmap) {
try {
File myDir = new File(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
myDir.mkdirs();
Logger.d("ListOfPhoto",""+myDir.getAbsolutePath());
Logger.d("ListOfPhotoRename",""+PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
for(File files: myDir.listFiles())
{
Logger.d("ListOfPhoto",""+files.getAbsolutePath());
Logger.d("ListOfPhotoRename",""+PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
}
Picasso.with(getApplicationContext()).load(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen()).skipMemoryCache();
/*Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + "3680" + ".png";
File file = new File(myDir, fname);
if (file.exists()) {
file.delete();
}*/
try {
if(myDir.exists())
{
myDir.delete();
}
FileOutputStream out = new FileOutputStream(myDir);
finalBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
catch (Exception e)
{
Logger.d("saveImageToInternalStorage",""+e.toString());
}
}
private void storeImage(Bitmap image) {
File pictureFile = new File(PreferenceForCustomCamera.getInstance().getImagePathForGalleryFullScreen());
if (pictureFile.exists()) {
pictureFile.delete();
}
//clearImageDiskCache();
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Logger.d("GalleryImage", "File not found: " + e.getMessage());
} catch (IOException e) {
Logger.d("GalleryImage", "Error accessing file: " + e.getMessage());
}
}
public boolean clearImageDiskCache() {
File cache = new File(getApplicationContext().getCacheDir(), "picasso-cache");
if (cache.exists() && cache.isDirectory()) {
return deleteDir(cache);
}
return false;
}
public static boolean deleteDir(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
// The directory is now empty so delete it
return dir.delete();
}
}
The following code used in my xml for draw.
<RelativeLayout
android:id="#+id/img_fullscreen_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/edit_components_bar"
android:layout_centerHorizontal="true">
<ImageView
android:id="#+id/img_fullscreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"/>
</RelativeLayout>
It is working fine when I use Landscape images. But when I use Portrait image, image getting stretched. Please let me know how to make the canvas fit to the image.
Thanks in advance
I alter this code:
Matrix m = new Matrix();
RectF inRect = new RectF(0, 0, imageWidth, imageHeight);
RectF outRect = new RectF(0, 0, imageWidth-10, imageHeight-10);
m.setRectToRect(inRect, outRect, Matrix.ScaleToFit.CENTER);
Bitmap mSignatureBitmapImage = Bitmap.createBitmap(image,0,0,imageWidth,
imageHeight, m,true);
I used this code also. But Not working:
Matrix m = mFullScreenImage.getImageMatrix();
RectF drawableRect = new RectF(0, 0, imageWidth, imageHeight);
RectF viewRect = new RectF(0, 0, mFullScreenImage.getWidth(), mFullScreenImage.getHeight());
m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER);
Bitmap mSignatureBitmapImage = Bitmap.createBitmap(image,0,0,imageWidth,
imageHeight, m,true);
Am not performing Undo/Redo operation canvas in this code. When am use the array list for removing the postion then it not work and during changing the color of paint from color picker the previous drawing color has been also change.
I am not understanding that how to perform UNDO/REDO for this.
So plz help
//This is main class
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView (mView = new MyView(this));
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFFFF0000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4);
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
}
//And MyView class is
public class MyView extends View {
private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
ArrayList<Path> paths = new ArrayList<Path>();
ArrayList<Path> undonePaths = new ArrayList<Path>();
public MyView(Context c)
{
super(c);
mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
// mCanvas.setBackgroundResource(0xFFFFFFFF);
mCanvas.drawColor (0xFFFFFFFF);
paths.add(mPath);
}
public MyView (Context c, int color)
{
super(c);
mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mCanvas.drawColor (color);
paths.add(mPath);
}
#Override protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
}
#Override protected void onDraw(Canvas canvas)
{
canvas.drawColor(0xFF000000);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
for(Path p: paths)
{
canvas.drawPath(p, mPaint);
}
}
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;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, mPaint);
paths.add(mPath);
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;
}
public void clear ()
{
Paint p = new Paint();
p.setAntiAlias(true);
p.setDither(true);
p.setColor(0xFFFFFFFF);
mCanvas.drawPaint (p);
}
public void drawImage (int resourceId)
{
Bitmap _scratch = BitmapFactory.decodeResource(getResources(), resourceId);
mCanvas.drawBitmap(_scratch, 0, 0, null);
}
public void undo() {
// TODO Auto-generated method stub
mCanvas.drawCircle(posX, posY, 100, mPaint);
Toast.makeText(getApplicationContext(), "Hello", 1000).show();
if (paths.size()>0)
{
undonePaths.add(paths.remove(paths.size()-1));
mView.invalidate();
Toast.makeText(getApplicationContext(), "Undo", 1000).show();
}
else
{
Toast.makeText(getApplicationContext(), "Not", 1000).show();
}
}
public void redo() {
// TODO Auto-generated method stub
if (undonePaths.size()>0)
{
paths.add(undonePaths.remove(undonePaths.size()-1));
invalidate();
}
else
{
}
}
public void saveAsJpg (File f)
{
String fname = f.getAbsolutePath ();
FileOutputStream fos = null;
try {
fos = new FileOutputStream (f);
mBitmap.compress (CompressFormat.JPEG, 95, fos);
} catch (Throwable ex) {
ex.printStackTrace ();
}
} // end saveAsJpg
} // end MyView
} // end class FingerPaint
this working code .I test it on my own app and it is working very good.
May be it help u.Please comment on it.
public class Main extends Activity implements OnColorChangedListener {
//public static int selectedColor = Color.BLACK;
public static ArrayList<Path> mMaindialog;
// private ArrayList<Path> undonePaths;
// public int selectedcolor;
private static final String COLOR_PREFERENCE_KEY = "color";
private FrameLayout relativelayout;
static String sdpath,location;
Boolean i;
// Instance variables
private Bitmap mBitmap=null;
Bitmap bitmap;
private Paint mPaint, mBitmapPaint, mPaint1;
private MyView mView;
ImageView idd;
// private Path mPath;
int slll = Color.BLACK;
Bitmap map=ListView5.bMap;
private Button ClearPaint, Colorpaint;
Ghostdatabase gost;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
idd=(ImageView)findViewById(R.id.imageView1);
relativelayout = (FrameLayout) findViewById(R.id.frameLayout);
DisplayMetrics metrics = getBaseContext().getResources()
.getDisplayMetrics();
int w = metrics.widthPixels;
int h = metrics.heightPixels;
System.out.println(" width " + w);
System.out.println(" height " + h);
mView = new MyView(this, w, h);
mView.setDrawingCacheEnabled(true);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4);
ClearPaint = (Button) findViewById(R.id.ne);
ClearPaint.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// mBitmap.eraseColor(Color.TRANSPARENT);
// mPath.reset();
// mView.invalidate();
mView.onClickUndo();
}
});
Button save22 = (Button) findViewById(R.id.save);
save22.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
File cacheDir;
Toast.makeText(Main.this, "Photo", 500).show();
Bitmap icon;
relativelayout.setDrawingCacheEnabled(true);
icon = Bitmap.createBitmap(relativelayout.getDrawingCache());
Bitmap bitmap = icon;
relativelayout.setDrawingCacheEnabled(false);
// File mFile1 = Environment.getExternalStorageDirectory();
Date d = new Date();
String fileName = d.getTime() + "mg1.jpg";
File storagePath = (Environment.getExternalStorageDirectory());
File dest = new File(storagePath + "/CityAppImages");
if (!dest.exists()) {
dest.mkdirs();
}
File mFile2 = new File(dest, fileName);
sdpath = mFile2.getAbsolutePath();
Log.d("qqqqqqqqqqqqqqqqqqqqqqq", "zzzzzzzz" + sdpath);
try {
FileOutputStream outStream;
outStream = new FileOutputStream(mFile2);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
Toast.makeText(Main.this, "Photo Saved Sucessfully", 500)
.show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(Main.this, "Photo Not Saved Sucessfully",
500).show();
}
gost = new Ghostdatabase(Main.this);
gost.open();
gost.insertTitle(sdpath);
}
});
Button view = (Button) findViewById(R.id.listtt);
view.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent ii = new Intent(Main.this, ListView5.class);
startActivity(ii);
}
});
Button Colorpaint = (Button) findViewById(R.id.Color);
Colorpaint.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int color = PreferenceManager.getDefaultSharedPreferences(
Main.this).getInt(COLOR_PREFERENCE_KEY, Color.WHITE);
// int _color = R.color.red;
new ColorPickerDialog(v.getContext(),
new OnColorChangedListener() {
public void colorChanged(int color) {
mPaint.setColor(color);
slll = color;
Log.i("TAG", "mpaint one" + mPaint);
}
}, mPaint.getColor()).show();
Log.i("TAG", "mpaint two" + mPaint);
}
});
relativelayout.addView(mView);
}
// //////////******************* Pinting view
// *******************///////////////////
public class MyView extends View implements OnTouchListener {
private Map<Path, Integer> colorsMap = new HashMap<Path, Integer>();
private ArrayList<Path> mMaindialog = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
int colorPicked = slll;
// Paint mPaint1;
private Canvas mCanvas;
private Path mPath;
public MyView(Context c, int w, int h) {
super(c);
if(GlobalVariable.impath==1)
{
Log.d("","111111"+GlobalVariable.impath);
System.out.println(GlobalVariable.impath);
Intent ii = getIntent();
location = ii.getStringExtra("IMAGE");
// bitmap.recycle();
Log.d("","location"+location);
bitmap = BitmapFactory.decodeFile(location);
mBitmap = Bitmap.createScaledBitmap(bitmap,300, 300,false);
Log.d("hhhhhhhhhhhhhhhssssssss","mBitmap"+mBitmap);
//mBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
// idd.setImageBitmap(mBitmap);
Log.d("hhhhhhhhhhhhhhhssssssss","GlobalVariable.impath"+GlobalVariable.impath);
}
else if(GlobalVariable.impath==2){
//bitmap.recycle();
Log.d("","22222222222222222222222"+GlobalVariable.impath);
bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.base);
mBitmap = Bitmap.createScaledBitmap(bitmap,100, 100, false);
//mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Log.d("hhhhhhhhhhhhhhhssssssss1111111","mBitmap"+mBitmap);
}
//
mCanvas = new Canvas(mBitmap);
mPath = new Path();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
for (Path p : mMaindialog) {
mPaint.setColor(colorsMap.get(p));
canvas.drawPath(p, mPaint);
}
mPaint.setColor(slll);
canvas.drawPath(mPath, mPaint);
}
// //////************touching evants for painting**************///////
private float mX, mY;
private static final float TOUCH_TOLERANCE = 0;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
undonePaths.clear();
}
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;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath = new Path();
mPath.reset();
mMaindialog.add(mPath);
}
#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();
undonePaths.clear();
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
// touch_move(x, y);
// invalidate();
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;
}
invalidate();
break;
case MotionEvent.ACTION_UP:
// touch_up();
// invalidate();
mPath.lineTo(mX, mY);
mMaindialog.add(mPath);
colorsMap.put(mPath, slll);
mPath = new Path();
mPath.reset();
invalidate();
break;
}
return true;
} // end of touch events for image
private Paint createPen(int colorPicked) {
// TODO Auto-generated method stub
mPaint1 = new Paint();
mPaint1.setColor(colorPicked);
mPaint1.setAntiAlias(true);
mPaint1.setDither(true);
mPaint1.setStyle(Paint.Style.STROKE);
mPaint1.setStrokeJoin(Paint.Join.ROUND);
mPaint1.setStrokeCap(Paint.Cap.ROUND);
// mPaint1.setStrokeWidth(3);
return mPaint1;
}
public void onClickRedo() {
if (undonePaths.size() > 0) {
mMaindialog.add(undonePaths.remove(undonePaths.size() - 1));
mView.invalidate();
} else {
}
// toast the user
}
public void onClickUndo() {
if (mMaindialog.size() > 0) {
undonePaths.add(mView.mMaindialog.remove(mView.mMaindialog
.size() - 1));
mView.invalidate();
}
else {
}
}
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
return false;
}
}// end MyView
#Override
public void colorChanged(int color) {
// TODO Auto-generated method stub
PreferenceManager.getDefaultSharedPreferences(this).edit()
.putInt(COLOR_PREFERENCE_KEY, color).commit();
slll = color;
}
}
I have a relative layout on which i add a view. this is the code in the activity:
paint = (RelativeLayout) findViewById(R.id.paint);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
myView = new CustomImage(getBaseContext());
paint.addView(myView);
String imagePath = (String) getIntent().getExtras().get("selectedImagePath");
LogService.log("PaintActivity", "Imagepath: " + imagePath);
// Drawable background = BitmapDrawable.createFromPath(imagePath);
// bitmap = ((BitmapDrawable) background).getBitmap();
try {
fis = new FileInputStream(imagePath);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
mBitmap = loadBitmap(fis.getFD());
bitmap = getResizedBitmap(mBitmap, 412*2, 1024*2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
LogService.log("PaintActivity", "Bitmap = " + mBitmap);
myView.setBitmap(bitmap);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF000000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(50);
myView.setPaint(mPaint);
}
}, 50);
This is my View:
public class CustomImage extends View {
private boolean hasResized = false;
private Bitmap bitmap, bitmap2;
public Context context;
Paint paint;
private Canvas canvas;
public String text = null;
private Paint mBitmapPaint, paintText;
private Path mPath = new Path();
private float mX, mY, pX, pY, tX, tY;
private static final float TOUCH_TOLERANCE = 4;
private float screenDensity;
int height, width;
private Bitmap mBitmap;
private RandomAccessFile randomAccessFile;
private int bh;
private int bw;
public CustomImage(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public CustomImage(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CustomImage(Context context) {
super(context);
init(context);
}
private void init(Context context) {
this.context = context;
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
public void setImg(Context context, Canvas canvas, Bitmap bitmapw, int width, int height) {
bw = bitmapw.getWidth();
bh = bitmapw.getHeight();
float scaleWidth = ((float) width)/ bw;
float scaleHeight = ((float) height)/ bh;
System.out.println("CustomImage.setImg()");
bitmap = bitmapw;
}
public void setPaint(Paint paint) {
this.paint = paint;
LogService.log("in setPaint", "paint = " + paint);
}
public void setBitmap(Bitmap bitmap) throws Exception {
File file = new File("/mnt/sdcard/sample/temp.txt");
file.getParentFile().mkdirs();
randomAccessFile = new RandomAccessFile(file, "rw");
int bWidth = bitmap.getWidth();
int bHeight = bitmap.getHeight();
FileChannel channel = randomAccessFile.getChannel();
MappedByteBuffer map = channel.map(MapMode.READ_WRITE, 0, bWidth*bHeight*4);
bitmap.copyPixelsToBuffer(map);
bitmap.recycle();
this.bitmap = Bitmap.createBitmap(bWidth, bHeight, Config.ARGB_8888);
map.position(0);
this.bitmap.copyPixelsFromBuffer(map);
channel.close();
randomAccessFile.close();
// this.bitmap = bitmap;
// canvas = new Canvas();
}
public void setBitmap2(Bitmap bitmap) {
bitmap2 = bitmap;
invalidate();
}
public void getText(String text) {
this.text = text;
paintText = new Paint();
paintText.setColor(0xFFFFFFFF);
paintText.setStrokeWidth(10);
paintText.setTextSize(20);
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(bitmap, 0, 0, mBitmapPaint);
if (PaintActivity.isPic == 1) {
if (bitmap2 != null) {
canvas.drawBitmap(bitmap2, mX, mY, mBitmapPaint);
pX = mX;
pY = mY;
}
if(text != null){
canvas.drawText(text, tX, tY, paintText);
}
} else if (PaintActivity.isPic == 2) {
if(text != null){
canvas.drawText(text, mX, mY, paintText);
tX = mX;
tY = mY;
}
if (bitmap2 != null) {
canvas.drawBitmap(bitmap2, pX, pY, mBitmapPaint);
}
}else{
canvas.drawPath(mPath, paint);
if (bitmap2 != null) {
canvas.drawBitmap(bitmap2, pX, pY, mBitmapPaint);
}
if(text != null){
canvas.drawText(text, tX, tY, paintText);
}
}
}
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
canvas.drawPoint(x, y, paint);
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;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
mPath.moveTo(mX, mY);
canvas.drawPath(mPath, paint);
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;
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
System.out.println("CustomImage.onSizeChanged()");
super.onSizeChanged(w, h, oldw, oldh);
if ((w != 0) && (h != 0)) {
if (!hasResized) {
hasResized = true;
renderImage();
}
}
}
public void renderImage() {
System.out.println("======in renderimage=======w " + getMeasuredWidth() + "h " + getMeasuredHeight());
width = getMeasuredWidth();
height = getMeasuredHeight();
canvas = new Canvas(bitmap);
setImg(context, canvas, bitmap, width, height);
}
}
As you can see, I have a resizing function in the activity:
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
Now if i comment this function out of the code, the image looks normal, but not scaled. If i leave it there, then i get an ugly image, but it is resized. Example:
normal not resized: http://imgur.com/BD5Pp,YWDTi
altered but resized pic: http://imgur.com/BD5Pp,YWDTi#1
As OP stated answering my question, the bitmap is converted to RGB_565, which is a known bug in createBitmap() - #16211, fixed in Android 3.0. It affects createScaledBitmap() as well. The bitmap wouldn't look distorted if it remained ARGB_8888.
As a workaround you have to create target bitmap manually (which gives you full control of the pixel format), then create canvas attached to this bitmap and paint a scaled version of the original bitmap on it. Here's a sample from my project:
public class BitmapUtils {
private static Matrix matrix = new Matrix();
private static Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
public static final Bitmap resizeBitmap(Bitmap bitmap, float scale, Bitmap.Config targetConfig) {
int srcWidth = bitmap.getWidth();
int srcHeight = bitmap.getHeight();
int newWidth = (int) (srcWidth * scale);
int newHeight = (int) (srcHeight * scale);
float sx = newWidth / (float) srcWidth;
float sy = newHeight / (float) srcHeight;
matrix.setScale(sx, sy);
Bitmap target = Bitmap.createBitmap(newWidth, newHeight, targetConfig);
Canvas c = new Canvas(target);
c.drawBitmap(bitmap, matrix, paint);
return target;
}
}
Note: this code is not reentrant, due to global matrix instance. Also, it takes scale as parameter, but adapting it to your needs (new width/height as parameters) is trivial.