Как нарисовать круг после увеличения в android
Я использую изображение с изображением и наложением наложения с помощью layerDrawable.
Я использовал два растровых изображения original и myBitmap.
После масштабирования я не умею рисовать круг в правильном месте, он нарисован в другом месте.
Это код, который я использую,
ImageView view = (ImageView) findViewById(R.id.imageView);
view.setOnTouchListener(this);
Options options = new BitmapFactory.Options();
options.inScaled = false;
original = BitmapFactory.decodeResource(getResources(), R.drawable.mainscreen,options);
original= getResizedBitmap(original, width, 200);
myBitmap = func(original);
Resources r = getResources();
layers = new Drawable[2];
layers[0] = new BitmapDrawable(original);
layers[1] = new BitmapDrawable(myBitmap);
LayerDrawable layerDrawable = new LayerDrawable(layers);
view.setImageDrawable(layerDrawable);
bitmap = Bitmap.createBitmap(width, 200, Config.ARGB_8888);
pcanvas = new Canvas();
pcanvas.setBitmap(bitmap);
pcanvas.drawBitmap(grayScale, 0, 0, null);
public boolean onTouch(View v, MotionEvent rawEvent) {
WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent);
// ...
ImageView view = (ImageView) v;
// Dump touch event to log
// dumpEvent(event);
if (isZoomRequired == false)
{
x = (int) rawEvent.getX();
y = (int) rawEvent.getY();
r = SettingsActivity.brushsize;
pcanvas.drawCircle(x, y, r, mPaint);
layers[1] = new BitmapDrawable(bitmap);
LayerDrawable layerDrawable = new LayerDrawable(layers);
view.setImageDrawable(layerDrawable);
}
else
{
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG");
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
Log.d(TAG, "oldDist=" + oldDist);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
Log.d(TAG, "mode=ZOOM");
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
Log.d(TAG, "mode=NONE");
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
// ...
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x,
event.getY() - start.y);
}
else if (mode == ZOOM) {
float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix);
}
return true; // indicate event was handled
}
Пожалуйста, помогите мне. Мне нужно рисовать круг в правильном месте после масштабирования.
Любая помощь будет оценена.
Ответы
Ответ 1
Не могли бы вы добавить изображения, показывающие, что именно вы пытаетесь получить, и рисунок, показывающий, что вы получаете вместо этого?
Следует иметь в виду, что некоторые операции используют другую нулевую точку для оси y. Я боролся с этим на матричных операциях на поверхности, где мне приходилось вычислять коэффициент коррекции, потому что одна операция использовала верхнюю часть представления как y = 0, а операция матрицы использовала нижнюю часть представления при y = 0, поэтому для реальной работы матрицы понадобилось что-то вроде: matrixY = (totalHeightY - Yposition).
Но показ того, что вы ожидаете, и то, что вы получаете, поможет быстрее диагностировать проблему, чем работать и работать с вашим кодом:)
Ответ 2
Я мог видеть, что matrix.preTranslate не использовался, прежде чем использовать postTranslate, чтобы убедиться, что представление задает изображение в правильном месте.
Ответ 3
Трудно ответить правильно, не зная, что вы пытаетесь сделать.
Я предлагаю создать другой класс, который расширяет представление и использует его для рисования круга поверх вашего ImageView в вашей деятельности. Это также позволит вам привлечь столько кругов (если вы планируете более 1), не создавая каких-либо функций внутри своей деятельности.
Как только вы создадите свой класс, который расширяет представление, тогда в методе onDraw() вы можете нарисовать круг canvas.drawCircle() и canvas.translate(), чтобы переместить его по экрану. Вам нужно будет использовать onTouchEvent и перехватить события касания для этого.
Здесь есть хороший пример с включенным apk: http://adblogcat.com/custom-view-to-draw-rotate-erase-and-convert-images-to-black-and-white/
Ответ 4
Как ниже OnTouchListener вы можете увеличить изображение или растровое изображение. Когда ваш уровень масштабирования архивируется, то
imageView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix1);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
start.set(event.getX(), event.getY());
savedMatrix.set(matrix1);
midPoint(mid, event);
// mode = POINT2;
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
mode = NONE;
distanceOffset = minOffset;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
distanceOffset = minOffset;
break;
case MotionEvent.ACTION_MOVE:
if (mode == POINT2) {
newDist = spacing(event);
if (newDist - oldDist > 5f
|| newDist - oldDist < -5f) {
mode = ZOOM;
} else {
start.set(event.getX(), event.getY());
mode = DRAG;
}
} else if (mode == DRAG) {
matrix1.set(savedMatrix);
matrix1.postTranslate(event.getX() - start.x,
event.getY() - start.y);
} else if (mode == ZOOM) {
newDist = spacing(event);
if (newDist > 10f) {
matrix1.set(savedMatrix);
float scale = newDist / oldDist;
matrix1.postScale(scale, scale, mid.x,
mid.y);
finalscale = scale;
}
}
break;
}
view.setImageMatrix(matrix1);
// matrixTurning(matrix1, view);
return true; // indicate event was handled
}
});
}
Теперь начните рисовать круг в области масштабирования изображения, здесь я пишу код для простой краски. Вы можете поместить свой код для рисования круга ниже слушателя. Упование это полезно для вас.
mPaintView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
PaintView view = (PaintView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
if (falg) {
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
} else {
view.onTouchEvent(event);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (falg) {
oldDist = spacing(event);
if (oldDist > 10f) {
start.set(event.getX(), event.getY());
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
}
break;
case MotionEvent.ACTION_UP:
if (falg) {
mode = NONE;
distanceOffset = minOffset;
}
case MotionEvent.ACTION_POINTER_UP:
if (falg) {
mode = NONE;
distanceOffset = minOffset;
}
break;
case MotionEvent.ACTION_MOVE:
if (falg) {
if (mode == POINT2) {
newDist = spacing(event);
if (newDist - oldDist > 5f
|| newDist - oldDist < -5f) {
mode = ZOOM;
} else {
start.set(event.getX(), event.getY());
mode = DRAG;
}
} else if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x,
event.getY() - start.y);
} else if (mode == ZOOM) {
newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
finalscale = scale;
}
}
} else {
view.onTouchEvent(event);
}
break;
}
limitZoom(matrix);
view.setImageMatrix(matrix);
matrixTurning(matrix, view);
RectF r = new RectF();
matrix.mapRect(r);
scaledImageOffsetX = r.left;
scaledImageOffsetY = r.top;
return true;
}
});
}
private void limitZoom(Matrix m) {
float[] values = new float[9];
m.getValues(values);
float scaleX = values[Matrix.MSCALE_X];
float scaleY = values[Matrix.MSCALE_Y];
if(scaleX > MAX_ZOOM) {
scaleX = MAX_ZOOM;
} else if(scaleX < MIN_ZOOM) {
scaleX = MIN_ZOOM;
}
if(scaleY > MAX_ZOOM) {
scaleY = MAX_ZOOM;
} else if(scaleY < MIN_ZOOM) {
scaleY = MIN_ZOOM;
}
values[Matrix.MSCALE_X] = scaleX;
values[Matrix.MSCALE_Y] = scaleY;
m.setValues(values);
}
public boolean getFlag(boolean b) {
return falg = b;
}
PaintView.class
class PaintView extends ImageView {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
// onDraw
private Paint mPaint;
// onTouch
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
public PaintView(Context context) {
this(context, null);
}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
mBitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_8888);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
@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(0xFFAAAAAA);
super.onDraw(canvas);
mCanvas = canvas;
// canvas = mCanvas;
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
// canvas.drawBitmap(mBitmap, PaintScreen.matrix, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
public void clear() {
mPaint.reset();
// invalidate();
}
public void setMPaint(Paint paint) {
mPaint = paint;
}
private void touchStart(float x, float y) {
// mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touchMove(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 touchUp() {
mPath.lineTo(mX, mY);
// 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();
Log.d("PaintView", "ev ->" + event.getAction());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchStart(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touchMove(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touchUp();
invalidate();
break;
}
return true;
}
public void cMatrix(Matrix matrix) {
mCanvas.setMatrix(matrix);
}
}