2010年12月27日月曜日

OS標準のクリッピングを呼び出す方法

Androidで壁紙なんかを設定しようとすると、サイズが大きい場合にクリッピングのインテントへ画像を飛ばしてくれる。
似たようなものを自力で作ってみたんだけど、もとからあるならそれを使わせてもらいたいもんです。

というわけで、「OS標準のクリッピングを呼び出す方法」を調べてみましたが、中々有益な情報に出会わない。
ちゅーか、画像のセレクタからクリッピングへの流れを組むのは

  1. Intent intent = new Intent(Intent.ACTION_GET_CONTENT);  
  2. intent.setType("image/*");  
  3. intent.putExtra("crop""true");  
  4. startActivityForResult(intent, 0);  

てなのが出てくるんだけど。

違うんだよ。 今既にこっちでもっているBMPをクリッピングして返して欲しいんだよ!

ってなると、急激に情報がなくなっていきます。 少なくとも日本語圏ではまともなのがない(探し方が悪いだけって話もある)

なので、実際にクリッピング画面をカメラなり壁紙設定から実行して、DDMSのログを見てどのIntentが呼び出されているのかを調べてみました。

すると、
  1. INFO/ActivityManager(1381): Displayed activity com.android.camera/.CropImage: 863 ms (total 863 ms)  

まぁ、863msは置いといて。
com.android.cameraパッケージのCropImageが呼び出されているようです。

ちゅーことは。
  1. Intent intent = new Intent();  
  2. intent.setClassName("com.android.camera""com.android.camera.CropImage");  

でウッドボール!!


と、思ったら大間違い。 OS2.1以上だと起動しない!!!

なんと、このクリッピングのインテントはOSによって違う模様。 な・なんだってー!

僕はIS01で開発してたので、エミュレータでOS2.1にしてみると

  1. INFO/ActivityManager(72): Displayed activity com.android.gallery/com.android.camera.CropImage: 1289 ms (total 1472 ms)  

うお。 パッケージ名が "com.android.gallery"になってる・・・。

つーか、パッケージが"com.android.gallery"でクラス名が"com.android.camera.CropImage"ってどういことなんだ。

ともかく、
  1. Intent intent = new Intent();  
  2. intent.setClassName("com.android.gallery""com.android.camera.CropImage");  

にしてあげたら、OS2.1以上では起動しました。

・・・えぇ、1.6で起動しなくなりましたよ。当たり前ですけど。

なーぬーーーー。

ちゅーわけで、もう一手間。

android.os.Build でSDKのVerがわかるようなので、

  1. final int sdkInt = Integer.parseInt(Build.VERSION.SDK);  

で、sdkのVerを取得。 このsdkIntがAPIレベルになるようで。 すると、1.6は4。 2.2なら8です。

それら踏まえて
  1. Intent intent = new Intent();  
  2.   final int sdkInt = Integer.parseInt(Build.VERSION.SDK);  
  3.   if(sdkInt <= 4){ //OS1.6  
  4.    intent.setClassName("com.android.camera""com.android.camera.CropImage");  
  5.   }else//OS2.1  
  6.    intent.setClassName("com.android.gallery""com.android.camera.CropImage");  
  7.   }    
という感じ。 ふーはー。 とと、本題を忘れていた。 これらインテントにこっちからBMPを渡すんでした。 これもいろいろあるみたいなんですが、Intentで渡せるデータ容量の関係もあって、一度テンポラリとして保存をして、その保存ファイルのUriを渡すものみたいです。 なので僕のソースコードはこんな感じ。
  1. intent.setData(Uri.parse("file://" + url));  
  2.   intent.putExtra("crop""true");  
  3.   intent.putExtra("outputX", dw);  
  4.   intent.putExtra("outputY", dh);  
  5.   intent.putExtra("aspectX", dw);  
  6.   intent.putExtra("aspectY", dh);  
  7.   intent.putExtra("scale"true);  
  8.   intent.putExtra("noFaceDetection"true);  
  9.   intent.putExtra("return-data""true");  
  10.   intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + url));  
  11.   startActivityForResult(intent, INTENT_CALL_CROP);  
urlが渡すBMPを保存したパスだと思いねぇ。 その際に、Intent.EXTRA_STREAMで指定した場所にクリッピングしたデータを書きこんでくれるみたいなので、僕は渡した画像ファイルのパスをそのまま指定してます。 ところで、
  1. intent.putExtra("return-data""true");  
ってー指定があってね。 これによってリザルトが戻ってくるんだかなんだか・・・。 でも、ウェブではどう調べても
  1. intent.putExtra("return-data"true);  
って書いてあるんだよね。 本当かね。 ウチの環境ではここでtrueぶち込んでもリザルト返ってこないんだけど。

教えてエライヒト。 それでは、また。ノシシ

0 件のコメント:

コメントを投稿