I know the insert method
MediaStore.Images.Media.insertImage(..............)
Insert a thumbnail instaed of the original Bitmap image,I need a way to save Bitmap with no compress to keep its pixels as they are (steganography), I need the image to be stored on gallery in internal storage.
The Gallery can contains folders for application on android, to get high resolution file there is need to store them outside the gallery and tell gallery about your file and your application folder and show your files as thumbnails,so I implement this method which perform what I need and I hope help others
private void SaveImage(Bitmap segg) {
OutputStream fOut = null;
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fileName = "Image-"+ n +".png";
final String appDirectoryName = "TBStego";
final File imageRoot = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), appDirectoryName);
imageRoot.mkdirs();
final File file = new File(imageRoot, fileName);
try {
fOut = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
segg.compress(Bitmap.CompressFormat.PNG, 100, fOut);
try {
Toast.makeText(ExtractActivity.this,
file.getAbsolutePath(),
Toast.LENGTH_LONG).show();
fOut.flush();
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE,"stego");
values.put(MediaStore.Images.Media.DESCRIPTION, "stego description");
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.ImageColumns.BUCKET_ID, file.toString().toLowerCase(Locale.US).hashCode());
values.put(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME, file.getName().toLowerCase(Locale.US));
values.put("_data", file.getAbsolutePath());
Toast.makeText(ExtractActivity.this,
file.getAbsolutePath(),
Toast.LENGTH_LONG).show();
ContentResolver cr = getContentResolver();
cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Toast.makeText(ExtractActivity.this, "The Image thumbnail created in Gallery ", Toast.LENGTH_LONG).show();
}
Related
when I save images, I want image to appear in the gallery, and not only inside the internal storage like apps wallpaper , facebook messenger
my code , On Click Button
holder.img_download.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
File dir = new File(Environment.getExternalStorageDirectory(), "/Wallpapers");
if(!dir.exists()) {
dir.mkdirs();
}
Bitmap bitmap = ((BitmapDrawable)holder.img_photo.getDrawable()).getBitmap();
saveImage(bitmap,dir);
}
});
funcation saveImage
private void saveImage(Bitmap finalBitmap,File dir) {
Random r = new Random();
String fname = "Image_" + r.nextInt(1000000) + ".jpg";
File file = new File(dir, fname);
if (file.exists()) file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
Toast toasty = Toasty.success(context,"Saved", Toast.LENGTH_LONG);
toasty.setGravity(Gravity.CENTER, 0, 0);
toasty.show();
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + dir)));
} catch (Exception e) {
e.printStackTrace();
}
}
I dont have any problem saving pictures but I want to show up in the gallery like image applications
Try this to add image in gallery:
public void addImageToGallery(final String filePath, final Context context) {
ContentValues contentValues = new ContentValues();
contentValues.put(Images.Media.DATE_TAKEN, System.currentTimeMillis());
contentValues.put(Images.Media.MIME_TYPE, "image/jpeg");
contentValues.put(MediaStore.MediaColumns.DATA, filePath);
context.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, contentValues);
}
instead of File dir = new File(Environment.getExternalStorageDirectory(), "/Wallpapers");
use
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
I have an app where the user creates an image and then I want to save it so it's visible form the default gallery application.
Now I don't want the pictures to be saved in the same folder as the pictures taken from the camera, I want them to be saved in a folder dedicated to the app, just like images from apps like whatsapp or facebook.
I've tried saving them in this two locations:
File imagePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)+ File.separator + appDirectoryName + File.separator);
and here
File imagePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+ File.separator + appDirectoryName + File.separator);
If I browse through the phone I see that I successfully save the images but they don't show in the gallery app. It is obvious that I'm missing something but I don't know what it is. Maybe adding some kind of metadata to the files or folders so the gallery recognizes them?
Well I found the answer in the end.
It turned out to be what I suspected. The saved image needs to have some metadata added in order to be seen in the gallery (at least in my device).
This is what I did:
OutputStream fOut = null;
File file = new File(imagePath,"GE_"+ System.currentTimeMillis() +".jpg");
try {
fOut = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
try {
fOut.flush();
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, this.getString(R.string.picture_title));
values.put(Images.Media.DESCRIPTION, this.getString(R.string.picture_description));
values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis ());
values.put(Images.ImageColumns.BUCKET_ID, file.toString().toLowerCase(Locale.US).hashCode());
values.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, file.getName().toLowerCase(Locale.US));
values.put("_data", file.getAbsolutePath());
ContentResolver cr = getContentResolver();
cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
I have had the same problem.
The second way is the correct way, but you don't see the images in the Gallery because the gallery needs to be refreshed.
So, you can wait a while until it refreshes itself, or you can use the MediaScanner -
look here
Hope this helped!
I did the following to get it to work:
public void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
String mCurrentPhotoPath = "file:" + image.getAbsolutePath(); // image is the created file image
File file = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
Try this
private void createDirectoryAndSaveFile(Bitmap imageToSave, String fileName) {
File direct = new File(Environment.getExternalStorageDirectory() + "/DirName");
if (!direct.exists()) {
File wallpaperDirectory = new File("/sdcard/DirName/");
wallpaperDirectory.mkdirs();
}
File file = new File(new File("/sdcard/DirName/"), fileName);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I tried this it works perfectly.
private Uri imageUri;
String getimgname, getimgpath;
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photo = new File(Environment.getExternalStorageDirectory(), "IMG"+System.currentTimeMillis()+".jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
getimgname = photo.getName();
getimgpath = photo.getAbsolutePath();
Try this
MediaScannerConnection.scanFile(context,
new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
I try to save the image into WathsappIMG but when I go to image gallery android I don't see the image and the image there into the directory can be seen from ES File Explorer
OutputStream output;
// Find the SD Card path
File filepath = Environment.getExternalStorageDirectory();
// Create a new folder in SD Card
File dir = new File(filepath.getAbsolutePath()
+ "/WhatSappIMG/");
dir.mkdirs();
// Retrieve the image from the res folder
BitmapDrawable drawable = (BitmapDrawable) principal.getDrawable();
Bitmap bitmap1 = drawable.getBitmap();
// Create a name for the saved image
File file = new File(dir, "Wallpaper.jpg" );
try {
output = new FileOutputStream(file);
// Compress into png format image from 0% - 100%
bitmap1.compress(Bitmap.CompressFormat.JPEG, 100, output);
output.flush();
output.close();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
the gallery don't displaying (necessarily) files from external storage.
this is a common mistake.
the gallery displays images stored on the media store provider
you can use this method to store image file on media store provider:
public static void addImageToGallery(final String filePath, final Context context) {
ContentValues values = new ContentValues();
values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA, filePath);
context.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
}
here is what you should enter, when you're about to save the picture in the Gallery
MediaStore.Images.Media.insertImage(getContentResolver(), yourBitmap, yourTitle , yourDescription);
That code will add the image at the end of the Gallery. so please, check your Gallery picture, to be sure
Try adding this:
MediaStore.Images.Media.insertImage(getContentResolver(), yourBitmap, yourTitle , yourDescription);
Fill in your details for yourBitmap, yourTitle, and yourDescription, or just leave it as "".
You need to add a MediaScannerConnection class to your function of saving the image to the gallery. This class scans for new files and folders in gallery connected with your app. Add the following class to scan the newly saved image files or new added image directory to the gallery or download Source Code
MediaScannerConnection.scanFile(this, new String[]{file.toString()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
Read more
For Xamarin fellows:
public static void SaveToTheGalley(this string filePath, Context context)
{
var values = new ContentValues();
values.Put(MediaStore.Images.Media.InterfaceConsts.DateTaken, Java.Lang.JavaSystem.CurrentTimeMillis());
values.Put(MediaStore.Images.Media.InterfaceConsts.MimeType, "image/jpeg");
values.Put(MediaStore.MediaColumns.Data, filePath);
context.ContentResolver.Insert(MediaStore.Images.Media.ExternalContentUri, values);
}
And don't forget about android.permission.WRITE_EXTERNAL_STORAGE permission.
As
MediaStore.MediaColumns.Data
and
MediaStore.Images.Media.insertImage
is deprecated now,
here is how I did it using bitmap
fun addImageToGallery(
fileName: String,
context: Context,
bitmap: Bitmap
) {
val values = ContentValues()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
}
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, fileName)
values.put(MediaStore.Images.ImageColumns.TITLE, fileName)
val uri: Uri? = context.contentResolver.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values
)
uri?.let {
context.contentResolver.openOutputStream(uri)?.let { stream ->
val oStream =
BufferedOutputStream(stream)
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, oStream)
oStream.close()
}
}
}
You should change this piece of code-
try {
output = new FileOutputStream(file);
// Compress into png format image from 0% - 100%
bitmap1.compress(Bitmap.CompressFormat.JPEG, 100, output);
output.flush();
output.close();
String url = Images.Media.insertImage(getContentResolver(), bitmap1,
"Wallpaper.jpg", null);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Kindly refer this code worked for me:
public static boolean saveImageToGallery(Context context, Bitmap bmp) {
// First save the picture
String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "dearxy";
File appDir = new File(storePath);
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
//Compress and save pictures by io stream
boolean isSuccess = bmp.compress(Bitmap.CompressFormat.JPEG, 60, fos);
fos.flush();
fos.close();
//Insert files into the system Gallery
//MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null);
//Update the database by sending broadcast notifications after saving pictures
Uri uri = Uri.fromFile(file);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
if (isSuccess) {
return true;
} else {
return false;
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
Use the following code to make your image visible in the gallery.
public void saveImageToGallery(Context context, Uri path) {
// Create image from the Uri for storing it in the preferred location
Bitmap bmp = null;
ContentResolver contentResolver = getContentResolver();
try {
if(Build.VERSION.SDK_INT < 28) {
bmp = MediaStore.Images.Media.getBitmap(contentResolver, path);
} else {
ImageDecoder.Source source = ImageDecoder.createSource(contentResolver, path);
bmp = ImageDecoder.decodeBitmap(source);
}
} catch (Exception e) {
e.printStackTrace();
}
// Store image to internal storage/ImagePicker directory
String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "ImagePicker";
File appDir = new File(storePath);
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
boolean isSuccess = bmp.compress(Bitmap.CompressFormat.JPEG, 60, fos);
fos.flush();
fos.close();
// Broadcast the image & make it visible in the gallery
Uri uri = Uri.fromFile(file);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
if (isSuccess) {
Toast.makeText(context, "File saved to gallery", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Failed to save", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
}
I am working on a drawing part, and have written the following code to save the image to the designated camera folder. However, I would rather like to create a new folder using the app name and save the image to the folder. How could that be made?
I would also like to later on retrieve the image files from that specific folder too.
Thanks!
Current code:
String fileName = "ABC";
// create a ContentValues and configure new image's data
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, fileName);
values.put(Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(Images.Media.MIME_TYPE, "image/jpg");
// get a Uri for the location to save the file
Uri uri = getContext().getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
try
{
OutputStream outStream = getContext().getContentResolver().openOutputStream(uri);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush(); // empty the buffer
outStream.close(); // close the stream
Try this it might help you.
public void saveImageToExternalStorage(Bitmap image) {
String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/directoryName";
try
{
File dir = new File(fullPath);
if (!dir.exists()) {
dir.mkdirs();
}
OutputStream fOut = null;
File file = new File(fullPath, "image.png");
if(file.exists())
file.delete();
file.createNewFile();
fOut = new FileOutputStream(file);
// 100 means no compression, the lower you go, the stronger the compression
image.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
}
catch (Exception e)
{
Log.e("saveToExternalStorage()", e.getMessage());
}
}
This Method works after so many try.
private String getFilename() {
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);
if(!file.exists()){
file.mkdirs();
}
return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".mp3");
}
I'm saving an image onto sd card using the following code:
ContentValues values = new ContentValues();
values.put(MediaColumns.TITLE, mFileName);
values.put(MediaColumns.DATE_ADDED, System.currentTimeMillis());
values.put(MediaColumns.MIME_TYPE, "image/jpeg");
resultImageUri = ApplyEffects.this.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
try{
OutputStream out = ApplyEffects.this.getContentResolver().openOutputStream(resultImageUri);
mResultBitmaps[positionSelected].compress(Bitmap.CompressFormat.JPEG, 70, out);
out.flush();
out.close();
} catch(FileNotFoundException e){
e.printStackTrace();
} catch(Exception e){
e.printStackTrace();
}
But the image file name is always the System.currentTimeMills. How do I specify a name for it?
Here's my complete working code based on dipu's suggestion:
private Uri saveToFileAndUri() throws Exception{
long currentTime = System.currentTimeMillis();
String fileName = "MY_APP_" + currentTime+".jpg";
File extBaseDir = Environment.getExternalStorageDirectory();
File file = new File(extBaseDir.getAbsoluteFile()+"/MY_DIRECTORY");
if(!file.exists()){
if(!file.mkdirs()){
throw new Exception("Could not create directories, "+file.getAbsolutePath());
}
}
String filePath = file.getAbsolutePath()+"/"+fileName;
FileOutputStream out = new FileOutputStream(filePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, JPEG_QUALITY, out); //control the jpeg quality
out.flush();
out.close();
long size = new File(filePath).length();
ContentValues values = new ContentValues(6);
values.put(Images.Media.TITLE, fileName);
// That filename is what will be handed to Gmail when a user shares a
// photo. Gmail gets the name of the picture attachment from the
// "DISPLAY_NAME" field.
values.put(Images.Media.DISPLAY_NAME, fileName);
values.put(Images.Media.DATE_ADDED, currentTime);
values.put(Images.Media.MIME_TYPE, "image/jpeg");
values.put(Images.Media.ORIENTATION, 0);
values.put(Images.Media.DATA, filePath);
values.put(Images.Media.SIZE, size);
return ThisActivity.this.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
}
Try the following approach.
String fileName = "my_file.jpg";
File extBaseDir = Environment.getExternalStorageDirectory();
File file = new File(extBaseDir.getAbsoluteFile() + "APP_NAME");
if(!file.exists()){
if(!file.mkdirs()){
throw new Exception("Could not create directories, "+file.getAbsolutePath());
}
}
String filePath = file.getAbsolutePath()+"/"+fileName;
FileOutputStream out = new FileOutputStream(filePath);
//now write your bytes into this outputstream.