素人のアンドロイドアプリ開発日記

トリミングのコンテンツ

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

2012.07.13

今回でトリミングは完成します。

ちょっとうまくできたので出すのが惜しいのですが(笑)

といいながらも、他のスーパーすごい人も結構、バスバスと情報を出してくれてるので、

というか使えるのか?これ?とか思いながらも出してみます。

最後にボタンを上にずらすのとかでサイズが少しおかしいような。そんな部分も適宜修正しております。

メインのクラスを画像のデータを用意して、activity間のbitmap受け渡しは静的インスタンスを利用します。

public class TipstarActivity extends Activity {

    private static int GETTRIM = 1;
    
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        
        Intent _intent = new Intent(getApplicationContext(),TrimingActivity.class);
        
        BitmapHolder._holdedBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.temple);
        startActivityForResult(_intent,GETTRIM);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == GETTRIM){
            if(resultCode == RESULT_OK){
                Toast.makeText(this, "画像の取得に成功しました。\nトリミングおめでとう", Toast.LENGTH_SHORT).show();
                BitmapHolder._holdedBitmap = null;
            }else{
                Toast.makeText(this, "画像の取得に失敗しました。", Toast.LENGTH_SHORT).show();
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}

上記では、まずビットマップを用意します。ここでのビットマップはどこから持ってきても大丈夫です。BitmapHolderは下記で作成する静的なbitmapを持ち運ぶエリアです。

で値が帰ってきた時には、bitmapを空にしてあげましょう。受け渡しの時に静的インスタンスを利用すると、メモリリークの原因になるので慎重に!

で、簡単にクラスは

public class BitmapHolder {
    public static Bitmap _holdedBitmap;
}

となんの変哲もないクラスです。

で、次にトリミングのクラスですが、縦幅と横幅に関しては、サイズ目一杯に広がってしまうと、画像のデータがないところまで移動できてしまうので、画像のデータに合わせて、トリミングのエリアの移動するように外部から設定をできるようにしておいます。

onSizeChanged→sizeSetの部分ですね。。

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(0xcc000000);
        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;
        */
    }
    
    public void sizeSet(int w, int h) {
        _w = w;
        _h = h;
        sqWidth = w - 40;
        sqHeight = w - 40;
        sqX = w / 2;
        sqY = h / 2;
    }
    
    public ArrayList<Integer> getTrimData(){
        ArrayList<Integer> _arl = new ArrayList<Integer>();
        _arl.add(sqX-sqWidth/2);
        _arl.add(sqY-sqHeight/2);
        _arl.add(sqWidth);
        _arl.add(sqHeight);
        
        return _arl;
    }

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


}

で、トリミング用のactivityでは

public class TrimingActivity extends Activity {
     @Override
        public void onCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            System.gc();
            _bmOriginal = BitmapHolder._holdedBitmap.copy(Bitmap.Config.ARGB_8888, true);
            BitmapHolder._holdedBitmap = null;
        }
        
        Bitmap _bmOriginal;
        
        @Override
        public void onWindowFocusChanged(boolean hasFocus) {
            
            final TrimView _tview = new TrimView(getApplicationContext());
            ((LinearLayout)findViewById(R.id.imgcontainer)).addView(_tview);
            int _width = ((FrameLayout)findViewById(R.id.fl1)).getWidth();
            int _height = ((FrameLayout)findViewById(R.id.fl1)).getHeight();
            
            //_bmOriginal = BitmapFactory.decodeResource(getResources(),R.drawable.temple);
            
            
            float _scaleW = (float) _width / (float) _bmOriginal.getWidth();
            float _scaleH = (float) _height / (float) _bmOriginal.getHeight();
            final float _scale = Math.min(_scaleW, _scaleH);
            Matrix matrix = new Matrix();
            matrix.postScale(_scale, _scale);
            
            Bitmap _bm = Bitmap.createBitmap(_bmOriginal, 0, 0, _bmOriginal.getWidth(),_bmOriginal.getHeight(), matrix, true);
            
            
            ((ImageView)findViewById(R.id.imageView1)).setImageBitmap(_bm);
            
            ((Button)findViewById(R.id.button1)).setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    ArrayList<Integer> _al = _tview.getTrimData();
                    
                    int _ix = (int)(_al.get(0)/_scale);
                    int _iy = (int)(_al.get(1)/_scale);
                    int _iwidth = (int)(_al.get(2)/_scale);
                    int _iheight = (int)(_al.get(3)/_scale);
                    
                    _ix = (_ix>0) ? _ix : 0;
                    _iy = (_iy>0) ? _iy : 0;
                    _iwidth = (_iwidth + _ix < _bmOriginal.getWidth()) ? _iwidth : _bmOriginal.getWidth() - _ix;
                    _iheight = (_iheight + _iy < _bmOriginal.getHeight()) ? _iheight : _bmOriginal.getHeight() - _iy;
                    BitmapHolder._holdedBitmap = Bitmap.createBitmap(_bmOriginal, _ix, _iy, _iwidth, _iheight, null, true);
                    setResult(RESULT_OK);
                    finish();
                    //((ImageView)findViewById(R.id.imageView1)).setImageBitmap(_bm);
                }
            });
            
            super.onWindowFocusChanged(hasFocus);
            _tview.sizeSet((int)(_bmOriginal.getWidth()*_scale),(int)(_bmOriginal.getHeight()*_scale));
        }
}

上記無理やりも入っています。。

 

で、上記で利用している、main.xmlは下記です

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/fl1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical" >

            <ImageView
                android:id="@+id/imageView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/imgcontaineron"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <LinearLayout
                android:id="@+id/imgcontainer"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:orientation="vertical" >
            </LinearLayout>
        </LinearLayout>
    </FrameLayout>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="とりみんぐー" />

</LinearLayout>

 

ですね。これで、実行すると画像のトリミングのアクティビティんび移動して、トリミングをすると成功。トリミングをしないで戻ると失敗とでます。

まぁ、面倒な作業が続いたのですが、多分、これの必要に迫られてない人はなんのこっちゃな話ですが、

一応、トリミングの実装でした。

おやくに立てればとおもいますー

カテゴリー:トリミング

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

2012.07.11

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

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

 

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

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

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


}

 

 

カテゴリー:トリミング

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

2012.07.11

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

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

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

}

 

 

カテゴリー:トリミング

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

2012.07.11

画像のトリミングを行いたいと思います。

結構探すと下記でトリミングができるのがわかります

Intent intent = new Intent("com.android.camera.action.CROP");
intent.setData(data.getData());// トリミングに渡す画像パス


intent.putExtra("outputX", 300);// トリミング後の画像の幅
intent.putExtra("outputY", 300);// トリミング後の画像の高さ

intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);

intent.putExtra("scale", true);// トリミング中の枠を拡大縮小させるか
intent.putExtra("return-data", true);// トリミングしたデータを返すよ
startActivityForResult(intent, REQUEST_CROP_PICK);

で終えたいのですが、画像のサイズですが、300*300だと、基本的には画像の300*300の画像のデータを取得できます。トリミングも基本的にデフォルトのトリミングのアクティビティを利用してくれるのですが、画像サイズを大きくすると、おかしい事が起こります。(端末の依存があるとおもいますが:galaxy sです)実行しても動かない or 切り取っても動作が重いと言う現象が起こります。galaxy sだと400*400~発生しました。

一定以上の画像のデータの受け渡しはメモリの問題上できないように制限されているみたいです。

 

基本的には、そのような情報はどこにも書いてないのですが。。。

ですが、よくよく見てみてみると、画像のアプリはほとんどが、トリミングをアプリ内部で行なっています。インスタグラムや、LINEカメラなどでも。

 

上記の引数の指定方法はかなり簡単にできるので、使いたいのですが、画像サイズを一定以上大きくしたい場合に、トリミングを自分で実装しなくてはいけないのかもしれません。

次回以降、大きな方向性と、実際の実装をすすめてみたいと思います。

 

カテゴリー:トリミング

公開中のアプリ、是非ダウンロードしてみてください

2chまとめのたね

RSSを利用してさまざまなブログの情報をキュレーションしてくれるアプリ

インストールする

ひらがな戦記

OPENGL ES2 を利用したカルタのソーシャルゲーム

インストールする