una studio photoview imagen hacer android imageview zoom

studio - Dibuje un rectángulo sobre ImageView para resaltar que se puede acercar o alejar con zoom en Android



zoom imageview on touch android (4)

Dibujar Ractangle imageview

public class RactangleImageView extends ImageView { private static final int strockwidth = 6; private Paint paintBorder; private Bitmap bitmap; private int strokeWidthPx; private RectF rectF; private RadialGradient radialGradient; public RactangleImageView(Context context) { super(context); init(); } private void init() { bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.imageicon); strokeWidthPx = (int) (strockwidth * getResources().getDisplayMetrics().density); int halfStrokeWidthPx = strokeWidthPx / 2; paintBorder = new Paint(); paintBorder.setStyle(Paint.Style.FILL); int totalWidth = bitmap.getWidth() + strokeWidthPx * 2; int totalHeight = bitmap.getHeight() + strokeWidthPx * 2; radialGradient = new RadialGradient(totalWidth /2, totalHeight /2, totalWidth /2, new int[] {Color.BLACK, Color.GREEN}, null, Shader.TileMode.MIRROR); paintBorder.setShader(radialGradient); setImageBitmap(Bitmap.createBitmap(totalWidth, totalHeight, Bitmap.Config.ARGB_8888)); rectF = new RectF(halfStrokeWidthPx, halfStrokeWidthPx, totalWidth - halfStrokeWidthPx, totalHeight - halfStrokeWidthPx); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawRoundRect(rectF, 40, 40, paintBorder); canvas.drawBitmap(bitmap,strokeWidthPx, strokeWidthPx, null); } }

He referido este ejemplo de SO abajo son ellos.

1. Dibujar línea sobre ImageView

2. Dibujar una imagen sobre ImageView

3.He utilizado esta clase de ImageView para que mi imagen se convierta en alejar y alejar la imagen .

Ahora lo que intento hacer es:

Quiero hacer zoom acercando la pantalla y el otro punto es que cuando hago un solo toque, un rectángulo debe dibujarse sobre la vista de imagen y también quiero que este rectángulo tenga zoom in y out con imageView Zoom in and Zoom Out y quiero para usarlo a través de la clase ScaleImageView .

La salida de esto debe verse como debajo de la imagen.

Y también sabía que esto se puede hacer usando Relative Layout o SurfaceView en Android, pero soy nuevo para usar Surface View y también me preocupa si uso Another View sobre imageView para dibujar y luego hacer esto. para acercar y alejar. Si uso SurfaceView sobre ImageView, entonces haga Image. Se puede acercar y alejar.

Usando este ejemplo de pellizco de acercamiento y alejamiento desde aquí. ejemplo que uso pinch zoom .

Ahora dibujo Rectángulo en Single Touch con el siguiente código en ese ejemplo.

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Log.v("Log_tag", "Draw Image View"); //Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.rect_image); //canvas.drawColor(Color.BLACK); //canvas.drawBitmap(_scratch, 10, 10, null); Drawable d = getDrawable(); //Bitmap bitmap = ((BitmapDrawable)d).getBitmap(); Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.RGB_565); /*if(bitmap!=null){ if (x1 > 0 || x2 > 0 || y1 > 0 || y2 > 0){ Log.v("Log_tag", "ImageBitmap is draw"); //Canvas mCanvas=new Canvas(bitmap); //mCanvas.drawRect(x1, y1, x2, y2, mPaint); // canvas.clipRect(left, top, right, bottom); paint.setStyle(Paint.Style.FILL_AND_STROKE); paint.setStrokeWidth(1); paint.setColor(0xFF000000 + ((int)(PRESET_PRESSURE * pressure) <<16) + ((int)(PRESET_PRESSURE * pressure) << 8) + (int)(PRESET_PRESSURE * pressure)); //mCanvas.drawCircle(x1, y1, (PRESET_SIZE * size), paint); } }*/ //canvas.save(); //canvas.translate(mPosX, mPosY); // canvas.scale(mScaleFactor, mScaleFactor); mBitmapDrawable.draw(canvas); Paint myPaint = new Paint(); myPaint.setColor(Color.GREEN); myPaint.setStyle(Paint.Style.STROKE); myPaint.setStrokeWidth(1); Log.v("Log_tag", "Redraw with this point"); canvas.drawRect(rect_x1-30,rect_y1-30, rect_x1+30, rect_y1+30, myPaint); mCanvasMatrix=canvas.getMatrix(); mImageCanvas=canvas; canvas.setMatrix(mCanvasMatrix); //canvas.restore(); }

ACTUALIZAR

A continuación se muestra mi clase utilizada para ImageView Pinch Zoom.

public class ImageViewScale extends ImageView implements OnTouchListener { @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //canvas.save(); //canvas.scale(mScale, mScale); mCanvasMatrix=canvas.getMatrix(); Paint myPaint = new Paint(); myPaint.setColor(Color.GREEN); myPaint.setStyle(Paint.Style.STROKE); myPaint.setStrokeWidth(1); if(mCanvasMatrix!=null){ if(orignalRect!=null) mCanvasMatrix.mapRect(orignalRect); } if(orignalRect!=null){ canvas.drawRect(orignalRect,myPaint); } //canvas.drawRect(rect_x1-30,rect_y1-30, rect_x1+30, rect_y1+30, myPaint); int canavs_width=canvas.getWidth(); int canavs_height=canvas.getHeight(); canvas.setMatrix(mCanvasMatrix); //canvas.setMatrix(mMatrix); if(mDrawable!=null){ //mDrawable.draw(canvas); Log.v("Log_tag", "draw with Canvas is done W:"+ canavs_width+"H:"+ canavs_height); } //canvas.restore(); } private float MAX_SCALE = 2f; private int DOUBLE_TAP_SECOND = 400; private float CANVAS_MAX_SCALE=2f; float rect_x1=50; float rect_y1=150; private Matrix mMatrix; private Matrix mCanvasMatrix; private final float[] mCanvasMatrixValues=new float[9]; private final float[] mMatrixValues = new float[9]; RectF orignalRect; private Drawable mDrawable; private ImageView mImageView; // display width height. private int mWidth; private int mHeight; private int mIntrinsicWidth; private int mIntrinsicHeight; private int mCanvasWidth; private int mCanvasHeight; private float mScale; private float mMinScale; private float mCanvasMinScale; // double tap for determining private long mLastTime = 0; private boolean isDoubleTap; private int mDoubleTapX; private int mDoubleTapY; private float mPrevDistance; private boolean isScaling; private int mPrevMoveX; private int mPrevMoveY; String TAG = "ScaleImageView"; public ImageViewScale(Context context, AttributeSet attr) { super(context, attr); initialize(); } public ImageViewScale(Context context) { super(context); initialize(); } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); this.initialize(); } private void initialize() { this.setScaleType(ScaleType.MATRIX); this.mMatrix = new Matrix(); Drawable d = getDrawable(); mDrawable=d; if (d != null) { mIntrinsicWidth = d.getIntrinsicWidth(); mIntrinsicHeight = d.getIntrinsicHeight(); setOnTouchListener(this); } } @Override protected boolean setFrame(int l, int t, int r, int b) { Log.v("Log_tag", "Size are here "+ l + t + r+ b); mWidth = r - l; mHeight = b - t; mMatrix.reset(); mScale = (float) r / (float) mIntrinsicWidth; int paddingHeight = 0; int paddingWidth = 0; // scaling vertical if (mScale * mIntrinsicHeight > mHeight) { mScale = (float) mHeight / (float) mIntrinsicHeight; mMatrix.postScale(mScale, mScale); paddingWidth = (r - mWidth) / 2; paddingHeight = 0; // scaling horizontal } else { mMatrix.postScale(mScale, mScale); paddingHeight = (b - mHeight) / 2; paddingWidth = 0; } mMatrix.postTranslate(paddingWidth, paddingHeight); setImageMatrix(mMatrix); mMinScale = mScale; zoomTo(mScale, mWidth / 2, mHeight / 2); cutting(); return super.setFrame(l, t, r, b); } protected float getValue(Matrix matrix, int whichValue) { matrix.getValues(mMatrixValues); return mMatrixValues[whichValue]; } //New Added protected float getCanvasValue(Matrix matrix,int whichvalues){ mCanvasMatrix.getValues(mCanvasMatrixValues); return mCanvasMatrixValues[whichvalues]; } protected float getScale() { return getValue(mMatrix, Matrix.MSCALE_X); } //New added Method protected float getCanvasScale(){ return getCanvasValue(mCanvasMatrix, Matrix.MSCALE_X); } protected float getTranslateX() { return getValue(mMatrix, Matrix.MTRANS_X); } //New added Method protected float getCanvasTranslateX(){ return getCanvasValue(mCanvasMatrix, Matrix.MTRANS_X); } protected float getTranslateY() { return getValue(mMatrix, Matrix.MTRANS_Y); } //New Added Method protected float getCanvasTranslateY(){ return getCanvasValue(mCanvasMatrix, Matrix.MTRANS_Y); } protected void maxZoomTo(int x, int y) { if (mMinScale != getScale() && (getScale() - mMinScale) > 0.1f) { // threshold 0.1f float scale = mMinScale / getScale(); zoomTo(scale, x, y); } else { float scale = MAX_SCALE / getScale(); zoomTo(scale, x, y); } } protected void zoomTo(float scale, int x, int y) { if (getScale() * scale < mMinScale) { return; } if (scale >= 1 && getScale() * scale > MAX_SCALE) { return; } mMatrix.postScale(scale, scale); // move to center mMatrix.postTranslate(-(mWidth * scale - mWidth) / 2, -(mHeight * scale - mHeight) / 2); // move x and y distance mMatrix.postTranslate(-(x - (mWidth / 2)) * scale, 0); mMatrix.postTranslate(0, -(y - (mHeight / 2)) * scale); setImageMatrix(mMatrix); } protected void zoomToCanvas(float scale,int x,int y){ if(getCanvasScale()* scale<mCanvasMinScale){ return; } if(scale>=1 && getCanvasScale()*scale> CANVAS_MAX_SCALE){ return; } mCanvasMatrix.postScale(scale, scale); } public void cutting() { int width = (int) (mIntrinsicWidth * getScale()); int height = (int) (mIntrinsicHeight * getScale()); if (getTranslateX() < -(width - mWidth)) { mMatrix.postTranslate(-(getTranslateX() + width - mWidth), 0); } if (getTranslateX() > 0) { mMatrix.postTranslate(-getTranslateX(), 0); } if (getTranslateY() < -(height - mHeight)) { mMatrix.postTranslate(0, -(getTranslateY() + height - mHeight)); } if (getTranslateY() > 0) { mMatrix.postTranslate(0, -getTranslateY()); } if (width < mWidth) { mMatrix.postTranslate((mWidth - width) / 2, 0); } if (height < mHeight) { mMatrix.postTranslate(0, (mHeight - height) / 2); } setImageMatrix(mMatrix); } private float distance(float x0, float x1, float y0, float y1) { float x = x0 - x1; float y = y0 - y1; return FloatMath.sqrt(x * x + y * y); } private float dispDistance() { return FloatMath.sqrt(mWidth * mWidth + mHeight * mHeight); } @Override public boolean onTouchEvent(MotionEvent event) { int touchCount = event.getPointerCount(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_1_DOWN: case MotionEvent.ACTION_POINTER_2_DOWN: if (touchCount >= 2) { float distance = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1)); mPrevDistance = distance; isScaling = true; } else { if (System.currentTimeMillis() <= mLastTime + DOUBLE_TAP_SECOND) { if (30 > Math.abs(mPrevMoveX - event.getX()) + Math.abs(mPrevMoveY - event.getY())) { isDoubleTap = true; mDoubleTapX = (int) event.getX(); mDoubleTapY = (int) event.getY(); } } mLastTime = System.currentTimeMillis(); mPrevMoveX = (int) event.getX(); mPrevMoveY = (int) event.getY(); } break; case MotionEvent.ACTION_MOVE: if (touchCount >= 2 && isScaling) { float dist = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1)); float scale = (dist - mPrevDistance) / dispDistance(); mPrevDistance = dist; scale += 1; scale = scale * scale; zoomTo(scale, mWidth / 2, mHeight / 2); cutting(); } else if (!isScaling) { int distanceX = mPrevMoveX - (int) event.getX(); int distanceY = mPrevMoveY - (int) event.getY(); mPrevMoveX = (int) event.getX(); mPrevMoveY = (int) event.getY(); mMatrix.postTranslate(-distanceX, -distanceY); cutting(); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_POINTER_2_UP: if (event.getPointerCount() <= 1) { isScaling = false; if (isDoubleTap) { if (30 > Math.abs(mDoubleTapX - event.getX()) + Math.abs(mDoubleTapY - event.getY())) { maxZoomTo(mDoubleTapX, mDoubleTapY); cutting(); } } } isDoubleTap = false; break; } return true; } @Override public boolean onTouch(View v, MotionEvent event) { int count_touch=event.getPointerCount(); switch(event.getAction()){ case MotionEvent.ACTION_UP: float point_x=event.getX(); float point_y=event.getY(); rect_x1=point_x; rect_y1=point_y; if(count_touch==1){ orignalRect=new RectF(rect_x1-30, rect_y1-30, rect_x1+30, rect_y1+30); invalidate(); } break; } return super.onTouchEvent(event); } }


@ Herry: he hecho un pequeño POC sobre este tipo de problema y he encontrado que tenemos que transformar exactamente el lienzo mientras estamos transformando la vista de imagen.

Ejemplo:

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Resources res = this.getResources(); Bitmap mBitmap = BitmapFactory.decodeResource(res, R.drawable.circlered); canvas.save(); canvas.translate(1f, 1f); canvas.restore(); canvas.save(); canvas.concat(mMatrix); canvas.drawBitmap(mBitmap, 100, 150, null); }

¡Intenta esto! y déjame saber.


Es posible que desee Matrix.mapRect . Utilice este método para transformar el rectángulo en la misma cantidad que la imagen en la vista de imagen.

boolean onTouch(MotionEvent ev) { .... // this rect dimensions should be initial values and should be a member. mOriginalRect = new RectF(rect_x1-30, rect_y1-30, rect_x1+30, rect_y1+30); ..... } @Override protected void onDraw(Canvas canvas) { .... mCanvasMatrix = canvas.getMatrix(); ///matrix should have scale values.. mCanvasMatrix.mapRect(tempRect, mOriginalRect); // mOriginalRect is src canvas.drawRect(tempRect, myPaint); // draw tempRect.. .... }


Probablemente desee ampliar ImageView, en las vistas de Dibujar (Lienzo) dibujaría el rectángulo.

Extienda ImageView una vez para hacer pinch-to-zoom (que debería usar Matrix en la vista de imagen para implementar el zoom de pinch)

Extiéndelo nuevamente para tomar un rectángulo, transformarlo usando la matriz de la imagen y dibujarlo después de la llamada super.draw ().