Putting some indicator around the image in image m

2019-03-08 05:57发布

I would like to Scale, Move, Resize Image. I would like to surround the image with Indicators which guide user what operation these indicators perform i.e. Moving, Rotating, Scaling.

enter image description here

I've tried

  • Scaling - but it only crops down. No chance to increase length and height of image.
  • Rotate - achieved but via inserting manual degrees. That's not a good option in here.
  • Moving - as I'm achieving drag on Api < 11. So little bit of difficult. Still no hope in here.

Is there any library which can do me simple image edit [Move, Scale, Rotate]?

8条回答
乱世女痞
2楼-- · 2019-03-08 06:09

I recently tried the same thing but ended up using a library since it covered a lot more edge cases. This is a great, and pretty widely used library:

http://code.google.com/p/android-multitouch-controller/

查看更多
别忘想泡老子
3楼-- · 2019-03-08 06:09

I think I can help you with the rotation part. I recently made an android wheel menu library. It tracks user's hand motion and rotates the imageview accordingly. You can check out the source to see how I did it here:

https://github.com/anupcowkur/Android-Wheel-Menu

查看更多
贼婆χ
4楼-- · 2019-03-08 06:09

Bitmap rotation

Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight, config);
Canvas canvas = new Canvas(targetBitmap);
Matrix matrix = new Matrix();
matrix.setRotate(mRotation,source.getWidth()/2,source.getHeight()/2);
canvas.drawBitmap(source, matrix, new Paint());

Image Scaling Scaling

AssetManager assetManager = context.getAssets();
InputStream imageIn;
String imgPath = "test.png";
Bitmap image;
try {
    imageIn = assetManager.open(imgPath, AssetManager.ACCESS_BUFFER);
    image = BitmapFactory.decodeStream(imageIn);
} catch (IOException e) {

}
//TODO: calculate width and height to fill or fit screen
image = Bitmap.createScaledBitmap(image, width, height, true);

Image moving Image in Canvas with touch events

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;

public class ImgView extends View {

private static final int INVALID_POINTER_ID = -1;

    private Drawable mImage;
    private float mPosX;
    private float mPosY;

    private float mLastTouchX;
    private float mLastTouchY;
    private int mActivePointerId = INVALID_POINTER_ID;

    private ScaleGestureDetector mScaleDetector;
    private float mScaleFactor = 1.f;

    public ImgView(Context context) {
        this(context, null, 0);
    mImage = getResources().getDrawable(R.drawable.imagename);

        mImage.setBounds(0, 0, mImage.getIntrinsicWidth(), mImage.getIntrinsicHeight());
    }

    public ImgView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ImgView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // Let the ScaleGestureDetector inspect all events.
        mScaleDetector.onTouchEvent(ev);

        final int action = ev.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN: {
            final float x = ev.getX();
            final float y = ev.getY();

            mLastTouchX = x;
            mLastTouchY = y;
            mActivePointerId = ev.getPointerId(0);
            break;
        }

        case MotionEvent.ACTION_MOVE: {
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(pointerIndex);
            final float y = ev.getY(pointerIndex);

            // Only move if the ScaleGestureDetector isn't processing a gesture.
            if (!mScaleDetector.isInProgress()) {
                final float dx = x - mLastTouchX;
                final float dy = y - mLastTouchY;

                mPosX += dx;
                mPosY += dy;

                invalidate();
            }

            mLastTouchX = x;
            mLastTouchY = y;

            break;
        }

        case MotionEvent.ACTION_UP: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_CANCEL: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_POINTER_UP: {
            final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
                    >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            final int pointerId = ev.getPointerId(pointerIndex);
            if (pointerId == mActivePointerId) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouchX = ev.getX(newPointerIndex);
                mLastTouchY = ev.getY(newPointerIndex);
                mActivePointerId = ev.getPointerId(newPointerIndex);
            }
            break;
        }
        }

        return true;
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.save();
        Log.d("DEBUG", "X: "+mPosX+" Y: "+mPosY);
        canvas.translate(mPosX, mPosY);
        canvas.scale(mScaleFactor, mScaleFactor);
        mImage.draw(canvas);
        canvas.restore();
    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            mScaleFactor *= detector.getScaleFactor();

            // Don't let the object get too small or too large.
            mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));

            invalidate();
            return true;
        }
    }

}
查看更多
祖国的老花朵
5楼-- · 2019-03-08 06:10

You can use Matrix transaformation to achieve rotating, scaling, and moving....I hope this will help you....

for rotating

Matrix matrix = new Matrix();
    matrix.postRotate(90);

for scaling

 matrix.postScale(scaleWidth, scaleHeight);

create new bitmap without changing the original one...like this

Bitmap bmp2 = Bitmap.createBitmap(bmp1, 0, 0, pow2, pow2, matrix, true);
查看更多
别忘想泡老子
6楼-- · 2019-03-08 06:12
干净又极端
7楼-- · 2019-03-08 06:15

Using Library : StickerView

Its a 3rd Party Library which gives exactly what i was looking for.

WorkAround :

Still these answer is half of what I've asked for in OP. Means It ain't surronded by some specific Indicator. I'm still searching how to wrap ImageView with indicators and use them for Translate & Resize.

Initilization of Variables inside Activity important for Translate & Resize ImageView

public static final int DRAG = 1;
public static final int NONE = 0;
private static final String TAG = "Touch";
public static final int ZOOM = 2;
public static PointF mid = new PointF();
public static int mode = 0;
float d = 0.0F;
Matrix savedMatrix = new Matrix();
Matrix matrix = new Matrix();
PointF start = new PointF();

Setting ImageView to scaleType - Matrix

iv = new ImageView(this);
iv.setPadding(10, 10, 25, 25);
iv.setScaleType(ImageView.ScaleType.MATRIX);

iv.setOnTouchListener(t);

Adding onTouch Listener to ImageView which uses

  • 1 Finger for Translate - Drag
  • 2 Finger for Zoom - Resize {Pinch To Zoom}

    View.OnTouchListener t = new View.OnTouchListener()
    {
    public boolean onTouch(View paramView, MotionEvent event)
    {
      ImageView view = (ImageView)paramView;
      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_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;
    
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_POINTER_UP:
    
          mode = NONE;
          Log.d(TAG, "mode=NONE" );
          break;
      }  
      view.setImageMatrix(matrix);
      return true;
    
    }
    
     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 / 2, y / 2);
    }
    
          private float spacing(MotionEvent event) {
          float x = event.getX(0) - event.getX(1);
          float y = event.getY(0) - event.getY(1);
          return FloatMath.sqrt(x * x + y * y);
          }
         };
    
查看更多
登录 后发表回答