Android: Saving an image to directory - android

I'm trying to save a bitmap to my directory but haven't a little trouble.
What my applications does is:
1.Opens the inbuilt camera application by an Intent.
public void openCamera() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory()+ File.separator + "image.jpg");
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
2.It then stores the picture intent into 'REQUEST_IMAGE_CAPTURE' and saves the image into a temp directory.
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
3.Which is then converted into a bitmap and loaded from the tmp directory into an image view
protected void onActivityResult(int requestCode, int resultCode, Intent data){
//Check that request code matches ours:
if (requestCode == REQUEST_IMAGE_CAPTURE){
//Get our saved file into a bitmap object:
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image.jpg");
Bitmap image = decodeSampledBitmapFromFile(file.getAbsolutePath(), 1000, 700);
imageView.setImageBitmap(image);
}
}
Now, how do i save the bitmap which in the imageview into the picture directory?
I have inputted the permissions into my manifest
<uses-feature android:name="android.hardware.camera"
android:required="true" />
...
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
...
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

use bitmap.compress in order to direct the bitmap into an OutputStream.
for example:
FileOutputStream fo = new FileOutputStream(filename);
bmp.compress(Bitmap.CompressFormat.PNG, 100, fo); // bmp is your Bitmap

private void saveImage(Bitmap bmp, String filePath){
File file = new File(filePath);
FileOutputStream fo = null;
try {
boolean result = file.createNewFile(); // true if created, false if exists or failed
fo = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, IMAGE_QUALITY_PERCENT, fo);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fo != null) {
try {
fo.flush();
fo.close();
} catch (Exception ignored) {
}
}
}
}
Note that filePath is directory + filename e.g. /sdcard/iamges/1.jpg

Related

How to get actual path of image from Uri in Android Q?

I'm taking picture using camera and selecting from gallery. After that doing compression to reduce file size. I was using getRealPathFromURI() method to get actual image path, but in Android QMediaStore.Images.Media.DATA is deprecated.
fun getRealPathFromURI(contentUri: Uri, activityContext: Activity): String {
val proj = arrayOf(MediaStore.Images.Media.DATA)
val cursor = activityContext.managedQuery(contentUri, proj, null, null, null)
val column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor.moveToFirst()
return cursor.getString(column_index)
}
As per documentation I tried openFileDescriptor() to gain access:
private fun getBitmapFromUri(context: Context, uri: Uri): Bitmap {
val parcelFileDescriptor = context.contentResolver.openFileDescriptor(uri, "rw")
val fileDescriptor = parcelFileDescriptor?.fileDescriptor
val image = BitmapFactory.decodeFileDescriptor(fileDescriptor)
parcelFileDescriptor?.close()
return image
}
also tried this
Due to Scoped Storage, we can’t write the image directly to the desired folder and then update the MediaStore . Instead, Android Q introduces a new field MediaStore.Images.Media.RELATIVE_PATH in which we can specify the path of the image (for example, "Pictures/Screenshots/").
Please refer "Saving a photo to the gallery" section of this blog for more information.
for loading image from gallery you can use it and you have the create provide in manifest
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"></meta-data>
</provider>
create your #xml/provide_paths like this
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images"
path="Android/data/package_name/files/Pictures" /> //pictures is the folder where your image will store
</paths>
code:
if (resultCode == Activity.RESULT_OK) { //onActivity you will get the result like this way
if (data != null) {
Uri contentURI = data.getData();
String path = null;
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),contentURI);
path = saveImage(bitmap);
// decodeImage(path);
img.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
mCurrentPhotoPath = path;
}
}
public void activeGallery() {// for taking the picture from gallery
Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent,RESULT_LOAD_IMAGE);
}
and for capture image in on Activity use
Bundle bundle=data.getExtras(); //
Bitmap bitmap= (Bitmap) bundle.get("data");
img.setImageBitmap(bitmap);
saveImage(bitmap);
public String saveImage(Bitmap myBitmap) { //this method will compress your image
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
myBitmap.compress(JPEG, 90, bytes);
File wallpaperDirectory = new File(Environment.getExternalStorageDirectory() , ""+IMAGE_DIRECTORY);
// have the object build the directory structure, if needed.
if (!wallpaperDirectory.exists()) {
wallpaperDirectory.mkdirs();
}
try {
File f = new File(wallpaperDirectory, Calendar.getInstance()
.getTimeInMillis() + ".jpg");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
// FileOutputStream fos = new FileOutputStream(f);
myBitmap.compress(JPEG, 90, fo);
fo.write(bytes.toByteArray());
MediaScannerConnection.scanFile(this,
new String[]{f.getPath()},
new String[]{"image/jpeg"}, null);
fo.close();
Log.d("TAG", "File Saved::--->" + f.getAbsolutePath());
return f.getAbsolutePath();
} catch (IOException e1) {
e1.printStackTrace();
}
return "";
}
public void activeTakePhoto() {// it will go on camera intent
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getApplicationContext().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}

How to create folder in internal storage and save captured image

I want to capture image and save it to specific folder in internal storage. Currently i am able to open intent and get thumbnail of captured image. I dont want to user extrnal stotage as now mostly users use their internal storage and not sd card.
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null){
startActivityForResult(intent,1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK){
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
LayoutInflater inflater = LayoutInflater.from(LeaveApplicationCreate.this);
final View view = inflater.inflate(R.layout.item_image,attachView, false);
ImageView img = view.findViewById(R.id.img);
AppCompatImageView btnRemove = view.findViewById(R.id.btnRemove);
img.setImageBitmap(imageBitmap);
btnRemove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
attachView.removeView(view);
}
});
attachView.addView(view);
File directory = new File(Environment.getExternalStorageDirectory(),"/Digimkey/Camera/");
if (!directory.exists()) {
directory.mkdir();
}
File file = new File(directory, System.currentTimeMillis()+".jpg");
try (FileOutputStream out =new FileOutputStream(file)) {
imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (IOException e) {
e.printStackTrace();
}
}
}
First gain Write Permissions.
File directory = new File(Environment.getExternalStorageDirectory(), dirName);
if (!directory.exists()) {
directory.mkdirs();
}
File file = new File(directory, fileName);
if (!file.exists()) {
file.createNewFile();
}
try (FileOutputStream out =new FileOutputStream(file)) {
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (IOException e) {
e.printStackTrace();
}
There are two types of storage.
1) Internal ex. "/root/.."
Unless you have rooted device, we can't access. this path.
2) External ex. "/storage/emuated/0"
Environment.getExternalStorageDirectory()
By using this path, we are able to create a directory/file.
Use to method to save your bimap in local storage. Pass bimap image as parameter i.e saveToInternalStorage(imageBitmap)
private String saveToInternalStorage(Bitmap bitmapImage){
//set image saved path
File storageDir = new File(Environment.getExternalStorageDirectory()
+ "MyApp"+ "/Files");
if (!storageDir.exists()) {
storageDir.mkdirs();
}
File mypath=new File(storageDir,"bitmap_image.jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return directory.getAbsolutePath();
}
Required permissions in Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Android - How to store and retrieve the image from internal storage

I want to take image from camera and store it and view it from internal storage.
I use this code to take image from camera.
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, TAKE_PIC);
I tried the following to save the bitmap in internal storage.
public String saveToInternalSorage(Bitmap bitmapImage, String fileName){
File file = new File(createBasePath(), fileName + ".png");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return file.getName();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PIC && resultCode == RESULT_OK) {
Intent i=new Intent(Intent.ACTION_VIEW);
i.setDataAndType(Uri.fromFile(output), "image/png");
startActivity(i);
}
}
My path is /data/user/0/com.dev/app/1454351400000/33352/capture_Image1.png
But here I am facing one issue. The bit map size is very small. I want exact image what I taken from camera.
Then I found one solution. Set the path before intent. So I tried like this.
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
output = new File(createBasePath(), "capture_Image1" + ".png");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(output));
startActivityForResult(intent, TAKE_PIC);
When I use this code the image is not showing. on onActivityResult the resultCode showing -1.
If I use the following code
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File dir= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
output=new File(dir, "CameraContentDemo.png");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(output));
startActivityForResult(intent, TAKE_PIC);
This code is working fine. After taking the image it showing image.
So please let me know store and retrieve the image from internal db with original quality.
Below is code to save the image to internal directory.
private String saveToInternalStorage(Bitmap bitmapImage){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
// Now Create imageDir
File mypath=new File(directory,"abc.jpg");
FileOutputStream foss = null;
try {
foss = new FileOutputStream(mypath);
// Using compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, foss);
} catch (Exception e) {
e.printStackTrace();
} finally {
foss.close();
}
return directory.getAbsolutePath();
}
Use below code for Reading a file from internal storage
private void loadImageFromStorage(String path)
{
try {
File f=new File(path, "abc.jpg");
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
ImageView img=(ImageView)findViewById(R.id.imgPicker);
img.setImageBitmap(b);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
void openMultiSelectGallery() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri =getOutputMediaFile();
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
/* start activity for result pass intent as argument and request code */
startActivityForResult(intent, CAMERA_REQUEEST_CODE);
}
/**
* This method set the path for the captured image from camera for updating
* the profile pic
*/
private Uri getOutputMediaFile() {
File mediaStorageDir = new File(
Environment.getExternalStorageDirectory(), "."
+ Constants.CONTAINER);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
mediaStorageDir.mkdirs();
}
File mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + System.currentTimeMillis() + ".png");
Uri uri = null;
if (mediaFile != null) {
uri = Uri.fromFile(mediaFile);
}
return uri;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK
&& requestCode == CAMERA_REQUEEST_CODE) {
String path =fileUri.getPath();
//decode the path to bitmap here
}
}

Image not saving in folder

I am trying to create a folder and save images in it.
But it's not working.
I don't know what's wrong in my code - can you tell me why?
// The method that invoke of uploading images
public void openGallery() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == RESULT_OK && data != null && data.getData() != null) {
File folder = new File(this.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), "albumName");
File file = new File(this.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), "fileName"+3);
Bitmap imageToSave = (Bitmap) data.getExtras().get("data");
try {
FileOutputStream out = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Uri selectedImage = data.getData();
Intent i = new Intent(this,
AddImage.class);
i.putExtra("imagePath", selectedImage.toString());
startActivity(i);
}
edit
final File path =
Environment.getExternalStoragePublicDirectory
(
// Environment.DIRECTORY_PICTURES + "/ss/"
//Environment.DIRECTORY_DCIM
Environment.DIRECTORY_DCIM + "/MyFolderName/"
);
// Make sure the Pictures directory exists.
if(!path.exists())
{
path.mkdirs();
}
Bitmap imageToSave = (Bitmap) data.getExtras().get("data");
final File file = new File(path, "file" + ".jpg");
try {
FileOutputStream fos = new FileOutputStream(path);
final BufferedOutputStream bos = new BufferedOutputStream(fos, 8192);
FileOutputStream out = new FileOutputStream(path);
//fos = new FileOutputStream(path);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, fos);
// imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
How I do make the folder in DCIM and create a file there into:
/*
Create a path where we will place our picture in the user's public
pictures directory. Note that you should be careful about what you
place here, since the user often manages these files.
For pictures and other media owned by the application, consider
Context.getExternalMediaDir().
*/
final File path =
Environment.getExternalStoragePublicDirectory
(
//Environment.DIRECTORY_PICTURES
//Environment.DIRECTORY_DCIM
Environment.DIRECTORY_DCIM + "/MyFolderName/"
);
// Make sure the Pictures directory exists.
if(!path.exists())
{
path.mkdirs();
}
final File file = new File(path, fileJPG + ".jpg");
try
{
final FileOutputStream fos = new FileOutputStream(file);
final BufferedOutputStream bos = new BufferedOutputStream(fos, 8192);
//bmp.compress(CompressFormat.JPEG, 100, bos);
bmp.compress(CompressFormat.JPEG, 85, bos);
bos.flush();
bos.close();
}
catch (final IOException e)
{
e.printStackTrace();
}
fileJPG is the file name I'm creating (dynamically, adding a date).
Replace MyFolderName with albumName.
bmp is my Bitmap data (a screenshot, in my case).
i take a long time for this faking error too and finally it's solve just with add this one line code in manifest
android:requestLegacyExternalStorage="true"

Fragment of SlideTabLayout: store Bitmap

i am using the API21 SlidingTabLayout and SlidingTabStrips for my application.
I am saving an .tmp file of my intent camera photo. that works fine and i can see it on my phone package directory but i can store this .tmp file as .png ( i want to change the resolution because i need <1mb files instead of the 3mb files from the photo API intent)
i tried so many things in the last two hours and i can't solve it.
here is my code:
starting the intent with: takeAPicture
private void takeAPicture(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(getView().getContext())));
startActivityForResult(intent, TAKE_PHOTO_CODE);
}
the path of my .tmp file: getTempFile
private File getTempFile(Context context){
final File path = new File(Environment.getExternalStorageDirectory(), getView().getContext().getPackageName());
if(!path.exists()){
path.mkdir();
}
return new File(path, "test.tmp");
}
at least i handle the ActivityResult:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "onActivityResult: Joined");
if(resultCode == Activity.RESULT_OK){
switch (requestCode){
case TAKE_PHOTO_CODE:
final File file = getTempFile(getView().getContext());
Toast.makeText(getActivity().getApplicationContext(), "Uri: " + Uri.fromFile(file), Toast.LENGTH_LONG);
try{
Bitmap captureBmp = MediaStore.Images.Media.getBitmap(getActivity().getApplicationContext().getContentResolver(), Uri.fromFile(file));
FileOutputStream fos = new FileOutputStream(new File(new File(Environment.getExternalStorageDirectory(), getView().getContext().getPackageName()),"done.png"));
captureBmp.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
The fact is, the .tmp file is stored and the uri for
Bitmap captureBmp = MediaStore.Images.Media.getBitmap(getActivity().getApplicationContext().getContentResolver(), Uri.fromFile(file));
is correct.
hope someone can help me
You can use my code:
public static boolean saveImage(Context context, byte[] image, String filename) {
Bitmap bitmapImage = BitmapFactory.decodeByteArray(image, 0, image.length);
return saveImage(context, bitmapImage, filename);
}
public static boolean saveImage(Context context, Bitmap image, String filename) {
try {
FileOutputStream fos = context.openFileOutput(filename,Context.MODE_PRIVATE);
imagem.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
File file = context.getFileStreamPath(filename);
} catch (Exception e) {
return false;
}
return true;
}

Categories

Resources