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

今回は拡大縮小部分を中心に使いたいと思います。

拡大縮小はこまかく指に追従できるようにもできるのですが。。。

 

今回は割とフランクにいきたいと思います。

中心からの距離をとって、離れていれば拡大、小さくなっていれば、縮小です。勢いよく変わってしまうとうまく設定ができないのでしきい値をつけてあげます。

String TouchMode = "NONE";
float _distance = 0f;

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

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

            sqX += disX;
            sqY += disY;

            
        }else if(TouchMode == "SCALE"){
            
            float _cdistance = culcDistance(sqX,sqY,(int)e.getX(),(int)e.getY());
            
            float _rate = _cdistance/_distance;
            _rate = (_rate < 1.05)? _rate: 1.05f;
            _rate = (_rate > 0.95)? _rate: 0.95f;
            sqWidth *= _rate;
            if(sqWidth > _w){
                sqWidth = _w;
            }else if(sqWidth < 100){
                sqWidth = 100;
            }
            sqHeight = sqWidth;
        }
        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;
        }
        _distance = culcDistance(sqX,sqY,(int)e.getX(),(int)e.getY());
        _x = e.getX();
        _y = e.getY();
        invalidate();
        break;
    case MotionEvent.ACTION_UP:
        TouchMode = "NONE";
        break;
    default:
        break;
    }
    return true;
}

private float culcDistance(int x1,int y1,int x2,int y2) {
    float x = x1 - x2;
    float y = y1 - y2;
    return FloatMath.sqrt(x * x + y * y);
}

前回との重複もあるので細かい説明は割愛するのですが、一応、拡大縮小に関しては、枠を指で触った時としたいのですが、指で触った時など細かい事をやってしまうと、複雑になってしまうので、

見えない枠を考えて、その枠の中にいる場合に限定しております。四角の内部も少し判定があった方が自然なので、少しだけ、もとの四角をつかむエリアを小さくしております。

今回まででデータの枠が作成できたので、デザインにうつりたい思います。

エリアの上下左右には、まず、黒い四角をおいて、灰色のフレーム用に、線を用意して、つかめるのがわかるように、まず。paintを作ります。

paint1 = new Paint();
paint1.setColor(0xdd000000);
paint1.setAntiAlias(true);

paint2 = new Paint();
paint2.setStyle(Style.STROKE);
paint2.setColor(Color.LTGRAY);

paint3 = new Paint();
paint3.setAntiAlias(true);
paint3.setColor(Color.LTGRAY);

で各エリアに対応できるように、図形を書いていってみます。

protected void onDraw(Canvas canvas) {
    
    canvas.drawRect(0, 0, _w, sqY - sqHeight / 2, paint1);
    canvas.drawRect(0, sqY - sqHeight / 2, sqX - sqWidth / 2, sqY + sqHeight / 2, paint1);
    canvas.drawRect(sqX + sqWidth
            / 2, sqY - sqHeight / 2, _w, sqY + sqHeight / 2, paint1);
    canvas.drawRect(0, sqY + sqHeight / 2, _w, _h, paint1);
    
    canvas.drawRect(sqX - sqWidth / 2, sqY - sqHeight / 2, sqX + sqWidth
            / 2, sqY + sqHeight / 2, paint2);
    canvas.drawCircle(sqX, sqY - sqHeight / 2, 12, paint3);
    canvas.drawCircle(sqX, sqY + sqHeight / 2, 12, paint3);
    canvas.drawCircle(sqX - sqWidth / 2, sqY, 12, paint3);
    canvas.drawCircle(sqX + sqWidth / 2, sqY, 12, paint3);
}

で、背景をしいたものに、このviewを載せると

上記のように、一気にトリミングっぽくなってきましたね。

次回はいよいよ画像をトリミングの機能の実装をします。

今回のソースです。

public class TrimView extends View {

    public float _x = 0, _y = 0;
    Paint paint1;
    Paint paint2;
    Paint paint3;
        
    public TrimView(Context context) {
        super(context);
        paint1 = new Paint();
        paint1.setColor(0xdd000000);
        paint1.setAntiAlias(true);
        
        paint2 = new Paint();
        paint2.setStyle(Style.STROKE);
        paint2.setColor(Color.LTGRAY);
        
        paint3 = new Paint();
        paint3.setAntiAlias(true);
        paint3.setColor(Color.LTGRAY);
    }

        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(0, 0, _w, sqY - sqHeight / 2, paint1);
        canvas.drawRect(0, sqY - sqHeight / 2, sqX - sqWidth / 2, sqY + sqHeight / 2, paint1);
        canvas.drawRect(sqX + sqWidth
                / 2, sqY - sqHeight / 2, _w, sqY + sqHeight / 2, paint1);
        canvas.drawRect(0, sqY + sqHeight / 2, _w, _h, paint1);
        
        canvas.drawRect(sqX - sqWidth / 2, sqY - sqHeight / 2, sqX + sqWidth
                / 2, sqY + sqHeight / 2, paint2);
        canvas.drawCircle(sqX, sqY - sqHeight / 2, 12, paint3);
        canvas.drawCircle(sqX, sqY + sqHeight / 2, 12, paint3);
        canvas.drawCircle(sqX - sqWidth / 2, sqY, 12, paint3);
        canvas.drawCircle(sqX + sqWidth / 2, sqY, 12, paint3);
    }

    String TouchMode = "NONE";
    float _distance = 0f;
    
    public boolean onTouchEvent(MotionEvent e) {
        switch (e.getAction()) {
        case MotionEvent.ACTION_DOWN:
            _x = e.getX();
            _y = e.getY();
            if (sqX - sqWidth / 2+20 < _x && sqX + sqWidth / 2-20 > _x) {
                // x的にいうと触れている
                if (sqY - sqHeight / 2+20 < _y && sqY + sqHeight / 2-20 > _y) {
                    // y的にいうと触れている
                    TouchMode = "MOVE";
                }else if(sqY - sqHeight / 2-20 < _y && sqY + sqHeight / 2+20 > _y){
                    _distance = culcDistance(sqX,sqY,(int)e.getX(),(int)e.getY());
                    TouchMode = "SCALE";
                }
            }else if(sqX - sqWidth / 2-20 < _x && sqX + sqWidth / 2+20 > _x){
                if(sqY - sqHeight / 2-20 < _y && sqY + sqHeight / 2+20 > _y){
                    _distance = culcDistance(sqX,sqY,(int)e.getX(),(int)e.getY());
                    Log.e("log",Float.toString(_distance));
                    TouchMode = "SCALE";
                }
            }
            

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

                sqX += disX;
                sqY += disY;

                
            }else if(TouchMode == "SCALE"){
                
                float _cdistance = culcDistance(sqX,sqY,(int)e.getX(),(int)e.getY());
                
                float _rate = _cdistance/_distance;
                _rate = (_rate < 1.05)? _rate: 1.05f;
                _rate = (_rate > 0.95)? _rate: 0.95f;
                sqWidth *= _rate;
                if(sqWidth > _w){
                    sqWidth = _w;
                }else if(sqWidth < 100){
                    sqWidth = 100;
                }
                sqHeight = sqWidth;
            }
            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;
            }
            _distance = culcDistance(sqX,sqY,(int)e.getX(),(int)e.getY());
            _x = e.getX();
            _y = e.getY();
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            TouchMode = "NONE";
            break;
        default:
            break;
        }
        return true;
    }
    
    private float culcDistance(int x1,int y1,int x2,int y2) {
        float x = x1 - x2;
        float y = y1 - y2;
        return FloatMath.sqrt(x * x + y * y);
    }


}

 

 

前後の記事

前の記事:

次の記事:

関連の記事

コメントの投稿

  • サイト内検索

新作アプリの紹介

関連サイトの紹介

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