Enregistrer et lire des bitmaps / images à partir de la mémoire interne sous Android

161

Ce que je veux faire, c'est enregistrer une image dans la mémoire interne du téléphone (pas sur la carte SD) .

Comment puis-je le faire?

J'ai l'image directement de la caméra à la vue d'image dans mon application, tout fonctionne bien.

Maintenant, ce que je veux, c'est enregistrer cette image de Image View dans la mémoire interne de mon appareil Android et y accéder également si nécessaire.

Quelqu'un peut-il s'il vous plaît me guider comment faire cela?

Je suis un peu nouveau sur Android alors s'il vous plaît, j'apprécierais si je peux avoir une procédure détaillée.

Usama Zafar
la source
Salut, où se /data/data/yourapp/app_data/imageDirtrouve exactement? stackoverflow.com/questions/40323126/…
Khalil Khalaf

Réponses:

344

Utilisez le code ci-dessous pour enregistrer l'image dans le répertoire interne.

private String saveToInternalStorage(Bitmap bitmapImage){
        ContextWrapper cw = new ContextWrapper(getApplicationContext());
         // path to /data/data/yourapp/app_data/imageDir
        File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
        // Create imageDir
        File mypath=new File(directory,"profile.jpg");

        FileOutputStream fos = null;
        try {           
            fos = new FileOutputStream(mypath);
       // Use the compress method on the BitMap object to write image to the OutputStream
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
        } catch (Exception e) {
              e.printStackTrace();
        } finally {
            try {
              fos.close();
            } catch (IOException e) {
              e.printStackTrace();
            }
        } 
        return directory.getAbsolutePath();
    }

Explication:

1. Le répertoire sera créé avec le nom donné. Javadocs est pour dire où exactement il créera le répertoire.

2. Vous devrez donner le nom de l'image sous laquelle vous souhaitez l'enregistrer.

Pour lire le fichier depuis la mémoire interne. Utilisez le code ci-dessous

private void loadImageFromStorage(String path)
{

    try {
        File f=new File(path, "profile.jpg");
        Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
            ImageView img=(ImageView)findViewById(R.id.imgPicker);
        img.setImageBitmap(b);
    } 
    catch (FileNotFoundException e) 
    {
        e.printStackTrace();
    }

}
Brijesh Thakur
la source
Je remarque que vous avez placé certains commentaires, pouvez-vous me guider ce que sous-entend? Comme celui sur le chemin? Dois-je donner un chemin ou quelque chose?
Usama Zafar
1
Comment puis-je accéder à mon image depuis la mémoire?
Usama Zafar
J'ai édité la réponse. Pour accéder à l'image de la mémoire. Comment définissez-vous l'image à votre image? Je crois que ce n'est rien d'autre que Bitmap, la même instance que vous pouvez transmettre à la fonction.
Brijesh Thakur
Pourquoi pas. Voir la fonction, elle renvoie le chemin du fichier. que vous pouvez utiliser pour le récupérer et le montrer à imageview. J'ai mis le code pour récupérer l'image également
Brijesh Thakur
4
Vous devriez vraiment fermer le flux à partir d'un bloc finally, et non à l'intérieur du bloc try.
Kenn Cal
72
/**
 * Created by Ilya Gazman on 3/6/2016.
 */
public class ImageSaver {

    private String directoryName = "images";
    private String fileName = "image.png";
    private Context context;
    private boolean external;

    public ImageSaver(Context context) {
        this.context = context;
    }

    public ImageSaver setFileName(String fileName) {
        this.fileName = fileName;
        return this;
    }

    public ImageSaver setExternal(boolean external) {
        this.external = external;
        return this;
    }

    public ImageSaver setDirectoryName(String directoryName) {
        this.directoryName = directoryName;
        return this;
    }

    public void save(Bitmap bitmapImage) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(createFile());
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @NonNull
    private File createFile() {
        File directory;
        if(external){
            directory = getAlbumStorageDir(directoryName);
        }
        else {
            directory = context.getDir(directoryName, Context.MODE_PRIVATE);
        }
        if(!directory.exists() && !directory.mkdirs()){
            Log.e("ImageSaver","Error creating directory " + directory);
        }

        return new File(directory, fileName);
    }

    private File getAlbumStorageDir(String albumName) {
        return new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), albumName);
    }

    public static boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state);
    }

    public static boolean isExternalStorageReadable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state) ||
                Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
    }

    public Bitmap load() {
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(createFile());
            return BitmapFactory.decodeStream(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

Usage

  • Sauver:

    new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            save(bitmap);
  • Charger:

    Bitmap bitmap = new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            load();

Éditer:

Ajouté ImageSaver.setExternal(boolean)pour prendre en charge l'enregistrement sur un stockage externe basé sur l' exemple de Google .

Ilya Gazman
la source
13
Voici une autre méthode utile à mettre en classe:public boolean deleteFile(){ File file = createFile(); return file.delete(); }
Micro
lorsque je veux partager l'image enregistrée, il renvoie "Répertoire non créé" et l'image est plantée. Pouvez-vous m'aider?
A. N
pourriez-vous ajouter une déclaration sur la licence sous laquelle ce code est disponible, pour permettre de l'inclure dans un projet?
Don Park
2
@DonPark Pas besoin, tout code sur stackoverflowis est sous licence stackoverflow, vous pouvez l'utiliser sans soucis :)
Ilya Gazman
J'essaye d'utiliser ceci, mais je rencontre des problèmes. Une aide sur cette question que j'ai postée? stackoverflow.com/questions/51276641/cannot-find-image-stored @IlyaGazman
Lion789
28

Je suis tombé sur cette question aujourd'hui et voici comment je le fais. Appelez simplement cette fonction avec les paramètres requis

public void saveImage(Context context, Bitmap bitmap, String name, String extension){
    name = name + "." + extension;
    FileOutputStream fileOutputStream;
    try {
        fileOutputStream = context.openFileOutput(name, Context.MODE_PRIVATE);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileOutputStream);
        fileOutputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

De même, pour lire la même chose, utilisez ceci

public Bitmap loadImageBitmap(Context context,String name,String extension){
    name = name + "." + extension
    FileInputStream fileInputStream
    Bitmap bitmap = null;
    try{
        fileInputStream = context.openFileInput(name);
        bitmap = BitmapFactory.decodeStream(fileInputStream);
        fileInputStream.close();
    } catch(Exception e) {
        e.printStackTrace();
    }
     return bitmap;
}
Anurag
la source
Comment passez-vous l'argument bà la fonction saveImage. J'ai mis les images sur mon appareil Android, mais je ne parviens pas à obtenir leur chemin. Si je ne peux pas obtenir leur chemin, je ne peux pas les transmettre comme arguments à la fonction saveImage.
Autonome
J'ai cette photo sur l'appareil. Je peux le voir à travers les applications d'explorateur de fichiers ainsi que le shell adb, mais je n'ai pas pu obtenir son adresse par programme. Donc, je me suis laissé l'écrire en utilisant du code, puis le relire. La lecture est mon but ultime, mais j'obtiens toujours nilquand j'essaye de lire cette photo.
Autonome
1
ok donc quand vous dites que vous l'écrivez à nouveau, je suppose que vous avez ces données d'image sous forme de bitmap ou de données brutes sous forme de tableau d'octets. Si vous avez un bitmap, vous pouvez utiliser directement les fonctions ci-dessus. Si vous l'avez sous la forme d'un tableau d'octets, utilisez-le pour le convertir en bitmap Bitmap bitmap = BitmapFactory.decodeByteArray (bitmapdata, 0, bitmapdata .length); Ou même si c'est sous une autre forme, convertissez-le simplement en bitmap et utilisez les fonctions ci-dessus.
Anurag
"Modifié la réponse" avec l'extension, dans mon cas, des problèmes ont été soulevés, donc après tout j'ai trouvé le problème que l'extension devrait être ajoutée en tant que paramètre.
Naveed Ahmad
Merci pour la modification, j'ai supposé que l'extension faisait partie du nom lui-même.
Anurag
6

Pour les utilisateurs de Kotlin, j'ai créé une ImageStorageManagerclasse qui gérera facilement les actions d'enregistrement, d'obtention et de suppression des images:

class ImageStorageManager {
    companion object {
        fun saveToInternalStorage(context: Context, bitmapImage: Bitmap, imageFileName: String): String {
            context.openFileOutput(imageFileName, Context.MODE_PRIVATE).use { fos ->
                bitmapImage.compress(Bitmap.CompressFormat.PNG, 25, fos)
            }
            return context.filesDir.absolutePath
        }

        fun getImageFromInternalStorage(context: Context, imageFileName: String): Bitmap? {
            val directory = context.filesDir
            val file = File(directory, imageFileName)
            return BitmapFactory.decodeStream(FileInputStream(file))
        }

        fun deleteImageFromInternalStorage(context: Context, imageFileName: String): Boolean {
            val dir = context.filesDir
            val file = File(dir, imageFileName)
            return file.delete()
        }
    }
}

En savoir plus ici

Amiraslan
la source
Devez-vous utiliser le chemin absolu reçu de saveToInternalStorage () pour le récupérer avec getImageFromInternalStorage () ou simplement le nom de fichier?
Leo Droidcoder
1
Juste imageFileNameassez pour le récupérer
Amiraslan
Homme que j'ai perdu 10 heures pour ça
Pb Studies
0
    public static String saveImage(String folderName, String imageName, RelativeLayout layoutCollage) {
        String selectedOutputPath = "";
        if (isSDCARDMounted()) {
            File mediaStorageDir = new File(
                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), folderName);
            // Create a storage directory if it does not exist
            if (!mediaStorageDir.exists()) {
                if (!mediaStorageDir.mkdirs()) {
                    Log.d("PhotoEditorSDK", "Failed to create directory");
                }
            }
            // Create a media file name
            selectedOutputPath = mediaStorageDir.getPath() + File.separator + imageName;
            Log.d("PhotoEditorSDK", "selected camera path " + selectedOutputPath);
            File file = new File(selectedOutputPath);
            try {
                FileOutputStream out = new FileOutputStream(file);
                if (layoutCollage != null) {
                    layoutCollage.setDrawingCacheEnabled(true);
                    layoutCollage.getDrawingCache().compress(Bitmap.CompressFormat.JPEG, 80, out);
                }
                out.flush();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return selectedOutputPath;
    }



private static boolean isSDCARDMounted() {
        String status = Environment.getExternalStorageState();
        return status.equals(Environment.MEDIA_MOUNTED);
    }
Anil Singhania
la source
question concerne le stockage interne.
Denny Kurniawan
0

// récupération d'images multiples

 File folPath = new File(getIntent().getStringExtra("folder_path"));
 File[] imagep = folPath.listFiles();

 for (int i = 0; i < imagep.length ; i++) {
     imageModelList.add(new ImageModel(imagep[i].getAbsolutePath(), Uri.parse(imagep[i].getAbsolutePath())));
 }
 imagesAdapter.notifyDataSetChanged();
Rencontrez Bhavsar
la source