画像を拡大縮小、移動、サイズ変更したいのですが。これらのインジケーターが実行する操作、つまり移動、回転、スケーリングなどをユーザーに案内するインジケーターで画像を囲みます。
私はもう試した
簡単な画像編集[移動、拡大縮小、回転]を実行できるライブラリはありますか?
ライブラリの使用: 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();
ImageView
をscaleTypeに設定-Matrix
iv = new ImageView(this);
iv.setPadding(10, 10, 25, 25);
iv.setScaleType(ImageView.ScaleType.MATRIX);
iv.setOnTouchListener(t);
を使用するImageView
へのonTouchリスナーの追加
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);
}
};
マトリックス変換を使用して、回転、スケーリング、移動を実現できます。
回転用
Matrix matrix = new Matrix();
matrix.postRotate(90);
スケーリング
matrix.postScale(scaleWidth, scaleHeight);
元のビットマップを変更せずに新しいビットマップを作成します...このように
Bitmap bmp2 = Bitmap.createBitmap(bmp1, 0, 0, pow2, pow2, matrix, true);
この画像クロッピングリファレンスをご覧ください。
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
このリンクは、画像のトリミング、回転、スケーリングにも役立ちます。
私は最近同じことを試しましたが、ライブラリがはるかに多くのEdgeケースをカバーしていたため、ライブラリを使用することになりました。これはすばらしい、かなり広く使用されているライブラリです。
https://github.com/siddhpuraamitr/MultitouchWithDynamicAddandRemove プロジェクトでこのコードを試してください
これは答えではありませんが、言及する価値があります。
このプロジェクト を見てください。私はそれをGitHubに配置するつもりですが、まだ(まったく)完了していません。
画像を回転させるボタンがあります。私はまだ「保存」に取り組んでいます。クラスの多くは、Androidおかげで Lorenzo Villaniのプロジェクト)のソースから取得されます
プロジェクトのマニフェストに追加します。
<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);
回転部分のお手伝いができると思います。私は最近Androidホイールメニューライブラリを作成しました。これはユーザーの手の動きを追跡し、それに応じて画像ビューを回転させます。ソースをチェックして、ここでどのようにしたかを確認できます。
ビットマップ回転
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);
イメージの移動タッチイベントを含むキャンバス内のイメージ
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;
}
}
}