Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am making photo editing application, in my activity I have bitmap that is going to erase on touch when it's not zoomed or rotated its drawing perfectly but after I zoom or rotate bitmap, eraser is not erased at touched points.its erased on some other position according bitmap scaled.
how can I resolve this, please help me.
Drawingview.java
public class DrawingView extends ImageView implements View.OnTouchListener,MatrixGestureDetector.OnMatrixChangeListener {
private int ERASE = 1;
private int ZOOMTOUCH = 5;
private Matrix matrix = new Matrix();
Matrix inverse = new Matrix();
MatrixGestureDetector mgd = new MatrixGestureDetector(matrix, this);
#Override
public void onChange(Matrix matrix) {
invalidate();
}
public interface ActionListener {
void onActionCompleted(int i);
}
public void setImageBitmap(Bitmap bm) {
if (bm != null) {
bmp = bm;
orgBit = bm.copy(Bitmap.Config.ARGB_8888, true);
Bitmap2 = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);
c2 = new Canvas();
c2.setBitmap(Bitmap2);
c2.drawBitmap(bmp, 0, 0, null);
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.concat(matrix);
canvas.drawBitmap(Bitmap2,0,0, null);
if (c2 != null) {
Paint p;
if (!updateOnly) {
if (isTouched) {
paint = getPaintByMode(MODE, brushSize);
c2.drawPath(tPath, paint);
isTouched = false;
} else if (curIndx >= 0 && drawOnLasso) {
redrawCanvas();
}
}
if (MODE == ERASE) {
p = new Paint();
p.setColor(SupportMenu.CATEGORY_MASK);
erPaint.setStrokeWidth(updatebrushsize(erps, scale));
canvas.drawCircle(f887X, f888Y, (float) (brushSize / 2), erPaint);
canvas.drawCircle(f887X, f888Y + ((float) offset), updatebrushsize(ImageUtils.dpToPx(getContext(), 7), scale), p);
}
if (MODE == ZOOMTOUCH) {
}
updateOnly = false;
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (MODE == ERASE) {
f887X = event.getX();
f888Y = event.getY() - ((float) offset);
isTouched = true;
switch (event.getAction()) {
case 0:
paint.setStrokeWidth((float) brushSize);
tPath = new Path();
tPath.moveTo(f887X, f888Y);
drawPath.moveTo(f887X, f888Y);
invalidate();
break;
case 1:
drawPath.lineTo(f887X, f888Y);
tPath.lineTo(f887X, f888Y);
invalidate();
changesIndx.add(curIndx + 1, new Path(tPath));
brushIndx.add(curIndx + 1, Integer.valueOf(brushSize));
modeIndx.add(curIndx + 1, Integer.valueOf(MODE));
vectorPoints.add(curIndx + 1, null);
lassoIndx.add(curIndx + 1, Boolean.valueOf(insidCutEnable));
tPath.reset();
curIndx++;
clearNextChanges();
break;
case 2:
drawPath.lineTo(f887X, f888Y);
tPath.lineTo(f887X, f888Y);
invalidate();
break;
default:
return false;
}
}
if (MODE == ZOOMTOUCH) {
matrix.invert(inverse);
float[] pts = {event.getX(), event.getY()};
inverse.mapPoints(pts);
mgd.onTouchEvent(event);
}
return true;
}
}
class MatrixGestureDetector {
private static final String TAG = "MatrixGestureDetector";
private int ptpIdx = 0;
private Matrix mTempMatrix = new Matrix();
private Matrix mMatrix;
private OnMatrixChangeListener mListener;
private float[] mSrc = new float[4];
private float[] mDst = new float[4];
private int mCount;
interface OnMatrixChangeListener {
void onChange(Matrix matrix);
}
public MatrixGestureDetector(Matrix matrix, MatrixGestureDetector.OnMatrixChangeListener listener) {
this.mMatrix = matrix;
this.mListener = listener;
}
public void onTouchEvent(MotionEvent event) {
if (event.getPointerCount() > 2) {
return;
}
int action = event.getActionMasked();
int index = event.getActionIndex();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
int idx = index * 2;
mSrc[idx] = event.getX(index);
mSrc[idx + 1] = event.getY(index);
mCount++;
ptpIdx = 0;
break;
case MotionEvent.ACTION_MOVE:
for (int i = 0; i < mCount; i++) {
idx = ptpIdx + i * 2;
mDst[idx] = event.getX(i);
mDst[idx + 1] = event.getY(i);
}
mTempMatrix.setPolyToPoly(mSrc, ptpIdx, mDst, ptpIdx, mCount);
mMatrix.postConcat(mTempMatrix);
if (mListener != null) {
mListener.onChange(mMatrix);
}
System.arraycopy(mDst, 0, mSrc, 0, mDst.length);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (event.getPointerId(index) == 0) ptpIdx = 2;
mCount--;
break;
}
}
}
found the solution thanx to pskink, on this link Android ImageView Scaling and translating issue
by using invert matrix in layer#contain method.
Related
I want to put marker on image with below functionality
-Dynamically adding multiple markers on image with zoom and scroll functionality on image.
-Blink animation on marker after added on image.
-Marker can be click-able and drag & drop on image.
-Marker's x & y position on image to sync same with other devices
I have used https://github.com/davemorrissey/subsampling-scale-image-view library
Java Code :
public class PinMarkerView extends SubsamplingScaleImageView implements View.OnTouchListener {
private PointF sPin;
private Bitmap pin;
private int resId;
public float vX;
public float vY;
private PointF vPrevious;
private PointF vStart;
private boolean drawing = false;
private boolean markerTouch = false;
private int strokeWidth;
private ArrayList<MapPins> allPins = new ArrayList<MapPins>();
private ArrayList<DrawPins> drawnPins = new ArrayList<DrawPins>();
public PinView(Context context) {
this(context, null);
}
public PinView(Context context, AttributeSet attr) {
super(context, attr);
// initialise();
}
public void setPin(PointF sPin, #DrawableRes int resid, String extras) {
MapPins mapPins = new MapPins();
mapPins.setPointF(sPin);
mapPins.setResId(resid);
mapPins.setExtrasData(extras);
mapPins.setX(sPin.x);
mapPins.setY(sPin.y);
allPins.add(mapPins);
//this.sPin = sPin;
// this.resId = resid;
initialise();
invalidate();
}
public PointF getPin() {
return sPin;
}
public Bitmap getMarker() {
return pin;
}
private void initialise() {
setOnTouchListener(this);
float density = getResources().getDisplayMetrics().densityDpi;
strokeWidth = (int) (density / 60f);
for (int i = 0; i < allPins.size(); i++) {
MapPins mapPins = allPins.get(i);
Bitmap localpin = BitmapFactory.decodeResource(this.getResources(), mapPins.getResId());
float w = (density / 100f) * localpin.getWidth();
float h = (density / 100f) * localpin.getHeight();
//pin = Bitmap.createScaledBitmap(pin, (int) w, (int) h, true);
pin = Bitmap.createScaledBitmap(localpin, localpin.getWidth(), localpin.getHeight(), true);
mapPins.setCreatedBitmap(pin);
allPins.set(i, mapPins);
//-------
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Don't draw pin before image is ready so it doesn't move around during setup.
if (!isReady()) {
return;
}
Paint paint = new Paint();
paint.setAntiAlias(true);
for (int i = 0; i < allPins.size(); i++) {
MapPins mapPins = allPins.get(i);
if (mapPins.getPointF() != null && mapPins.getCreatedBitmap() != null) {
PointF vPin = sourceToViewCoord(mapPins.getPointF());
vX = vPin.x - (mapPins.getCreatedBitmap().getWidth() / 2);
vY = vPin.y - mapPins.getCreatedBitmap().getHeight();
canvas.drawBitmap(mapPins.getCreatedBitmap(), vX, vY, paint);
}
}
}
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
setMaxScale(5f);
return false;
}
#Override
public boolean onTouchEvent(#NonNull MotionEvent event) {
/* if (isZoomEnabled()) {
return super.onTouchEvent(event);
}*/
boolean consumed = false;
int touchCount = event.getPointerCount();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_1_DOWN:
vStart = new PointF(event.getX(), event.getY());
vPrevious = new PointF(event.getX(), event.getY());
getPinIdByPoint(vStart, viewToSourceCoord(event.getX(), event.getY()));
handleActionDown((int) event.getX(), (int) event.getY());
break;
case MotionEvent.ACTION_POINTER_2_DOWN:
// Abort any current drawing, user is zooming
vStart = null;
vPrevious = null;
break;
case MotionEvent.ACTION_MOVE:
if (markerTouch) {
setPanEnabled(false);
PointF sCurrentF = viewToSourceCoord(event.getX(), event.getY());
PointF sCurrent = new PointF(sCurrentF.x, sCurrentF.y);
PointF sStart = vStart == null ? null : new PointF(viewToSourceCoord(vStart).x, viewToSourceCoord(vStart).y);
if (touchCount == 1 && vStart != null) {
float vDX = Math.abs(event.getX() - vPrevious.x);
float vDY = Math.abs(event.getY() - vPrevious.y);
if (vDX >= strokeWidth * 5 || vDY >= strokeWidth * 5) {
if (sPin == null) {
sPin = sStart;
}
sPin = sCurrent;
vPrevious.x = event.getX();
vPrevious.y = event.getY();
drawing = true;
}
consumed = true;
invalidate();
} else if (touchCount == 1) {
// Consume all one touch drags to prevent odd panning effects handled by the superclass.
consumed = true;
}
} else {
return super.onTouchEvent(event);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
invalidate();
setPanEnabled(true);
drawing = false;
markerTouch = false;
vPrevious = null;
vStart = null;
}
// Use parent to handle pinch and two-finger pan.
return consumed || super.onTouchEvent(event);
}
public void handleActionDown(int eventX, int eventY) {
if (eventX >= (sPin.x - pin.getWidth()) && (eventX <= (sPin.x + pin.getWidth()))) {
if (eventY >= (sPin.y - pin.getHeight()) && (sPin.y <= (sPin.y + pin.getHeight()))) {
markerTouch = true;
} else {
markerTouch = false;
}
} else {
markerTouch = false;
}
}
public int getPinIdByPoint(PointF tappedCoordinate, PointF deeplinkCoordinate) {
for (int i = allPins.size() - 1; i >= 0; i--) {
MapPins dPin = allPins.get(i);
int blockWidth = dPin.getCreatedBitmap().getWidth();
int blockHeight = dPin.getCreatedBitmap().getHeight();
int deeplinkX = (int) (deeplinkCoordinate.x - (dPin.getCreatedBitmap().getWidth() / 2));
int deeplinkY = (int) (deeplinkCoordinate.y - dPin.getCreatedBitmap().getHeight());
// center coordinate -/+ blockWidth actually sets touchable area to 2x icon size
if (tappedCoordinate.x >= deeplinkX - blockWidth && tappedCoordinate.x <= deeplinkX + blockWidth &&
tappedCoordinate.y >= deeplinkY - blockHeight && tappedCoordinate.y <= deeplinkY + blockHeight) {
sPin = dPin.getPointF();
pin = dPin.getCreatedBitmap();
return dPin.getId();
}
}
return -1; //negative no means no pin selected
}
}
Currently, I am able to add multiple marker, but I am facing issue of marker click and dragging on image.
I want to draw canvas on image view
I am using concept of Finger Paint but it is not working
public class show_image extends Activity implements OnTouchListener,ColorPickerDialog.OnColorChangedListener {
ImageView img_vw_show;
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
float x1, y1, x2, y2;
Bitmap bmp;
int i = 1, width, height;
private static final float MINP = 0.25f;
// private static final float MAXP = 0.75f;
int w, h;
Bitmap mBitmap, bMap, newBitmap;
Canvas mCanvas;
Path mPath;
Paint mBitmapPaint, mPaint;
MaskFilter mEmboss;
MaskFilter mBlur;
BufferedInputStream buf;
MyView mv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.show_image);
System.out.println("oncreate method called");
img_vw_show = (ImageView) this.findViewById(R.id.img_vw_show);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f);
// mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
img_vw_show.setOnTouchListener((OnTouchListener) this);
String responseImagePath = this.getIntent().getStringExtra(
"responseImagePath");
String selectedImagePath = this.getIntent().getStringExtra(
"selectedImagePath");
System.out.println("responseImagePath in show image========"
+ responseImagePath);
System.out.println("selectedImagePath in show image========"
+ selectedImagePath);
Boolean selectedImagePathFlag = false;
if (selectedImagePath == null) {
selectedImagePathFlag = true;
} else if (selectedImagePath.equals("")) {
selectedImagePathFlag = true;
}
if (selectedImagePathFlag) {
if (responseImagePath != null && !responseImagePath.equals("")) {
URL url1;
InputStream in;
try {
url1 = new
// URL("http://mail.sshanghvi.com:8080/sacplupload/checklist/"+responseImagePath);
URL("http://192.168.1.49:82/uploads/" + responseImagePath);
in = url1.openStream();
// Read the inputstream
buf = new BufferedInputStream(in);
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
// The new size we want to scale to
final int REQUIRED_SIZE = 70;
// Find the correct scale value. It should be the power of
// 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
bMap = BitmapFactory.decodeStream(buf, null, o2);
img_vw_show.setImageBitmap(bMap);
width = bMap.getWidth();
height = bMap.getHeight();
System.out.println("Width and Height is==" + width + " & "
+ height);
mv = new MyView(show_image.this, bMap);
System.out.println("Setting the Myview");
mv.invalidate();
if (in != null) {
in.close();
}
if (buf != null) {
buf.close();
}
} catch (Exception e) {
Log.e("Error reading file", e.toString());
}
} else {
Toast.makeText(getApplicationContext(), "Image Not Available",
Toast.LENGTH_SHORT).show();
}
} else {
File imgFile = new File(selectedImagePath);
BitmapFactory.Options bfOptions = new BitmapFactory.Options();
bfOptions.inDither = false; // Disable Dithering mode
bfOptions.inPurgeable = true; // Tell to gc that whether it needs
// free memory, the Bitmap can be
// cleared
bfOptions.inInputShareable = true; // Which kind of reference will
// be used to recover the Bitmap
// data after being clear, when
// it will be used in the future
bfOptions.inTempStorage = new byte[32 * 1024];
Bitmap myBitmap = BitmapFactory.decodeFile(
imgFile.getAbsolutePath(), bfOptions);
img_vw_show.setImageBitmap(myBitmap);
}
}
public class MyView extends View {
public MyView(Context c, Bitmap img) {
super(c);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(8);
setWillNotDraw(false);
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6,
3.5f);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
Bitmap newBitmap;
Canvas newCanvas;
public void onDraw(Canvas canvas) {
super.onDraw(newCanvas);
newBitmap= Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
newCanvas= new Canvas(newBitmap);
System.out.println("canvas == "+canvas);
System.out.println("newCanvas == "+newCanvas);
System.out.println("onDraw Called");
img_vw_show.draw(newCanvas);
newCanvas.drawBitmap(newBitmap, 0, 0, mBitmapPaint);
newCanvas.drawPath(mPath, mPaint);
img_vw_show.setImageBitmap(newBitmap);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
System.out.println("Touch Start Called");
onDraw(newCanvas);
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
System.out.println("Touch Move Called");
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() {
System.out.println("Touch Up Called");
mPath.lineTo(mX, mY);
// commit the path to our offscreen
newCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
}
private static final int COLOR_MENU_ID = Menu.FIRST;
private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
private static final int BLUR_MENU_ID = Menu.FIRST + 2;
private static final int ERASE_MENU_ID = Menu.FIRST + 3;
private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');
/****
* Is this the mechanism to extend with filter effects? Intent intent =
* new Intent(null, getIntent().getData());
* intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
* menu.addIntentOptions( Menu.ALTERNATIVE, 0, new ComponentName(this,
* NotesList.class), null, intent, 0, null);
*****/
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
mPaint.setXfermode(null);
mPaint.setAlpha(0xFF);
switch (item.getItemId()) {
case COLOR_MENU_ID:
new ColorPickerDialog(this, this, mPaint.getColor()).show();
return true;
case EMBOSS_MENU_ID:
if (mPaint.getMaskFilter() != mEmboss) {
mPaint.setMaskFilter(mEmboss);
} else {
mPaint.setMaskFilter(null);
}
return true;
case BLUR_MENU_ID:
if (mPaint.getMaskFilter() != mBlur) {
mPaint.setMaskFilter(mBlur);
} else {
mPaint.setMaskFilter(null);
}
return true;
case ERASE_MENU_ID:
// mPaint.setXfermode(new
// PorterDuffXfermode(PorterDuff.Mode.CLEAR));
return true;
case SRCATOP_MENU_ID:
// mPaint.setXfermode(new
// PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
mPaint.setAlpha(0x80);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void colorChanged(int color) {
}
#Override
public boolean onTouch(View v, MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mv.touch_start(x, y);
v.invalidate();
break;
case MotionEvent.ACTION_MOVE:
mv.touch_move(x, y);
v.invalidate();
break;
case MotionEvent.ACTION_UP:
mv.touch_up();
v.invalidate();
break;
}
return true;
}
}
Even i faced the same problem in my app. Drawing the shapes from the canvas onto the imageViews and later updating them each time did not seem to work.
I accomplished the same by extracting the shape onto my UI class and there i wrote a method
showView(View v, color color)
{
}
And called it in my main activity whenever required. In my app the scenario was to changethe colors dynamically of the canvas.
So I worked upon it like that and it worked. Hope it helps.
Canvas Class:
public void init()
{
basePaint = new Paint();
basePaint.setColor(Color.RED);
basePaint.setStrokeWidth(2);
basePaint.setStyle(Paint.Style.FILL_AND_STROKE);
paint = new Paint();
paint.setStrokeWidth(2);
paint.setColor(color);
triPaint = new Paint();
triPaint.setColor(Color.RED);
triPaint.setStrokeWidth(2);
triPaint.setStyle(Paint.Style.FILL_AND_STROKE);
triPaint1 = new Paint();
triPaint1.setColor(Color.RED);
triPaint1.setStrokeWidth(2);
triPaint1.setStyle(Paint.Style.FILL_AND_STROKE);
diffPaint = new Paint();
diffPaint.setColor(color);
diffPaint.setStrokeWidth(2);
diffPaint.setStyle(Paint.Style.FILL_AND_STROKE);
Log.i("color","="+color);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
}
#Override
public void onDraw(Canvas canvas) {
Log.d("check","="+color);
Log.e("check","after set:"+buf);
Log.i("new view ", " on draw ");
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
paint.setColor(Color.WHITE);
/*basePaint.setStyle(Paint.Style.FILL);
basePaint.setStrokeWidth(3);
basePaint.setColor(Color.RED);
canvas.drawLine(0,40,80,40,basePaint);*/
path = new Path();
path.moveTo(0, 30); /*For Borders*/
path.lineTo(30, 0);
path.lineTo(-30, 0);
path.close();
path.offset(20, -5);
canvas.drawPath(path, paint);
diffPaint.setStyle(Paint.Style.FILL);
diffPaint.setStrokeWidth(3);
diffPaint.setColor(color); //To fill The Triangle
Log.d("Filling","Triangles");
diffPath = new Path();
diffPath.moveTo(0, 30);
Log.d("After","1st line");
diffPath.lineTo(30, 0);
Log.d("After","2nd line");
diffPath.lineTo(-30, 0);
Log.d("After","3rd line");
diffPath.close();
diffPath.offset(20, -5);
Log.d("Locating","Arrow");
canvas.drawPath(diffPath, diffPaint);
Log.d("Drew","Arrow");
Log.d("Color","="+color);
triPaint.setStyle(Paint.Style.FILL);
triPaint.setStrokeWidth(100);
triPaint.setColor(Color.BLACK);
triPath = new Path();
triPath.moveTo(0, -20);
triPath.lineTo(20, 0);
triPath.lineTo(-20, 0); //To Fill the extra Space
triPath.close();
triPath.offset(42,26);
canvas.drawPath(triPath, triPaint);
triPaint1.setStyle(Paint.Style.FILL);
triPaint1.setStrokeWidth(100);
triPaint1.setColor(Color.BLACK);
triPath1 = new Path();
triPath1.moveTo(0, -20);
triPath1.lineTo(20, 0);
triPath1.lineTo(-20, 0);
triPath1.close();
triPath1.offset(-2,26);
canvas.drawPath(triPath1, triPaint1);
}
UI class:
public void show(View anchor,int color) {
preShow();
int xPos, yPos, arrowPos;
mDidAction = false; /*Setting the position of arrows drawn using canvas in UI*/
int[] location = new int[2];
anchor.getLocationOnScreen(location);
Rect anchorRect = new Rect(location[0], location[1], location[0]
+ anchor.getWidth(), location[1] + anchor.getHeight());
mRootView.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
int rootHeight = mRootView.getMeasuredHeight();
if (rootWidth == 0) {
rootWidth = mRootView.getMeasuredWidth();
}
int screenWidth = mWindowManager.getDefaultDisplay().getWidth();
int screenHeight = mWindowManager.getDefaultDisplay().getHeight();
if ((anchorRect.left + rootWidth) > screenWidth) {
xPos = anchorRect.left - (rootWidth - anchor.getWidth());
xPos = (xPos < 0) ? 0 : xPos;
arrowPos = anchorRect.centerX() - xPos;
} else {
if (anchor.getWidth() > rootWidth) {
xPos = anchorRect.centerX() - (rootWidth / 2);
} else {
xPos = anchorRect.left;
}
arrowPos = anchorRect.centerX() - xPos;
}
int dyTop = anchorRect.top;
int dyBottom = screenHeight - anchorRect.bottom;
boolean onTop = (dyTop > dyBottom) ? true : false;
if (onTop) {
if (rootHeight > dyTop) {
yPos = 15;
LayoutParams l = mScroller.getLayoutParams();
l.height = dyTop - anchor.getHeight();
} else {
yPos = anchorRect.top - rootHeight;
}
} else {
yPos = anchorRect.bottom;
if (rootHeight > dyBottom) {
LayoutParams l = mScroller.getLayoutParams();
l.height = dyBottom;
}
}
showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), arrowPos,color);
/*updating color of arrow which is the shape drawn in canvas*/
container.setBackgroundColor(color);
setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
mWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos);
}
Main Activity:
Whenever the shape needs to be updated by a modification of color:
btn1 = (Button) this.findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.d("In","View");
quickAction.show(v,Color.BLUE);
/*By passing the color the color is getting updated and modified on each button click for the shape drawn using canvas on the imageView*/
}
});
I have a GridView of images, which are all in the /res directory (come with the app). When I open one of them, there is no problem. But, I want to be able to scroll between them also in the same way that's done in the gallery, i.e. sliding the finger on the image will cause the next image to appear. Is there any way to do that?
Thanks!
You can use ViewPager
See android viewPager implementation for some good links to learn how to implement it.
I ended up creating a simple implementation of my own:
public class PicView extends View{
private int mBackgroundPicPosition;
private Bitmap mBackgroundPic;
private int m_touchStartPosX;
private EventsActivity m_mainActivity;
private int m_viewWidth;
private int m_viewHeight;
private int m_backgroundX;
private Integer[] m_picIDs;
public PicView(Context context, Integer[] picIDs) {
super(context);
m_mainActivity = (EventsActivity)context;
m_viewWidth = m_mainActivity.mMetrics.widthPixels;
m_viewHeight = m_mainActivity.mMetrics.heightPixels;
m_picIDs = picIDs;
}
public void setBackground(int position) {
Options opts = new Options();
mBackgroundPicPosition = position;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), m_picIDs[position], opts);
mBackgroundPic = BitmapFactory.decodeResource(getResources(), m_picIDs[position], opts);
int picHeight = bitmap.getHeight();
int picWidth = bitmap.getWidth();
mBackgroundPic.recycle();
float xScale, yScale, scale;
if (picWidth > picHeight) {
// rotate the picture
Matrix matrix = new Matrix();
matrix.postRotate(-90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
picHeight = bitmap.getHeight();
picWidth = bitmap.getWidth();
matrix = null;
}
xScale = ((float)m_viewWidth)/ picWidth;
yScale = ((float)m_viewHeight) / picHeight;
scale = (xScale <= yScale) ? xScale : yScale;
m_backgroundX = (xScale >= yScale) ? (m_viewWidth - (int)(picWidth * scale)) / 2 : 0;
mBackgroundPic = Bitmap.createScaledBitmap(bitmap, (int)(picWidth * scale), (int)(picHeight * scale), true);
bitmap = null;
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
// draw the background
canvas.drawBitmap(mBackgroundPic, m_backgroundX, 0, null);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
int X = (int)event.getX();
switch (eventaction ) {
case MotionEvent.ACTION_DOWN:
m_touchStartPosX = X;
break;
case MotionEvent.ACTION_UP:
//check to see if sliding picture
if (X <= m_touchStartPosX) {
// slide to the left
setBackground(getNextPosition());
} else {
// slide to the right
setBackground(getPrevPosition());
}
m_touchStartPosX = -1;
break;
}
invalidate();
return true;
}
private int getPrevPosition() {
if (mBackgroundPicPosition == 0) {
return m_picIDs.length - 1;
} else {
return mBackgroundPicPosition - 1;
}
}
private int getNextPosition() {
if (mBackgroundPicPosition == m_picIDs.length - 1) {
return 0;
} else {
return mBackgroundPicPosition + 1;
}
}
How can I zoom the image without using matrix in android?
Here is the code that I am using:
public class SimpImageView extends BaseView{
private Bitmap image = null;
private Paint borderPaint = null;
PointF start = new PointF();
PointF lastPosition = new PointF();
Matrix savedMatrix = new Matrix();
private Paint imagePaint = null;
private Matrix matrix = null;
public Bitmap getImage() {
return image;
}
public void setImage(Bitmap image) {
this.image = image;
}
public SimpImageView(Bitmap image,int x,int y,int width,int height){
super(x, y, width, height);
this.image = image;
borderPaint = new Paint();
borderPaint.setARGB(255, 255, 128, 128);
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(2);
imagePaint = new Paint();
imagePaint.setARGB(32, 255, 255, 255);
imagePaint.setStyle(Paint.Style.FILL);
}
/* (non-Javadoc)
* #see com.simplogics.surfaceview.Views.BaseView#onDraw(android.graphics.Canvas)
*/
#Override
public void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
canvas.drawBitmap(image, getBounds().left, getBounds().top, null);
// canvas.drawBitmap(image, matrix, new Paint());
// canvas.drawBitmap(image, matrix, borderPaint);
// canvas.drawRect(getBounds() , borderPaint);
}
/* (non-Javadoc)
* #see com.simplogics.surfaceview.Views.BaseView#onTouchEvent(android.view.MotionEvent)
*/
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
#Override
public boolean onTouchEvent(MotionEvent event) {
boolean handled = false;
Log.d("SimpEditText", "(int)event.getX() " + (int)event.getX());
Log.d("SimpEditText", "(int)event.getY() " + (int)event.getY());
if(isTouchedInBounds((int)event.getX(), (int)event.getY())){
Log.d("SimpEditText", "Touched in Bounds");
handled = true;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
start.set(event.getX(), event.getY());
lastPosition.x = getBounds().left;
lastPosition.y = getBounds().top;
Log.d("VerticalLabelView", "mode=DRAG");
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
mode = ZOOM;
Log.d("VerticalLabelView", "mode=ZOOM");
break;
case MotionEvent.ACTION_UP:
mode = NONE;
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
Log.d("VerticalLabelView", "mode=NONE");
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
int x = (int)(event.getX() - start.x);
int y = (int)(event.getY() - start.y);
setPosition((int)lastPosition.x + x, (int)lastPosition.y + y);
mode = DRAG;
break;
}else if(mode == ZOOM){
Log.d("SimpImageView", "MODE=ZOOM");
Log.d("SimpImageView", "getImage().getWidth()="+getImage().getWidth());
Log.d("SimpImageView"," getImage().getHeight()="+getImage().getHeight());
}
break;
}
}
return handled;
}
}
baseView.java
public abstract class BaseView {
private int id = -1;
private Object tag = null;
private Rect bounds = null;
public Rect getBounds() {
return bounds;
}
public BaseView() {
bounds = new Rect();
}
public BaseView(int x, int y, int width, int height) {
bounds = new Rect(x, y, x + width, y + height);
}
public abstract void onDraw(Canvas canvas);
public abstract boolean onTouchEvent(MotionEvent event);
public void setBounds(int x, int y, int width, int height){
bounds.set(x, y, x + width, y + height);
}
public void setPosition(int x, int y){
if(x <= 0 || y <= 0){
Log.e("SimpEditText1", "----------------------------------------------------------");
Log.e("SimpEditText1", "-------------0000000000000000000000000000000000------------");
Log.e("SimpEditText1", "----------------------------------------------------------");
}
bounds.set(x, y, x + bounds.width(), y + bounds.height());
}
public void setScale(int x,int y,int width,int height){
bounds.set(x, y, x + bounds.width()+width, y + bounds.height()+height);
}
protected boolean isTouchedInBounds(int xPos, int yPos){
return bounds.contains(xPos, yPos);
}
public Object getTag() {
return tag;
}
public void setTag(Object tag) {
this.tag = tag;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
/**
* #param w
* #param h
* #param oldw
* #param oldh
*/
}
I have created my own ImageView which hopefully will
do overlays , zooming , panning and measuring between two points.
So far all but the measuring works The canvas.drawline shows nothing ?
This may be dirty and could probably be cleaned quite a bit.
Anyone got an Idea why the canvas.drawline does not work ?
Thanks in Advance
public class myImage extends ImageView implements OnTouchListener {
private static final short UNKNOWN = 0;
private static final short IMG_INIT = 1;
private static final short SET_IMAGE = 2;
private static final short DRAGGING = 3;
private static final short MARKING = 4;
private static final short STARTING = 5;
private static final short ZOOM_PAN = 6;
private static final short OVERLAY = 7;
private static short STATE = UNKNOWN;
private static PointF pointA = null;
private static PointF pointB = null;
private static PointF pointC = null;
private PointF busy = new PointF();
private Bitmap tracking = BitmapFactory.decodeResource(getResources(), R.drawable.target);
private Drawable[] layers = new Drawable[2];
private Paint mPaint;
private Bitmap mBitmap;
private Canvas busyCanvas;
private int touch_counter = 0;
#Override
protected void onDraw(Canvas canvas) {
switch (STATE) {
/* 0 */ case UNKNOWN: super.onDraw(canvas); break;
/* 1 */ case IMG_INIT: break;
/* 2 */ case SET_IMAGE: super.onDraw(canvas); break;
/* 3 */ case DRAGGING: break;
/* 4 */ case MARKING:
canvas.drawBitmap(mBitmap, matrix, mPaint);
if (touch_counter == 0 && pointB != null && CURRENT_STATUS == "DRAW_LINE" ) {
mPaint.setColor(Color.BLUE);
canvas.drawLine(pointA.x, pointA.y, pointB.x, pointB.y, mPaint);
This is What does Not Show up OR work
}
break;
/* 5 */ case STARTING: break;
/* 6 */ case ZOOM_PAN: super.onDraw(canvas); break;
/* 7 */ case OVERLAY: super.onDraw(canvas); break;
}
STATE = UNKNOWN;
}
public void InitOverlay(String fName) {
fName = "/sdcard/DCIM/"+fName;
if ( (fName.endsWith(".jpg") || fName.endsWith(".png")) ) {
Matrix matrix = new Matrix();
matrix.postScale(0.35f, 0.35f);
Bitmap bitm2 = BitmapFactory.decodeFile( fName );
layers[0] = new BitmapDrawable( mBitmap ); layers[0].setAlpha(255);
layers[1] = new BitmapDrawable( Bitmap.createBitmap(bitm2, 0, 0, bitm2.getWidth(), bitm2.getHeight(), matrix, true) ); layers[1].setAlpha( 50);
LayerDrawable layerDraw = new LayerDrawable(layers);
super.setImageDrawable(layerDraw);
super.invalidate();
STATE = OVERLAY;
}
}
private void OverLay(View view , MotionEvent event) {
if ( STATE == UNKNOWN && event.getAction() == MotionEvent.ACTION_MOVE) {
STATE = OVERLAY;
if ( event.getX() > 1 && event.getX() < 1130 ) {
layers[1].setAlpha( (int) (event.getX() / 4.35f) );
}
}
}
private void AddPoints(View view , MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: touch_start(event.getX() , event.getY()); break;
case MotionEvent.ACTION_MOVE: touch_busy (event.getX() , event.getY()); break;
case MotionEvent.ACTION_UP: touch_end (event.getX() , event.getY()); break;
}
}
private void touch_start(float x, float y) {
STATE = STARTING;
touch_counter++;
busy.x = ((x - 32.0f + (float)getScrollX()));
busy.y = ((y - 70.0f + (float)getScrollY()));
}
private void touch_busy(float x, float y) {
busy.x = ((x - 32.0f + (float)getScrollX()));
busy.y = ((y - 70.0f + (float)getScrollY()));
STATE = DRAGGING;
}
private void touch_end(float x, float y) {
STATE = MARKING;
if (touch_counter == 1) {
pointA = new PointF();
pointA.x = ((x - 32.0f)); // + ViewOffset.x));
pointA.y = ((y - 70.0f)); // + ViewOffset.y));
} else if (touch_counter == 2) {
pointB = new PointF();
pointB.x = ((x - 32.0f));
pointB.y = ((y - 70.0f));
if (CURRENT_STATUS == "DRAW_LINE") touch_counter = 0;
Log.i("Image" , "At this Point Calling Draw ");
super.draw(busyCanvas);
}
}
public myImage(Context context , FrameLayout screen) {
super(context);
super.setLayerType(LAYER_TYPE_HARDWARE, null);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF0000FF);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(5);
STATE = IMG_INIT;
invalidate();
}
public void freeImage() {
try {
mBitmap.recycle();
tracking.recycle();
} catch (Exception err) {
ImageExceptionHandler(err);
}
}
#Override
public void setImageBitmap(Bitmap bmp) {
try {
STATE = SET_IMAGE;
busyCanvas = new Canvas();
busyCanvas.setBitmap(bmp);
mBitmap = bmp;
busyCanvas.setBitmap(bmp);
} catch (Exception err) {
ImageExceptionHandler(err);
}
super.setImageBitmap(bmp);
}
private void ImageExceptionHandler(Exception err) {
Log.e("image" , "==============================================");
Log.e("image" , "EXCEPTION Handling ");
Log.e("image" , "==============================================");
err.printStackTrace();
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (CURRENT_STATUS == "PAN & ZOOM" ) ScrollAndZoom(v , event);
else if (CURRENT_STATUS == "OVERLAY" ) OverLay(v , event);
else if (CURRENT_STATUS == "DRAW_LINE" ) AddPoints(v , event);
else {
Log.w("ERROR" , "Should Never Be Here myImage On Touch");
Log.w("ERROR" , "Should Never Be Here myImage On Touch");
}
return true;
}
public void init() {
super.setScaleType( ImageView.ScaleType.MATRIX );
mode = NONE;
matrix = new Matrix();
matrix.set(getImageMatrix());
savematrix = new Matrix();
start = new PointF();
mid = new PointF();
oldDist = 1f;
oldfactor = 1f;
factor = 1f;
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.i("Image" , "Size Changed ["+w+"] x ["+h+"] ["+oldw+"] x ["+oldh+"] ");
super.onSizeChanged(w, h, oldw, oldh);
}
private static final short NONE = 0;
private static final short ZOOM = 1;
private static final short DRAG = 2;
private Matrix matrix = new Matrix();
private Matrix savematrix = new Matrix();
private short mode = NONE;
private PointF start = new PointF();
private PointF mid = new PointF();
private float oldDist = 1f;
private float oldfactor = 1f;
private float factor = 1f;
private void ScrollAndZoom(View view , MotionEvent event) {
STATE = ZOOM_PAN;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: start.set(event.getX() , event.getY());
savematrix.set(matrix);
mode = DRAG;
break;
//------------------------------------------------
case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event);
midPoint(mid , event);
mode = ZOOM;
oldfactor = factor;
break;
//------------------------------------------------
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP: start = new PointF();
mode = NONE;
matrix.set(getImageMatrix());
setBackgroundColor(Color.BLACK);
break;
//------------------------------------------------
case MotionEvent.ACTION_MOVE: matrix.set(savematrix);
if (mode == DRAG) {
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
setBackgroundColor(Color.BLACK);
matrix.postTranslate(dx, dy);
setImageMatrix(matrix);
} else if (mode == ZOOM) {
float newD = spacing(event);
float newfactor = newD / oldDist;
factor = oldfactor * newfactor;
zoom(newfactor);
}
break;
//------------------------------------------------
}
}
private void zoom (Float scale) {
setBackgroundColor(Color.BLACK);
matrix.postScale(scale , scale , mid.x , mid.y);
setImageMatrix(matrix);
}
private float spacing(MotionEvent event) {
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0);
return FloatMath.sqrt(dx*dx + dy*dy);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2f , y / 2f);
}
}
Making some progress some steps backwards
I have re-written some of it It will now Draw the Line and Zoom the entire image with the line zooming also.
However if I draw a line, then Zoom in Good !
But When I draw again it draws the line a Ultra zooms in, and when you zoom out most of the image is now lost? ? and ideas why?
Thanks in advance
Here is the current code
public class myImage extends ImageView implements OnTouchListener {
private static final short NONE = 0;
private static final short ZOOM = 1;
private static final short DRAG = 2;
private static short mode = NONE;
private static PointF pointA = null;
private static PointF pointB = null;
private ImageView pointer = null;
private PointF busy = new PointF();
private PointF start = new PointF();
private PointF mid = new PointF();
private Matrix matrix = new Matrix();
private Matrix savematrix = new Matrix();
private Bitmap tracking = BitmapFactory.decodeResource(getResources(), R.drawable.target);
private Drawable[] layers = new Drawable[2];
private Bitmap mBitmap;
private Canvas mCanvas;
private Paint mPaint;
private int touch_counter = 0;
private long touchTime = -1;
private float oldDist = 1f;
private float oldfactor = 1f;
private float factor = 1f;
public myImage(Context context , FrameLayout screen) {
super(context);
super.setLayerType(LAYER_TYPE_HARDWARE, null);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF0000FF);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(2);
mPaint.setTextSize(20f);
super.setScaleType( ImageView.ScaleType.MATRIX );
mode = NONE;
matrix = new Matrix();
matrix.set(getImageMatrix());
savematrix = new Matrix();
start = new PointF();
mid = new PointF();
oldDist = 1f;
oldfactor = 1f;
factor = 1f;
}
public void freeImage() {
try {
mBitmap.recycle();
tracking.recycle();
} catch (Exception err) {
ImageExceptionHandler(err);
}
}
#Override
public void setImageBitmap(Bitmap bmp) {
try {
mBitmap = bmp;
mCanvas = new Canvas(bmp);
mCanvas.setBitmap(bmp);
} catch (Exception err) {
ImageExceptionHandler(err);
}
super.setImageBitmap(bmp);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if ( CURRENT_STATUS == "PAN & ZOOM" ) ScrollAndZoom(v , event);
else if ( CURRENT_STATUS == "DRAW_LINE" ) AddPoints(v , event);
else {
Log.w("ERROR" , "Should Never Be Here myImage On Touch");
Log.w("ERROR" , "Should Never Be Here myImage On Touch ["+eedsActivity.CURRENT_STATUS+"] ");
Log.w("ERROR" , "Should Never Be Here myImage On Touch ["+eedsActivity.CURRENT_IMAGE +"] ");
Log.w("ERROR" , "Should Never Be Here myImage On Touch");
}
return true;
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.i("Image" , "Size Changed ["+w+"] x ["+h+"] ["+oldw+"] x ["+oldh+"] ");
super.onSizeChanged(w, h, oldw, oldh);
}
private void myDrawLine(PointF ptA , PointF ptB) {
mCanvas.drawBitmap(mBitmap , matrix , mPaint);
mPaint.setColor(Color.BLUE);
mCanvas.drawLine( ptA.x , ptA.y , ptB.x , ptB.y , mPaint);
if (ptA.x <= ptB.x ) mCanvas.translate( (ptA.x + 0.0f), (ptA.y + 0.0f) );
else mCanvas.translate( (ptA.x + 0.0f), (ptA.y + 0.0f) );
line newLine = new line(ptA , ptB , factor);
switch (newLine.getQuadrant()) {
case 1: mCanvas.rotate( (float) newLine.getAngle() ); break;
case 2: mCanvas.rotate( (newLine.getAngle() - 180.0f) ); break;
case 3: mCanvas.rotate( (newLine.getAngle() + 180.0f) ); break;
case 4: mCanvas.rotate( (float) newLine.getAngle() ); break;
}
String result = "";
mPaint.setColor(Color.YELLOW);
result = String.format("%4.3f mm", newLine.getDistance() );
mCanvas.drawText( result, ((newLine.getDistance() * line.PX_TO_MM) / 3.0f), -6.0f, mPaint);
invalidate();
}
public void recenter() {
oldDist = 1f;
oldfactor = 1f;
factor = 1f;
setBackgroundColor(Color.BLACK);
matrix.setScale(1f, 1f);
matrix.postTranslate(0f , 0f);
setImageMatrix(matrix);
}
private void AddPoints(View view , MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: touch_start(event.getX() , event.getY()); break;
case MotionEvent.ACTION_MOVE: touch_busy (event.getX() , event.getY()); break;
case MotionEvent.ACTION_UP: touch_end (event.getX() , event.getY()); break;
}
}
private void touch_start(float x, float y) {
touch_counter++;
busy.x = (x - 32.0f);
busy.y = (y - 70.0f);
LayoutParams lp = new LayoutParams(32 , 32);
pointer = new ImageView(super.getContext());
pointer.setBackgroundDrawable(getResources().getDrawable(R.drawable.target2));
lp.leftMargin = (int) x;
lp.topMargin = (int) y;
((ViewGroup) super.getParent()).addView(pointer , lp);
}
private void touch_busy(float x, float y) {
busy.x = (x - 32.0f);
busy.y = (y - 70.0f);
if (pointer != null) {
pointer.setLeft( (int)busy.x ); pointer.setRight ( (int)(busy.x+32) );
pointer.setTop ( (int)busy.y ); pointer.setBottom( (int)(busy.y+32) );
}
}
private void touch_end(float x, float y) {
((ViewGroup) super.getParent()).removeView(pointer);
if (touch_counter == 1) {
pointA = new PointF();
pointA.x = ((x - 32.0f));
pointA.y = ((y - 70.0f));
} else if (touch_counter == 2) {
pointB = new PointF();
pointB.x = ((x - 32.0f));
pointB.y = ((y - 70.0f));
}
if (touch_counter == 2) {
myDrawLine(pointA , pointB);
pointA = null; pointB = null;
pointC = null; touch_counter = 0;
}
}
private void ScrollAndZoom(View view , MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: if ((System.currentTimeMillis() - touchTime) < 400) {
// Double Click
touchTime = -1;
setBackgroundColor(Color.BLACK);
matrix.setScale(1f, 1f);
matrix.postTranslate(0f , 0f);
setImageMatrix(matrix);
} else {
// Single Click
touchTime = System.currentTimeMillis();
start.set(event.getX() , event.getY());
savematrix.set(matrix);
mode = DRAG;
}
break;
//------------------------------------------------
case MotionEvent.ACTION_POINTER_DOWN: touchTime = -1;
oldDist = distance(event);
midPoint(mid , event);
mode = ZOOM;
oldfactor = factor;
break;
//------------------------------------------------
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP: start = new PointF();
mode = NONE;
matrix.set(getImageMatrix());
setBackgroundColor(Color.BLACK);
break;
//------------------------------------------------
case MotionEvent.ACTION_MOVE: matrix.set(savematrix);
if (mode == DRAG) {
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
setBackgroundColor(Color.BLACK);
matrix.postTranslate(dx, dy);
setImageMatrix(matrix);
} else if (mode == ZOOM) {
float newD = distance(event);
float newfactor = newD / oldDist;
factor = oldfactor * newfactor;
setBackgroundColor(Color.BLACK);
matrix.postScale(newfactor , newfactor , mid.x , mid.y);
setImageMatrix(matrix);
}
break;
//------------------------------------------------
}
}
private float distance(MotionEvent event) {
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0);
return FloatMath.sqrt(dx*dx + dy*dy);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2f , y / 2f);
}
private void ImageExceptionHandler(Exception err) {
Log.e("image" , "==============================================");
Log.e("image" , "EXCEPTION Handling ");
Log.e("image" , "==============================================");
err.printStackTrace();
}
}
It looks to me like pointB is always null, because you only ever get one ACTION_DOWN per gesture. When the first finger goes down, you get the action, and it triggers touch_start(), setting touch_counter to 1. When the second finger goes down, it doesn't, because you get an ACTION_POINTER_DOWN instead, which isn't checked for.
That's assuming you want a two-finger gesture. If it's meant to be a 'touch here and then touch there' instead, then you shouldn't set touch_counter to zero with each touch_end().
Your line is only drawn when STATE is 'MARKING'; at the end of onDraw you're setting your state back to UNKNOWN which calls the base class's onDraw but doesn't draw your line. If you want your line to stick around in other states, you'll have to redraw it every time onDraw gets called.