Ajuda Zoom em Duas ImageViews

24 views
Skip to first unread message

Matheus Ariel

unread,
Mar 3, 2016, 3:47:46 PM3/3/16
to Android Brasil - Dev
Meu projeto android possui 2 imageViews, uma para abrir uma imagem e outra para desenhar retângulos sobre a imagem, o problema está que eu tenho que dar zoom nas duas imageViews ao mesmo tempo, alguém podeira me ajudar? Ou me dar dicas de como eu posso resolver esse problema.

Thiago Lopes Rosa

unread,
Mar 3, 2016, 6:15:35 PM3/3/16
to androidbrasil-dev
O que você já tentou fazer? Qual problema você encontrou?

On Thu, Mar 3, 2016 at 5:47 PM, Matheus Ariel <matheu...@gmail.com> wrote:
Meu projeto android possui 2 imageViews, uma para abrir uma imagem e outra para desenhar retângulos sobre a imagem, o problema está que eu tenho que dar zoom nas duas imageViews ao mesmo tempo, alguém podeira me ajudar? Ou me dar dicas de como eu posso resolver esse problema.

--
You received this message because you are subscribed to the Google Groups "Android Brasil - Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to androidbrasil-...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Matheus Ariel

unread,
Mar 4, 2016, 6:23:49 AM3/4/16
to Android Brasil - Dev
Olá Thiago, primeiramente obrigado por se interessar em tentar resolver meu problema.
Bem eu tentei usar uma lib chamada PhotoView:
(essa lib)

Originalmente um método é assim:



public void usingSimpleImage(ImageView imageView)
{
    ImageAttacher mAttacher = new ImageAttacher(imageView);
    ImageAttacher.MAX_ZOOM = 2.5f; // Double the current Size
    ImageAttacher.MIN_ZOOM = 1.0f; // Half the current Size
    MatrixChangeListener mMaListener = new MatrixChangeListener();
    mAttacher.setOnMatrixChangeListener(mMaListener);
    PhotoTapListener mPhotoTap = new PhotoTapListener();
    mAttacher.setOnPhotoTapListener(mPhotoTap);
}


Porém tentei adaptar para isso:

 public void usingSimpleImage(ImageView imageView, ImageView imageView2)
    {
        ImageAttacher mAttacher = new ImageAttacher(imageView);
        ImageAttacher mAttacher2 = new ImageAttacher(imageView2);
        ImageAttacher.MAX_ZOOM = 2.5f; // Double the current Size
        ImageAttacher.MIN_ZOOM = 1.0f; // Half the current Size
        MatrixChangeListener mMaListener = new MatrixChangeListener();
        mAttacher.setOnMatrixChangeListener(mMaListener);
        mAttacher2.setOnMatrixChangeListener(mMaListener);

        PhotoTapListener mPhotoTap = new PhotoTapListener();
        mAttacher.setOnPhotoTapListener(mPhotoTap);
        mAttacher2.setOnPhotoTapListener(mPhotoTap);

    }


Porém não deu certo, vc tem alguma idéia para eu tentar resolver esse problema?

Willian do Amor

unread,
Mar 4, 2016, 6:27:09 AM3/4/16
to androidb...@googlegroups.com
Bom dia Matheus,

eu também tentei usar o PhotoView, mas nao obtive sucesso.

Consegui resolver meu problema com essa lib aqui 


pra mim funcionou, veja se te ajuda.




Matheus Ariel

unread,
Mar 4, 2016, 6:46:43 AM3/4/16
to androidb...@googlegroups.com
Muito Obrigado pela ajuda Willian.
Estou começando agora no desenvolvimento android, e tenho uma dúvida, pois não estou conseguindo muito bem entender essa lib, é difícil implementar ela?  Procurei por exemplos de implementação dela, porém não achei, caso vc tenha e puder me passar eu agradeceria, de qualquer forma agradeço mais uma vez.

--
You received this message because you are subscribed to a topic in the Google Groups "Android Brasil - Dev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/androidbrasil-dev/2WKoCVQKxJY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to androidbrasil-...@googlegroups.com.

Willian do Amor

unread,
Mar 4, 2016, 7:59:51 AM3/4/16
to androidb...@googlegroups.com
cara, tambem faz pouco tempo que comecei a desenvolver. Essa foi a lib que mais me identifiquei e achei facil de configurar.

A minha necessidade era simples e eu fiz conforme diz la no site.

Veja um exemplo da minha classe que usa a lib.
FragFotoProduto.java

Matheus Ariel

unread,
Mar 9, 2016, 1:38:54 PM3/9/16
to Android Brasil - Dev
Sem sucesso, alguém me sugere alguma outra solução?

Matheus Ariel

unread,
Mar 10, 2016, 12:16:25 PM3/10/16
to Android Brasil - Dev
Pessoal, eu consegui e vou compartilhar o jeito, pois espero que seja útil para alguém. Bem primeiro você precisa criar uma classe que irá ter métodos para o zoom e para o pan das imageiews, segue o código:


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

/**
* Zooming view.
*/
public class Zoom2 extends FrameLayout {

public Zoom2(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}

public Zoom2(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

public Zoom2(final Context context) {
super(context);
}

/**
* Zooming view listener interface.
*
* @author karooolek
*
*/
public interface ZoomViewListener {

void onZoomStarted(float zoom, float zoomx, float zoomy);

void onZooming(float zoom, float zoomx, float zoomy);

void onZoomEnded(float zoom, float zoomx, float zoomy);
}

// zooming
float zoom = 1.0f;
float maxZoom = 5.0f;
float smoothZoom = 1.0f;
float zoomX, zoomY;
float smoothZoomX, smoothZoomY;
private boolean scrolling; // NOPMD by karooolek on 29.06.11 11:45

// minimap variables
private boolean showMinimap = false;
private int miniMapColor = Color.WHITE;
private int miniMapHeight = -1;
private String miniMapCaption;
private float miniMapCaptionSize = 10.0f;
private int miniMapCaptionColor = Color.WHITE;

// touching variables
private long lastTapTime;
private float touchStartX, touchStartY;
private float touchLastX, touchLastY;
private float startd;
private boolean pinching;
private float lastd;
private float lastdx1, lastdy1;
private float lastdx2, lastdy2;

// drawing
private final Matrix m = new Matrix();
private final Paint p = new Paint();

// listener
ZoomViewListener listener;

private Bitmap ch;

public float getZoom() {
return zoom;
}

public float getMaxZoom() {
return maxZoom;
}

public void setMaxZoom(final float maxZoom) {
if (maxZoom < 1.0f) {
return;
}

this.maxZoom = maxZoom;
}

public void setMiniMapEnabled(final boolean showMiniMap) {
this.showMinimap = showMiniMap;
}

public boolean isMiniMapEnabled() {
return showMinimap;
}

public void setMiniMapHeight(final int miniMapHeight) {
if (miniMapHeight < 0) {
return;
}
this.miniMapHeight = miniMapHeight;
}

public int getMiniMapHeight() {
return miniMapHeight;
}

public void setMiniMapColor(final int color) {
miniMapColor = color;
}

public int getMiniMapColor() {
return miniMapColor;
}

public String getMiniMapCaption() {
return miniMapCaption;
}

public void setMiniMapCaption(final String miniMapCaption) {
this.miniMapCaption = miniMapCaption;
}

public float getMiniMapCaptionSize() {
return miniMapCaptionSize;
}

public void setMiniMapCaptionSize(final float size) {
miniMapCaptionSize = size;
}

public int getMiniMapCaptionColor() {
return miniMapCaptionColor;
}

public void setMiniMapCaptionColor(final int color) {
miniMapCaptionColor = color;
}

public void zoomTo(final float zoom, final float x, final float y) {
this.zoom = Math.min(zoom, maxZoom);
zoomX = x;
zoomY = y;
smoothZoomTo(this.zoom, x, y);
}

public void smoothZoomTo(final float zoom, final float x, final float y) {
smoothZoom = clamp(1.0f, zoom, maxZoom);
smoothZoomX = x;
smoothZoomY = y;
if (listener != null) {
listener.onZoomStarted(smoothZoom, x, y);
}
}

public ZoomViewListener getListener() {
return listener;
}

public void setListner(final ZoomViewListener listener) {
this.listener = listener;
}

public float getZoomFocusX() {
return zoomX * zoom;
}

public float getZoomFocusY() {
return zoomY * zoom;
}

@Override
public boolean dispatchTouchEvent(final MotionEvent ev) {
// single touch
if (ev.getPointerCount() == 1) {
processSingleTouchEvent(ev);
}

// // double touch
if (ev.getPointerCount() == 2) {
processDoubleTouchEvent(ev);
}

// redraw
getRootView().invalidate();
invalidate();

return true;
}

private void processSingleTouchEvent(final MotionEvent ev) {

final float x = ev.getX();
final float y = ev.getY();

final float w = miniMapHeight * (float) getWidth() / getHeight();
final float h = miniMapHeight;
final boolean touchingMiniMap = x >= 10.0f && x <= 10.0f + w
&& y >= 10.0f && y <= 10.0f + h;

if (showMinimap && smoothZoom > 1.0f && touchingMiniMap) {
processSingleTouchOnMinimap(ev);
} else {
processSingleTouchOutsideMinimap(ev);
}
}

private void processSingleTouchOnMinimap(final MotionEvent ev) {
final float x = ev.getX();
final float y = ev.getY();

final float w = miniMapHeight * (float) getWidth() / getHeight();
final float h = miniMapHeight;
final float zx = (x - 10.0f) / w * getWidth();
final float zy = (y - 10.0f) / h * getHeight();
smoothZoomTo(smoothZoom, zx, zy);
}

private void processSingleTouchOutsideMinimap(final MotionEvent ev) {
final float x = ev.getX();
final float y = ev.getY();
float lx = x - touchStartX;
float ly = y - touchStartY;
final float l = (float) Math.hypot(lx, ly);
float dx = x - touchLastX;
float dy = y - touchLastY;
touchLastX = x;
touchLastY = y;

switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
touchStartX = x;
touchStartY = y;
touchLastX = x;
touchLastY = y;
dx = 0;
dy = 0;
lx = 0;
ly = 0;
scrolling = false;
break;

case MotionEvent.ACTION_MOVE:
if (scrolling || (smoothZoom > 1.0f && l > 30.0f)) {
if (!scrolling) {
scrolling = true;
ev.setAction(MotionEvent.ACTION_CANCEL);
super.dispatchTouchEvent(ev);
}
smoothZoomX -= dx / zoom;
smoothZoomY -= dy / zoom;
return;
}
break;

case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_UP:

// tap
if (l < 30.0f) {
// check double tap
if (System.currentTimeMillis() - lastTapTime < 500) {
if (smoothZoom == 1.0f) {
smoothZoomTo(maxZoom, x, y);
} else {
smoothZoomTo(1.0f, getWidth() / 2.0f,
getHeight() / 2.0f);
}
lastTapTime = 0;
ev.setAction(MotionEvent.ACTION_CANCEL);
super.dispatchTouchEvent(ev);
return;
}

lastTapTime = System.currentTimeMillis();

performClick();
}
break;

default:
break;
}

ev.setLocation(zoomX + (x - 0.5f * getWidth()) / zoom, zoomY
+ (y - 0.5f * getHeight()) / zoom);

ev.getX();
ev.getY();

super.dispatchTouchEvent(ev);
}

private void processDoubleTouchEvent(final MotionEvent ev) {
final float x1 = ev.getX(0);
final float dx1 = x1 - lastdx1;
lastdx1 = x1;
final float y1 = ev.getY(0);
final float dy1 = y1 - lastdy1;
lastdy1 = y1;
final float x2 = ev.getX(1);
final float dx2 = x2 - lastdx2;
lastdx2 = x2;
final float y2 = ev.getY(1);
final float dy2 = y2 - lastdy2;
lastdy2 = y2;

// pointers distance
final float d = (float) Math.hypot(x2 - x1, y2 - y1);
final float dd = d - lastd;
lastd = d;
final float ld = Math.abs(d - startd);

Math.atan2(y2 - y1, x2 - x1);
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startd = d;
pinching = false;
break;

case MotionEvent.ACTION_MOVE:
if (pinching || ld > 30.0f) {
pinching = true;
final float dxk = 0.5f * (dx1 + dx2);
final float dyk = 0.5f * (dy1 + dy2);
smoothZoomTo(Math.max(1.0f, zoom * d / (d - dd)), zoomX - dxk
/ zoom, zoomY - dyk / zoom);
}

break;

case MotionEvent.ACTION_UP:
default:
pinching = false;
break;
}

ev.setAction(MotionEvent.ACTION_CANCEL);
super.dispatchTouchEvent(ev);
}

private float clamp(final float min, final float value, final float max) {
return Math.max(min, Math.min(value, max));
}

private float lerp(final float a, final float b, final float k) {
return a + (b - a) * k;
}

private float bias(final float a, final float b, final float k) {
return Math.abs(b - a) >= k ? a + k * Math.signum(b - a) : b;
}

@Override
protected void dispatchDraw(final Canvas canvas) {

// do zoom
zoom = lerp(bias(zoom, smoothZoom, 0.05f), smoothZoom, 0.2f);
smoothZoomX = clamp(0.5f * getWidth() / smoothZoom, smoothZoomX,
getWidth() - 0.5f * getWidth() / smoothZoom);
smoothZoomY = clamp(0.5f * getHeight() / smoothZoom, smoothZoomY,
getHeight() - 0.5f * getHeight() / smoothZoom);

zoomX = lerp(bias(zoomX, smoothZoomX, 0.1f), smoothZoomX, 0.35f);
zoomY = lerp(bias(zoomY, smoothZoomY, 0.1f), smoothZoomY, 0.35f);
if (zoom != smoothZoom && listener != null) {
listener.onZooming(zoom, zoomX, zoomY);
}

final boolean animating = Math.abs(zoom - smoothZoom) > 0.0000001f
|| Math.abs(zoomX - smoothZoomX) > 0.0000001f
|| Math.abs(zoomY - smoothZoomY) > 0.0000001f;

// nothing to draw
if (getChildCount() == 0) {
return;
}

// prepare matrix
m.setTranslate(0.5f * getWidth(), 0.5f * getHeight());
m.preScale(zoom, zoom);
m.preTranslate(
-clamp(0.5f * getWidth() / zoom, zoomX, getWidth() - 0.5f
* getWidth() / zoom),
-clamp(0.5f * getHeight() / zoom, zoomY, getHeight() - 0.5f
* getHeight() / zoom));

// get view
final View v = getChildAt(0);
m.preTranslate(v.getLeft(), v.getTop());

// get drawing cache if available
if (animating && ch == null && isAnimationCacheEnabled()) {
v.setDrawingCacheEnabled(true);
ch = v.getDrawingCache();
}

// draw using cache while animating
if (animating && isAnimationCacheEnabled() && ch != null) {
p.setColor(0xffffffff);
canvas.drawBitmap(ch, m, p);
} else { // zoomed or cache unavailable
ch = null;
canvas.save();
canvas.concat(m);
v.draw(canvas);
canvas.restore();
}

// draw minimap
if (showMinimap) {
if (miniMapHeight < 0) {
miniMapHeight = getHeight() / 4;
}

canvas.translate(10.0f, 10.0f);

p.setColor(0x80000000 | 0x00ffffff & miniMapColor);
final float w = miniMapHeight * (float) getWidth() / getHeight();
final float h = miniMapHeight;
canvas.drawRect(0.0f, 0.0f, w, h, p);

if (miniMapCaption != null && miniMapCaption.length() > 0) {
p.setTextSize(miniMapCaptionSize);
p.setColor(miniMapCaptionColor);
p.setAntiAlias(true);
canvas.drawText(miniMapCaption, 10.0f,
10.0f + miniMapCaptionSize, p);
p.setAntiAlias(false);
}

p.setColor(0x80000000 | 0x00ffffff & miniMapColor);
final float dx = w * zoomX / getWidth();
final float dy = h * zoomY / getHeight();
canvas.drawRect(dx - 0.5f * w / zoom, dy - 0.5f * h / zoom, dx
+ 0.5f * w / zoom, dy + 0.5f * h / zoom, p);

canvas.translate(-10.0f, -10.0f);
}

// redraw
// if (animating) {
getRootView().invalidate();
invalidate();
// }
}
}

depois o detalhe está no xml pois fica assim: ( aqui é indiferente se for uma ou mais imageViews)


 <com.pkg.pie_custom_views.Zoom2
                android:id="@+id/zoomView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_above="@+id/rlBottomTitle"
                android:layout_below="@+id/rlPieTitle"
                android:layout_centerInParent="true" >

<RelativeLayout
                android:id="@+id/zoomView"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
<ImageView
    android:id="@+id/image"
    android:layout_width="50sp"
    android:layout_height="50sp"
    android:clickable="true"
    android:src="@drawable/ic_launcher" >

</ImageView>

<ImageView
    android:id="@+id/image1"
    android:layout_width="50sp"
    android:layout_height="50sp"
    android:layout_x="118dip"
    android:layout_y="30dip"
    android:src="@drawable/ic_launcher" >
</ImageView>
</RealtiveLayout>
 
</com.pkg.pie_custom_views.Zoom2> 


Espero que ajude alguém. Obrigado pela atenção dos que tentaram me ajudar, vlw.

wesley lima da silva

unread,
Mar 10, 2016, 12:18:37 PM3/10/16
to androidb...@googlegroups.com
Obrigado por compartilhar


--
Reply all
Reply to author
Forward
0 new messages