29

画像の拡大縮小、移動、サイズ変更をしたいのですが。画像をインジケーターで囲み、これらのインジケーターが実行する操作、つまり移動、回転、スケーリングをユーザーにガイドします。

ここに画像の説明を入力してください

私はもう試した

  • スケーリング-しかし、それは切り詰めるだけです。画像の長さと高さを増やす機会はありません。
  • 回転-達成されますが、手動度を挿入することによって達成されます。ここではそれは良い選択肢ではありません。
  • 移動-Api<11でドラッグを達成しているので、少し難しいです。ここにはまだ希望がありません。

簡単な画像編集[移動、拡大縮小、回転]ができるライブラリはありますか?

4

8 に答える 8

6

マトリックス変換を使用して、回転、スケーリング、および移動を実現できます。これがお役に立てば幸いです。

回転用

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

スケーリング用

 matrix.postScale(scaleWidth, scaleHeight);

元のビットマップを変更せずに新しいビットマップを作成...このように

Bitmap bmp2 = Bitmap.createBitmap(bmp1, 0, 0, pow2, pow2, matrix, true);
于 2013-02-10T16:57:26.670 に答える
4

この画像トリミングリファレンスをチェックしてください:

http://www.londatiga.net/featured-articles/how-to-select-and-crop-image-on-android/

画像の回転については、この例を参照してください。このサンプルコードは、画像の回転を動的に表します。

http://android-er.blogspot.in/2010/07/rotate-bitmap-image-using-matrix.html

このリンクは、画像の切り抜き、回転、拡大縮小にも役立ちます。

https://github.com/Yalantis/uCrop

于 2013-02-19T09:18:13.533 に答える
4

ライブラリの使用:StickerView

私が探していたものを正確に提供するサードパーティのライブラリです。

回避策:

それでも、これらの答えは、私が OP で求めたものの半分です。特定の指標に囲まれていないことを意味します。ImageViewインジケーターでラップし、それらを変換とサイズ変更に使用する方法をまだ探しています。

Activity翻訳とサイズ変更に重要な内部変数の初期化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();

scaleTypeImageViewへの設定 -Matrix

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

iv.setOnTouchListener(t);

ImageView使用する onTouch リスナーの追加

  • 1 本の指で移動 - ドラッグ
  • ズーム用の 2 本の指 - サイズ変更 {ピンチしてズーム}

    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);
          }
         };
    
于 2013-02-19T14:41:29.137 に答える
3

私は最近同じことを試しましたが、より多くのエッジケースをカバーしているため、ライブラリを使用することになりました。これは素晴らしく、かなり広く使用されているライブラリです。

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

于 2013-02-19T01:00:05.690 に答える
2

ローテーションの部分はお手伝いできると思います。最近、Android ホイール メニュー ライブラリを作成しました。ユーザーの手の動きを追跡し、それに応じてイメージビューを回転させます。ソースをチェックアウトして、ここでどのように行ったかを確認できます。

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

于 2013-02-18T08:14:10.127 に答える
2

これが答えではないことはわかっていますが、言及する価値があります。

このプロジェクトを見てください。GitHub に置くつもりですが、まだ (まったく) 完了していません。

画像を回転させるボタンがあります。私はまだ「保存」に取り組んでいます。クラスの多くは、 Lorenzo Villani のプロジェクトのおかげで Android ソースから取得されます。

プロジェクトのマニフェストに追加します。

    <activity
        android:name="mobi.sherif.camera.CropImage"
        android:hardwareAccelerated="false"
        android:screenOrientation="portrait" >

以下を使用してアクティビティを呼び出します。

Intent intent = new Intent(mContext, CropImage.class);
intent.setData(uri);
startActivityForResult(intent, S.request.cropimage);

ここに画像の説明を入力

于 2013-02-20T07:57:50.167 に答える
1

https://github.com/siddhpuraamitr/MultitouchWithDynamicAddandRemoveプロジェクトでこのコードを試すことができます

于 2015-07-08T11:00:55.637 に答える
1

ビットマップの回転

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());

画像のスケーリング スケーリング

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);

画像の移動 タッチ イベントによる Canvas 内の画像

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;
        }
    }

}
于 2013-02-19T08:30:20.073 に答える