【问题标题】:How to draw a circle after zoom in android如何在android放大后画一个圆圈
【发布时间】:2011-12-15 17:10:30
【问题描述】:

我正在使用图像视图并使用 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
   }

请帮助我。缩放后我需要在正确的位置画圆。

任何帮助将不胜感激。

【问题讨论】:

  • 您找到解决方案了吗?我在我的应用中也发现了同样的问题。
  • 我找不到解决方案,如果找到解决方案,我会通知您。

标签: android bitmap imageview zooming


【解决方案1】:

如下 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);
}

}

【讨论】:

    【解决方案2】:

    如果不知道您要做什么,很难正确回答。

    我建议您创建另一个扩展 View 的类,并使用它在您的活动中的 ImageView 顶部绘制圆圈。这也可以让您绘制尽可能多的圆圈(如果您计划绘制超过 1 个),而无需在 Activity 中创建一些函数。

    一旦您创建了扩展 View 的类,然后在 onDraw() 方法上,您可以通过 canvas.drawCircle() 和 canvas.translate() 绘制圆圈以在屏幕上移动它。为此,您必须使用 onTouchEvent 并拦截触摸事件。

    这里有一个很好的例子,其中包含 apk:http://adblogcat.com/custom-view-to-draw-rotate-erase-and-convert-images-to-black-and-white/

    【讨论】:

      【解决方案3】:

      您能否添加显示您想要获得的图像的图像和显示您获得的图像的图片?

      要记住的一点是,某些操作对 y 轴使用不同的零点。我一直在在表面视图上的矩阵运算上与此作斗争,在那里我必须计算一个校正因子,因为一个操作使用视图的顶部作为 y=0,而矩阵操作使用视图的底部作为 y=0 ,所以实际的矩阵运算需要类似:matrixY = (totalHeightY - Yposition)。

      但显示您的期望和得到的结果将有助于比运行和处理您的代码更快地诊断问题:)

      【讨论】:

        【解决方案4】:

        在您使用 postTranslate 以确保视图将图像设置在正确的位置之前,我可以看到 matrix.preTranslate 尚未使用。

        【讨论】:

        • 感谢您的回复。我已经尝试不拖动仅缩放,但缩放后我仍然无法在正确的位置绘制圆圈。我认为缩放后原始图像正在改变,不知道如何在不改变原始图像的情况下进行缩放。
        • 您必须创建一个空的可变位图对象,如下所述,您可以对此位图进行更改,然后使用 imageview 设置ImageBitmap。
        • 位图 bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon); Bitmap changedBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());画布画布 = 新画布(改变位图);油漆油漆 = 新油漆();矩阵矩阵 = 新矩阵(); matrix.setScale(1.5f, 1.0f,0, 0); canvas.drawBitmap(bmp, 矩阵, 绘画); ImageView 图像 = (ImageView)findViewById(R.id.image); image.setImageBitmap(alteredBitmap);
        • 我已经尝试使用上面的代码仍然面临同样的问题,如果你有,请分享示例实现,我在缩放后在正确的位置绘制了圆圈。
        猜你喜欢
        • 2012-11-12
        • 1970-01-01
        • 1970-01-01
        • 2021-06-24
        • 1970-01-01
        • 2014-11-15
        • 2021-10-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多