画像のトリミングを行いたい(複雑)その2

※公式な方法ではなく、個人的に考えた実装方法になりますので、ご利用の責任はお持ちできませんのでご了承下さい。

前回は「デフォルトで用意されている、トリミングの機能を使わないで独自で実装を行うように」と書きましたが、今回はその設計を考えていきたいと思います。

1、枠を作る。

2、枠をつかめるようにする。

3、枠の拡大縮小を行う。

4、枠のデータをデザインに合わせる。

5、枠を画像のあわせる。

6、枠の位置と大きさと、画像の位置を比較して、Bitmapのトリミングを使って画像をトリミング。

という流れがよいかと思います。

尚、今回は枠を小さくすると、画像が大きくなると言う仕様は割愛しております。(よくあるんですが、不要かと。。)

更には正方形でのトリミングをしております。

 

では、最初にですが、枠を作りたいとおもいます。

枠に関しては、Viewを利用して作成するのが簡単かと思います

 

TrimViewというのを作成して、最初なので白い画像の枠を作成してみたいと思います。

public TrimView(Context context) {
    super(context);
    paint = new Paint();
    paint.setColor(Color.WHITE);
    paint.setAntiAlias(true);
}

コンストラクタではpaintの用意だけ行いました。

位置のデータですが、中心点と横幅、縦幅で考えます。

SizeChangeで横幅と縦幅が取得できるので必要なデータを用意しておきます。

尚最初に関しては、四角を中心に、また、横幅に40くらいのサイズの余裕を持たせてみます。

protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    _w = w;
    _h = h;
    sqWidth = w-40;
    sqHeight = w-40;
    sqX = w/2;
    sqY = h/2;
}

描画は次のようにすれば四角が現れます。

protected void onDraw(Canvas canvas) {
    canvas.drawRect(sqX-sqWidth/2, sqY-sqHeight/2, sqX+sqWidth/2, sqY + sqHeight/2, paint);
}

これで表示は

となります。

つかむ方法は下記のように実装します。(ドラッグアンドドロップ)

public boolean onTouchEvent(MotionEvent e) {
    switch (e.getAction()) {
    case MotionEvent.ACTION_DOWN:
        _x = e.getX();
        _y = e.getY();
        if(sqX-sqWidth/2 < _x && sqX+sqWidth/2 > _x){
            //x的にいうと触れている
            if(sqY-sqHeight/2 < _y && sqY+sqHeight/2 > _y){
                //y的にいうと触れている
                TouchMode = "MOVE";
            }
        }
        
        break;
    case MotionEvent.ACTION_MOVE:
         if (TouchMode == "MOVE") {
             float disX =e.getX()-_x;
             float disY =e.getY()-_y;
             
             sqX += disX;
             sqY += disY;
             
             if(sqX-sqWidth/2 < 0 ){
                 sqX = sqWidth/2; 
             }else if(sqX+sqWidth/2 > _w){
                 sqX = _w - sqWidth/2;
             }
             if(sqY-sqHeight/2 < 0 ){
                 sqY = sqHeight/2; 
             }else if(sqY + sqHeight/2  > _h){
                 sqY = _h - sqHeight/2;
             }
             _x = e.getX();
             _y = e.getY();
         }
        invalidate();
        break;
    case MotionEvent.ACTION_UP:
        TouchMode = "NONE";
        break;
    default:
        break;
    }
    return true;
}

上記のようにします。簡単に説明をすると、Viewにタッチした時だと、全体に広がってしまうので、四角の内部をタッチした場合を考えたいので、今ifで分岐をしています。また、内部で、四角を移動させる時には、四角自体は画面からはみ出てしまうと、実際にトリミングされた部分がわからなくなったり、トリミングをするエリアをつかめなくなってしまうので、はみ出ないような仕様をいれております。

これで、四角を作ってつかむところまで出来ました。

次回は、サイズの変更とデザインの変更を行いたいとおもいます。

今回のソースです。

public class TrimView extends View {

    public float _x = 0, _y = 0;
    Paint paint;
        
    public TrimView(Context context) {
        super(context);
        paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setAntiAlias(true);
    }

        int _w = 0;
        int _h = 0;
        int sqWidth = 0;
        int sqHeight = 0;
        int sqX = 0;
        int sqY = 0;
        
        
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        _w = w;
        _h = h;
        sqWidth = w - 40;
        sqHeight = w - 40;
        sqX = w / 2;
        sqY = h / 2;
    }

    protected void onDraw(Canvas canvas) {
        canvas.drawRect(sqX - sqWidth / 2, sqY - sqHeight / 2, sqX + sqWidth
                / 2, sqY + sqHeight / 2, paint);
    }

    String TouchMode = "NONE";

    public boolean onTouchEvent(MotionEvent e) {
        switch (e.getAction()) {
        case MotionEvent.ACTION_DOWN:
            _x = e.getX();
            _y = e.getY();
            if (sqX - sqWidth / 2 < _x && sqX + sqWidth / 2 > _x) {
                // x的にいうと触れている
                if (sqY - sqHeight / 2 < _y && sqY + sqHeight / 2 > _y) {
                    // y的にいうと触れている
                    TouchMode = "MOVE";
                }
            }

            break;
        case MotionEvent.ACTION_MOVE:
            if (TouchMode == "MOVE") {
                float disX = e.getX() - _x;
                float disY = e.getY() - _y;

                sqX += disX;
                sqY += disY;

                if (sqX - sqWidth / 2 < 0) {
                    sqX = sqWidth / 2;
                } else if (sqX + sqWidth / 2 > _w) {
                    sqX = _w - sqWidth / 2;
                }
                if (sqY - sqHeight / 2 < 0) {
                    sqY = sqHeight / 2;
                } else if (sqY + sqHeight / 2 > _h) {
                    sqY = _h - sqHeight / 2;
                }
                _x = e.getX();
                _y = e.getY();
            }
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            TouchMode = "NONE";
            break;
        default:
            break;
        }
        return true;
    }
        

}

 

 

前後の記事

前の記事:

次の記事:

関連の記事

コメントの投稿

  • サイト内検索

新作アプリの紹介

関連サイトの紹介

アンドロイドアプリ開発TIPS
きぐるみカメラ
ふらいぱん
アンドロイドのデザイン集
Page top↑