Saving an image from ImageView into internal storage
Asked Answered
G

7

0

I have created an ImageView and I can see the preview of the camera and load the captured image into the ImageView and I wanted to store the image into a directory in my internal memory. I have referred many posts and tried but I couldn't find my image in my internal memory.

This is the code I have used:

package com.example.shravan.camera;

import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    private final String TAG = "abc";

    static final int REQUEST_IMAGE_CAPTURE =1 ;
    ImageView iv;
    Uri imageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn = (Button)findViewById(R.id.myB);
        iv = (ImageView) findViewById(R.id.myIV);
        //disable the button if the user has no camera
        if (!hasCamera()) {
            btn.setEnabled(false);
        }
    }

    public boolean hasCamera() {
        return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
    }

    //on click event handler that launches the camera
    public void launchCamera(View v) {
        Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(i, REQUEST_IMAGE_CAPTURE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            imageUri=data.getData();
            iv.setImageURI(imageUri);;
        }
    }

    public void SaveFile(View v) {
        BitmapDrawable drawable = (BitmapDrawable) iv.getDrawable();
        Bitmap bitmap = drawable.getBitmap();

        print("Creating cw");
        ContextWrapper cw = new ContextWrapper(this.getApplicationContext());
        print("Creating dir");
        File directory = cw.getDir("ImagesDir", Context.MODE_PRIVATE);
        print("Created dir" + directory);
        File mypath = new File(directory,"myImagesDGS.jpg");
        print("path is" + mypath);

        FileOutputStream fos = null;
        try {
            print("creating fos");
            fos = new FileOutputStream(mypath);
            print("Compressing bitmap");
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
                print("fos closed");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void print(String str){
        Log.d(TAG, str);
    }

}

I have made many log messages to debug and I got one path which I couldn't find in my phone.

This is the logcat:

08-07 21:47:37.089 11030-11030/com.example.shravan.camera D/abc: Creating cw 08-07

21:47:37.089 11030-11030/com.example.shravan.camera D/abc: Creating dir 08-07

21:47:37.099 11030-11030/com.example.shravan.camera D/abc: Created dir/data/user/0/com.example.shravan.camera/app_ImagesDir 08-07

21:47:37.099 11030-11030/com.example.shravan.camera D/abc: path is/data/user/0/com.example.shravan.camera/app_ImagesDir/myImagesDGS.jpg

08-07 21:47:37.099 11030-11030/com.example.shravan.camera D/abc: creating fos

08-07 21:47:37.099 11030-11030/com.example.shravan.camera D/abc: Compressing bitmap

08-07 21:47:42.589 11030-11030/com.example.shravan.camera D/abc: fos closed

Is there anything I need to check and I should change? Please help!

Ger answered 8/8, 2016 at 2:54 Comment(8)
ITs in /data/user/0/com.example.shravan.camera/app_ImagesDir/myImagesDGS.jpg. But you need root access to get at private app files.Bally
Your app saved a file in an app specific private directory. Only your app has access (no need for root)). Not other apps like file explorers which you used to find the file.Wilbur
@Wilbur How can I find it on file explorer then?Ger
@GabeSechan How can I access it from other apps? What modifications do I need to make?Ger
As said you can not find it with a file explorer. So don't save your file in internal memory but in external.Wilbur
My device doesn't have an external storage. That's the problem! What should I do now in this case to create a separate folder in my internal memory and then store my images in that directory?Ger
All devices have internal and external storage. It is unclear where you are talking about. If you put a micro SD card in it then that is considered removable storage.Wilbur
Ya. My device doesn't have support for a micro SD. All it has is internal storage. So, that's the issueGer
G
9

Got it working!

I used this code to create a directory in my file storage and then store the image:

FileOutputStream outStream = null;

// Write to SD Card
try {
    File sdCard = Environment.getExternalStorageDirectory();
    File dir = new File(sdCard.getAbsolutePath() + "/camtest");
    dir.mkdirs();

    String fileName = String.format("%d.jpg", System.currentTimeMillis());
    File outFile = new File(dir, fileName);

    outStream = new FileOutputStream(outFile);
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
    outStream.flush();
    outStream.close();

    Log.d(TAG, "onPictureTaken - wrote to " + outFile.getAbsolutePath());

    refreshGallery(outFile);
} catch (FileNotFoundException e) {
    print("FNF");
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {

}

My permissions:

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

Finally, the most important thing:

Go to Device Settings>Device>Applications>Application Manager>"your app">Permissions>Enable Storage permission!

Ger answered 11/8, 2016 at 18:34 Comment(3)
I've seen many suggestions but this one worked for me because of the important final step haha, most were missing this step so thanksCutinize
No worries mateGer
describing top to bottom, thanks, just send a parameter Bitmap bitmap, to the method, excellent.Tardy
I
1

The location your current images are saving, cannot be accessed by an other application.It's better to save them in a accessible location.try like this..

BitmapDrawable drawable = (BitmapDrawable) iv.getDrawable();
Bitmap bitmap = drawable.getBitmap();
 try {
           String root = Environment.getExternalStorageDirectory().toString();
           File file = new File(root + "/YourDirectory/myImagesDGS.jpg");
           FileOutputStream out = new FileOutputStream(file);
           bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
           out.flush();
           out.close();

                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                }

then you can retrieve your saved images like this..

String root = Environment.getExternalStorageDirectory().toString();
  File file = new File(root + "/YourDirectory/myImagesDGS.jpg");    
Bitmap bmap=BitmapFactory.decodeFile(file.getAbsolutePath());
Invalidism answered 8/8, 2016 at 3:48 Comment(12)
The location your current images are saving, cannot be accessed. Of course you can. If you can write to files there you can read them too. Please rephrase what you mean.Wilbur
I have tried your code and it gave me a file not found exception! What am I missing?Ger
But my device doesn't have external storage! How to create a directory in internal storage? @WilburGer
@ShravanDG actually you does...the one you can access(Internal Storage) is referred as external storage here..Invalidism
Where will the images be saved (the directory of the app or YourDirectory) in internal memory? I didn't find anything in either of these folders!Ger
@ShravanDG you'll find a directory called "yourdirectory" in your storage...that is where the file is being storedInvalidism
@Sandaruwan I cannot create the directory and save the image. I have been trying it in several ways. Can you please help?Ger
@ShravanDG are there any execeptions thrown....can you please check where the code breaks using Log.e() or somethingInvalidism
I am getting a FileNotFound exception! Don't know why! What am I missing?Ger
can you check weather the file is properly stored or not in the storage...using a file manager tool or something..Invalidism
That is the problem. I have checked it! It is not being stored!Ger
It is stored in some random location /data/user/0/com.example.shravan.asbdbsadbsabcxscsa/app_mydir/myfile which I cant find. By default I can ses the image in DCIM folder.Ger
M
0

Your image is saving from this path /data/user/0/com.example.shravan.camera/app_ImagesDir/myImagesDGS.jpg but your are not access.try this code for iamge reading.Call this method into onCreate this method is return you bitmap.

 Bitmap mBitmap= getImageBitmap(this,"myImagesDGS","jpg");

   if(mBitmap !=null){

yourImageView.setBitmap(mBitmap);

}else{

Log.d("MainActivity","Image is not found");
}

It is sepread method

     public Bitmap getImageBitmap(Context context,String name,String extension){
        name=name+"."+extension;  
        try{ 
            FileInputStream fis = context.openFileInput(name);
                Bitmap b = BitmapFactory.decodeStream(fis);
                fis.close();
                return b;
            } 
            catch(Exception e){
            } 
            return null; 
        }
Midstream answered 8/8, 2016 at 3:21 Comment(0)
R
0

try this. I modified my code to fit the code your provide. I did not test it. I temporary store the photo taken into a file with time stamp, then use the filename to retrieve the file. Hope it helps

private Uri mImageCaptureUri;
public void launchCamera(View v)
{
    //Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    //startActivityForResult(i, REQUEST_IMAGE_CAPTURE);

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
                            "tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));

                    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (mImageCaptureUri!=null){
//Do whatever you want with the uri
}

}
}
Residuary answered 8/8, 2016 at 3:25 Comment(0)
A
0

With that code, you will be ended to store your file to your private application data. You can't access that data with other applications except your application itself without root access. You can get the public image directory by using this code instead when declaring the file path if you want your image file can be accessed by other applications.

File albumF;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
    albumF = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
} else {
    albumF = context.getFilesDir();
}

If you need to make your sub directory inside public gallery directory, you can change the code above like this:

File albumF;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
    albumF = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DCIM), YOUR_SUB_DIRECTORY_STRING);
} else {
    albumF = new File(context.getFilesDir(), YOUR_SUB_DIRECTORY_STRING);
}

You might be need to add this code to create that album directory

if (!albumF.exists()) {
    albumF.mkdirs();
}
Anemochore answered 8/8, 2016 at 3:32 Comment(8)
I tried this code but still can't find my image directory or image in gallery! It just gets added to my default camera folder. Please helpGer
@ShravanDG yes, nothing wrong with the code, because it should work like that. I will add a code to make your subfolder inside the public gallery folderAnemochore
I have just tried the code and my app is stopping unfortunately. Can you plese look into this? my code: (I am saving the image on button click)Ger
//after converting image to bitmap then File albumF; if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ albumF = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "MyDir"); } else { albumF = new File(context.getFilesDir(), "MyDir"); } albumF.mkdirs(); File file = new File(albumF, "a.jpg"); FileOutputStream fout = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG, 85, fout); }Ger
@ShravanDG can you show the stack trace of the error?Anemochore
I got this: E/System: Uncaught exception thrown by finalizer, E/System: java.lang.IllegalStateException: Binder has been finalized at android.os.BinderProxy.transactNative(Native Method) at android.os.BinderProxy.transact(Binder.java:503) at com.android.internal.app.IAppOpsService$Stub$Proxy.stopWatchingMode(IAppOpsService.java:431) at android.media.SoundPool.release(SoundPool.java:195) at android...Ger
Hendra Wijaya Djiono- I debugged it! The app is crashing at this part: albumF.mkdirs(); File file = new File(albumF, FILENAME + CurrentDateAndTime + ".jpg"); FileOutputStream fout = new FileOutputStream(file); What shoud I do? (error while creating the fout and getting a FileNotFound exception!) Help..Ger
Try to check if the file exist first. If not exist, just create the file. if(!file.exists()) { file.createNewFile(); }Anemochore
G
0

Try using ImageSaver. It's a synchronous way to save and load images from internal and external storage.

Usage

  • To save:

    new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            setExternal(true).
            save(bitmap);
    
  • To load:

    Bitmap bitmap = new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            setExternal(true).
            load();
    
Gourley answered 10/8, 2016 at 6:8 Comment(0)
D
0

The solution proposed by @Shravan DG gives error for me. I have modified his code little bit and it works without errors.

 private void downloadQR()
{
    FileOutputStream outStream = null;
    
    try {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "QRCode_" + timeStamp + ".jpg";
        File storageDir = new File(Environment.getExternalStorageDirectory().toString(), "PARENT_DIR)/CHILD_DIR/");
        storageDir.mkdirs();

        File outFile = new File(storageDir, imageFileName);
        outStream = new FileOutputStream(outFile);
        BitmapDrawable drawable = (BitmapDrawable) qrCode.getDrawable();
        Bitmap bitmap = drawable.getBitmap();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
        outStream.flush();
        outStream.close();

        Log.d(TAG, "onPictureTaken - wrote to " + outFile.getAbsolutePath());

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {

    }
}

Chill Pill :)

Derte answered 9/5, 2021 at 17:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.