画像を SDカードに保存する

Androidアプリでビットマップ画像を SDカードに保存するサンプルを作成しました。

下記よりサンプルをダウンロードできます。

サンプルダウンロード

導入手順

1. パーミッションの追加

AndroidManifest.xml にメディアストレージへのアクセスを許可する権限を追加します。

1
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2. ImageManager クラスの組み込み

画像の保存などを行うクラス ImageManager.java を「/app/src/main/java/net/dolice/image/」ディレクトリに配置します。

3. 保存対象のビットマップ画像を取得

保存したい画像をビットマップ形式で取得します。下記の例では、イメージビューからビットマップを取得しています。

1
2
3
// イメージビューからビットマップを取得
ImageView sampleImageView = (ImageView)findViewById(R.id.image);
Bitmap sampleImage = ((BitmapDrawable)sampleImageView.getDrawable()).getBitmap();

4. 画像の保存を実行

ボタンのタップイベント等から ImageManager クラスを呼び出し、画像の保存を実行します。

1
2
3
4
5
6
7
8
// ビットマップを SDカードに保存
ImageManager imageManager = new ImageManager(this);
try {
    String albumName = "Save image sample";
    imageManager.save(sampleImage, albumName);
} catch (Error e) {
    Log.e("MainActivity", "onCreate: " + e);
}

下記に実装サンプルを記載します。

サンプルでは、画像の上に敷いてある透明なボタンをタップで、フォトアルバムを作成し画像を保存しています。

SDカードが必要であるのと、フォトアルバムへの反映のため ContentResolver を介してギャラリーに追加する必要がある点にご注意ください。

サンプルソースコード

activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/sample_image" />

    <Button
        android:id="@+id/button"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@null" />

</RelativeLayout>

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package net.dolice.saveimageex;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import net.dolice.image.ImageManager;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 画像保存ボタン定義
        Button sampleButton = (Button)findViewById(R.id.button);
        sampleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 画像保存
                saveImage();
            }
        });
    }

    // 画像保存
    private void saveImage() {
        // イメージビューからビットマップ保持
        ImageView sampleImageView = (ImageView)findViewById(R.id.image);
        Bitmap sampleImage = ((BitmapDrawable)sampleImageView.getDrawable()).getBitmap();

        // ビットマップを SDカードに保存
        ImageManager imageManager = new ImageManager(this);
        try {
            // 画像の保存実行
            String albumName = "Save image sample";
            imageManager.save(sampleImage, albumName);
        } catch (Error e) {
            Log.e("MainActivity", "onCreate: " + e);

            // 画像の保存失敗メッセージ表示
            Toast.makeText(MainActivity.this, "SDカードに保存できませんでした", Toast.LENGTH_SHORT).show();
        } finally {
            // 画像の保存完了メッセージ表示
            Toast.makeText(MainActivity.this, "SDカードに保存しました", Toast.LENGTH_SHORT).show();
        }
    }
}

ImageManager.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package net.dolice.image;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * Created by Dolice on 15/02/28.
 */

public class ImageManager {
    private Context mContext;
    private String fileFullPath;

    public ImageManager(Context context) {
        mContext = context;
    }

    /**
     * 画像の保存
     * @param bitmap
     * @param albumName
     */
    public void save(Bitmap bitmap, String albumName) {
        if (!canUseSd()) {
            Log.e("Error", "Can't use SD Card");

            return;
        }

        saveToSd(getSdStorageDir(albumName), bitmap);
    }

    /**
     * SDカードに画像保存
     * @param dir
     * @param bitmap
     */
    private void saveToSd(File dir, Bitmap bitmap) {
        String fileName = getFileName();
        fileFullPath = dir.getAbsolutePath() + "/" + fileName;
        try {
            // 保存処理
            FileOutputStream fos = new FileOutputStream(fileFullPath);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (Exception e) {
            Log.e("Error", "" + e.toString());
        } finally {
            // アルバムに反映
            addGallery(fileName);
        }
    }

    /**
     * 保存した画像をギャラリーに追加
     * @param fileName
     */
    private void addGallery(String fileName) {
        try {
            ContentValues values = new ContentValues();
            ContentResolver contentResolver = mContext.getContentResolver();
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
            values.put(MediaStore.Images.Media.TITLE, fileName);
            values.put("_data", fileFullPath);
            contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        } catch (Exception e) {
            Log.e("Error", "" + e);
        }
    }

    /**
     * 画像のファイル名を日付から生成し取得
     * @return
     */
    private String getFileName() {
        Date mDate = new Date();
        SimpleDateFormat fileNameFormat = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH);
        String fileName = fileNameFormat.format(mDate) + ".jpg";

        return fileName;
    }

    /**
     * SDカードのストレージパス取得
     * @param albumName
     * @return
     */
    private File getSdStorageDir(String albumName) {
        File dir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), albumName);

        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                Log.e("Error", "Directory not created");
            }
        }

        return dir;
    }

    /**
     * SDカードが読み込み可能か
     * @return
     */
    public boolean canReadSd() {
        String status = Environment.getExternalStorageState();
        if (!status.equals(Environment.MEDIA_MOUNTED)) {
            return false;
        }

        File file = Environment.getExternalStorageDirectory();
        if (file.canRead()){
            return true;
        }

        return false;
    }

    /**
     * SDカードに書き込み可能か
     * @return
     */
    public boolean canWriteSd() {
        String status = Environment.getExternalStorageState();
        if (!status.equals(Environment.MEDIA_MOUNTED)) {
            return false;
        }

        File file = Environment.getExternalStorageDirectory();
        if (file.canWrite()){
            return true;
        }

        return false;
    }

    /**
     * SDカードが使用可能か
     * @return
     */
    public boolean canUseSd() {
        return canReadSd() && canWriteSd();
    }
}
   このエントリーをはてなブックマークに追加

About

Masaki Hirokawa (@dolice_apps)

デザインエンジニア 廣川政樹の開発ブログ。Objective-Cや Javaなど iPhone/Androidアプリ開発に関する技術情報を掲載しています。

iPhone apps

  • リラックス・ヒーリング(無料)
  • 望みが叶う!引き寄せの法則アプリ(無料)
  • ミステリー - 怖い話や不思議な体験、都市伝説まとめ
  • 浮世絵壁紙 - 美しい日本画ギャラリー(無料)
  • アート壁紙HD(無料)
  • 綺麗な壁紙HD iPhone 7/7 Plus/SE & iPod対応(無料)
  • クールな壁紙HD iPhone 7/7 Plus/SE & iPod対応(無料)

Android apps

  • 浮世絵壁紙 - 美しい日本画ギャラリー
  • 綺麗な高画質壁紙

Objective-C Classes

Tag Cloud

ActionScript(9) ActionScript3(7) Ad(4) Adfurikun(2) AdMob(9) Android(10) Animation(17) AppDelegate(3) ARC(1) ArrayList(1) AVAudioPlayer(4) AVAudioSession(1) AVFoundation(3) Banner(2) Bitmap(1) Camera(4) CGAffineTransform(4) CGBlendMode(2) CGContextRef(1) CGImageRef(1) Classes(44) CLLocationManager(1) ConnectivityManager(1) ContentResolver(1) CoreLocation(2) Delegate(3) Device(7) Display(1) DisplayMetrics(1) Download(101) Facebook(6) Foundation(72) Framework(2) Google Analytics(1) Handler(1) iAd(6) ImageView(1) In-AppPurchase(1) iOS(12) iOS 7(15) iOS 7.1(3) iOS 8(1) iPad(7) iPhone(21) iPhone 6(4) Java(7) JavaScript(2) LINE(4) Localize(1) Magazine(1) MediaStore(1) MFComposeViewController(1) Nend(1) NetworkInfo(1) NSArray(23) NSCalendar(3) NSData(2) NSDate(7) NSDateComponents(2) NSDateFormatter(2) NSDictionary(12) NSEnumerator(1) NSIndexSet(1) NSInteger(6) NSMutableArray(17) NSMutableDictionary(5) NSMutableOrderedSet(7) NSMutableString(4) NSMutableURLRequest(1) NSNotificationCenter(1) NSNumber(1) NSObject(1) NSOrderedSet(7) NSRange(2) NSSelectorFromString(1) NSSet(6) NSString(19) NSTimer(4) NSTimeZone(1) NSURL(7) NSURLConnection(1) NSURLRequest(2) NSUserDefaults(7) NSXMLParser(2) Objective-C(222) PHP(1) Products(14) QuartzCore(3) RSS(2) Runnable(1) Sample(51) Screensaver(9) SDK(2) ShareCompat(1) Social(10) StoreKit(1) Twitter(6) UIAccelerometer(3) UIActionSheet(1) UIActivityIndicator(1) UIActivityIndicatorView(3) UIActivityViewController(1) UIAlertView(5) UIApplication(7) UIButton(4) UIColor(3) UIDatePicker(5) UIDevice(6) UIDeviceOrientation(1) UIEvent(6) UIImage(15) UIImagePickerController(4) UIImageView(12) UIKit(58) UILabel(7) UINavigationBar(4) UINavigationItem(1) UIPasteboard(4) UIScreen(1) UIScrollBar(1) UIScrollView(1) UISlider(3) UIStoryboardSegue(3) UISwitch(1) UITabBar(3) UITableView(4) UITextField(2) UIView(11) UIViewAnimationTransition(1) UIViewController(4) UIWebView(5) WindowManager(1) Xcode(48) Xcode 5(8) Xcode 5.1(2)