As a example, the bitmap is retrieved from ImageView by calling ((BitmapDrawable)imageView.getDrawable()).getBitmap(), note that it's not always work, depends on how to load image to ImageVIew.
To save file to external storage, permission of "android.permission.WRITE_EXTERNAL_STORAGE" is needed in AndroidManifest.xml. Otherwise you cannot save the file, but no error reported.
In this example:
- The first button save the bitmap as file, with specified path. In this case, MediaStore may not know there are new image, such that may be you cannot view it in Android Gallery App or Photos App.
- The second button insert the bitmap to MediaStore by calling MediaStore.Images.Media.insertImage(ContentResolver cr, Bitmap source, String title, String description), to MediaStore path. Such that you can view it in Android Gallery App or Photos App.
- The third button save the bitmap as file, then insert the file to MediaStore by calling MediaStore.Images.Media.insertImage(ContentResolver cr, String imagePath, String name, String description). In this case, you save two files actually.
package com.example.androidsavebitmap;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.support.v7.app.ActionBarActivity;
import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
/*
* "android.permission.WRITE_EXTERNAL_STORAGE" is needed
* otherwise, cannot save but no error report
*/
public class MainActivity extends ActionBarActivity {
ImageView imageView;
Button btnSaveExternalStorageDirectory;
Button btnSaveMediaStore;
Button btnSaveFileAndMediaStore;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView)findViewById(R.id.image);
btnSaveExternalStorageDirectory = (Button)findViewById(R.id.saveExternalStorageDirectory);
btnSaveExternalStorageDirectory.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
/*
* Save bitmap to ExternalStorageDirectory
*/
//get bitmap from ImageVIew
//not always valid, depends on your drawable
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
//always save as
String fileName = "test.jpg";
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
File ExternalStorageDirectory = Environment.getExternalStorageDirectory();
File file = new File(ExternalStorageDirectory + File.separator + fileName);
FileOutputStream fileOutputStream = null;
try {
file.createNewFile();
fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(bytes.toByteArray());
Toast.makeText(MainActivity.this,
file.getAbsolutePath(),
Toast.LENGTH_LONG).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(fileOutputStream != null){
try {
fileOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}});
btnSaveMediaStore = (Button)findViewById(R.id.saveMediaStore);
btnSaveMediaStore.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
/*
* Save bitmap to MediaStore
*/
//get bitmap from ImageVIew
//not always valid, depends on your drawable
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
ContentResolver cr = getContentResolver();
String title = "myBitmap";
String description = "My bitmap created by Android-er";
String savedURL = MediaStore.Images.Media
.insertImage(cr, bitmap, title, description);
Toast.makeText(MainActivity.this,
savedURL,
Toast.LENGTH_LONG).show();
}});
btnSaveFileAndMediaStore = (Button)findViewById(R.id.saveExternalStorageDirectoryMediaStore);
btnSaveFileAndMediaStore.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
/*
* Save bitmap to ExternalStorageDirectory
*/
//get bitmap from ImageVIew
//not always valid, depends on your drawable
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
//always save as
String fileName = "test.jpg";
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
File ExternalStorageDirectory = Environment.getExternalStorageDirectory();
File file = new File(ExternalStorageDirectory + File.separator + fileName);
FileOutputStream fileOutputStream = null;
try {
file.createNewFile();
fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(bytes.toByteArray());
ContentResolver cr = getContentResolver();
String imagePath = file.getAbsolutePath();
String name = file.getName();
String description = "My bitmap created by Android-er";
String savedURL = MediaStore.Images.Media
.insertImage(cr, imagePath, name, description);
Toast.makeText(MainActivity.this,
savedURL,
Toast.LENGTH_LONG).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(fileOutputStream != null){
try {
fileOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}});
}
}
<LinearLayout 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"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.androidsavebitmap.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<Button
android:id="@+id/saveExternalStorageDirectory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Save to ExternalStorageDirectory" />
<Button
android:id="@+id/saveMediaStore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Save to MediaStore" />
<Button
android:id="@+id/saveExternalStorageDirectoryMediaStore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Save to ExternalStorageDirectory and insert to MediaStore" />
</LinearLayout>
Download the files.
more:
- Insert the bitmap to MediaStore with title and List images title in MediaStore
Hi Eric,
ReplyDeleteCould you tell me the exact purpose of title and description in insertImage? Neither pieces of text in " " seem to be saved as file info once the image is saved to your device - what is the point of these two Strings?
"ContentResolver contentResolver = getContentResolver();
String title = "title";
String description = "description";
MediaStore.Images.Media.insertImage(contentResolver, bitmap, title, description);"
Thanks!
Lara.
hello Lara,
ReplyDeleteIt's for MediaStore, refer http://developer.android.com/reference/android/provider/MediaStore.Images.Media.html#insertImage(android.content.ContentResolver, android.graphics.Bitmap, java.lang.String, java.lang.String)
Hi Eric,
ReplyDeleteI got that. :-).
I just can't find any other documentation about the usefulness of title and description - I was hoping you have might have some more knowledge on the subject.
Lara.
Hello Lara,
ReplyDeleteIn my understanding, they are some extra info stored in MediaStore, not file name, not ID. Actually I can't find any apps use the info.
Here is my modified example show how to store the title and list the titles in MediaStore. Insert bitmap to MediaStore with title and List images title in MediaStore.
Hi Eric,
ReplyDeleteGood to know regarding other apps, just wanted someone's else opinion.
And cheers for the second link!
You aren't on Twitter are you?
Lara.
Can some one explain me why third approach giving me out of memory exception.
ReplyDelete#Stack Trace#
at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:752)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:728)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:477)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:515)
at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:886)
at com.example.myappsampleimagegallery.MainActivity.click3(MainActivity.java:127)