今回でトリミングは完成します。
ちょっとうまくできたので出すのが惜しいのですが(笑)
といいながらも、他のスーパーすごい人も結構、バスバスと情報を出してくれてるので、
というか使えるのか?これ?とか思いながらも出してみます。
最後にボタンを上にずらすのとかでサイズが少しおかしいような。そんな部分も適宜修正しております。
メインのクラスを画像のデータを用意して、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>
ですね。これで、実行すると画像のトリミングのアクティビティんび移動して、トリミングをすると成功。トリミングをしないで戻ると失敗とでます。
まぁ、面倒な作業が続いたのですが、多分、これの必要に迫られてない人はなんのこっちゃな話ですが、
一応、トリミングの実装でした。
おやくに立てればとおもいますー