Androidの画像保存をやってみた

            Androidで画像を端末に保存したときにやったこととはまったこと。

String型で『data:image/jpeg;base64,・・・』という生データを端末のギャラリーで見えるようにするまで。

保存場所を決める

/sdcard/ やら /mnt/sdcard/ 以下に保存するらしい。 例えば、/mnt/sdcard/MyApp/20120130210000.jpg みたいな感じ。 [java] File dir; if (this.readySdcard()) { // 1 dir = new File(this.getDirPath()); if (!dir.exists()) { // 2 if (!dir.mkdirs()) return new PluginResult(Status.ERROR, "Failed Create Dir"); } } else { dir = this.ctx.getFilesDir(); // 3 }

File path = new File(this.getFilePath(dir)); // 4

private boolean readySdcard() { String status = Environment.getExternalStorageState(); return status.equals(Environment.MEDIA_MOUNTED); }

private String getDirPath() { return Environment.getExternalStorageDirectory().getPath()+"/MyApp/"; }

private String getFilePath(File dir) { Date d = new Date();

String path = dir.getAbsolutePath() + "/"; path += String.format("%4d%02d%02d%02d%02d%02d.jpg", (1900+d.getYear()), (d.getMonth()+1), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds());

return path; } [/java]

  1. SDカードがマウントされていれば、画像を保存するディレクトリを取得します。
  2. ディレクトリがまだなければ作ります。
  3. もし、SDカードがマウントされていなければ使用できるディレクトリを探します。
  4. ディレクトリが決まったら、ディレクトリのパス情報を元にファイル名を足して保存場所を決定します。

また、SDカードへの書き込みにはマニフェストで許可してあげる必要があります。 AndroidManifest.xmlに追記します。 [xml] <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> [/xml]

画像データを書き込み可能なフォーマットに変換する

Androidの画像保存では、画像データをBitmapオブジェクトに変換する必要があります。 [java] Bitmap bmp = this.convertBitmapFromJpeg(data); // data = (String)"data:image/jpeg;base64,・・・"

private Bitmap convertBitmapFromJpeg(String data) { data = data.replaceFirst("data:image/jpeg;base64,", ""); // 1 byte[] bytes = Base64.decode(data, Base64.DEFAULT); // 2 return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); // 3 } [/java]

  1. データの先頭についている『data:image/jpeg;base64,』を取ります。
  2. Base64でデコードします。
  3. Bitmapオブジェクトに変換します。

Base64はAndroidSDKに入ってるのでそれを使います。 ここで、1と2をしなければいけないことに気づかず結構はまりました。 参考. http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=46376&forum=12

保存する

ここまでできればあとは保存するだけです。 ただし、Androidは画像を保存しただけではギャラリーでみれないらしく、別途ギャラリーへの登録処理が必要です。 [java] try { this.saveImage(path, bmp); try { this.addGarally(path); System.out.println("画像の保存に成功"); } catch (Exception e) { System.out.println("画像の保存に失敗 : " + e.getMessage()); } } catch (Exception e) { System.out.println("画像の保存に失敗 : " + e.getMessage()); }

private void saveImage(File path, Bitmap bmp) throws Exception { FileOutputStream out = null;

try { out = new FileOutputStream(path); bmp.compress(CompressFormat.JPEG, 100, out); out.flush(); } catch (Exception e) { throw e; } finally { if (out != null) { try { out.close(); } catch (IOException e) {} } } }

private void addGarally(File path) throws Exception { try { ContentValues values = new ContentValues(); ContentResolver contentResolver = this.ctx.getContentResolver(); values.put(Images.Media.MIME_TYPE, "image/jpeg"); values.put(Images.Media.DATE_MODIFIED,System.currentTimeMillis() / 1000); values.put(Images.Media.SIZE, path.length()); values.put(Images.Media.TITLE, path.getName()); values.put(Images.Media.DATA, path.getPath()); contentResolver.insert(Media.EXTERNAL_CONTENT_URI, values); } catch (Exception e) { throw e; } } [/java]

これで端末に画像を保存して、見れるようになります。

参考. http://goo.gl/yiE6m http://dividebyzero-ksz.blogspot.com/2010/11/sd.html

エラーハンドリングがお粗末なのはすいません。

おわり。