Salvataggio e lettura di bitmap / immagini dalla memoria interna in Android


161

Quello che voglio fare è salvare un'immagine nella memoria interna del telefono (Not The SD Card) .

Come posso farlo?

Ho ottenuto l'immagine direttamente dalla fotocamera alla visualizzazione dell'immagine nella mia app, tutto funziona bene.

Ora quello che voglio è salvare questa immagine da Image View nella memoria interna del mio dispositivo Android e accedervi anche quando richiesto.

Qualcuno può guidarmi per favore come fare questo?

Sono un po 'nuovo per Android, quindi per favore, apprezzerei se potessi avere una procedura dettagliata.


Ciao, dove si /data/data/yourapp/app_data/imageDirtrova esattamente? stackoverflow.com/questions/40323126/…
Khalil Khalaf,

Risposte:


344

Utilizzare il codice seguente per salvare l'immagine nella directory interna.

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();
    }

Spiegazione :

1.La directory verrà creata con il nome specificato. Javadocs serve a dire esattamente dove creerà la directory.

2. Dovrai dare il nome dell'immagine con cui vuoi salvarlo.

Leggere il file dalla memoria interna. Usa sotto il codice

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();
    }

}

Ho notato che hai inserito alcuni commenti, mi puoi guidare cosa sono implicanti? Come quello sul percorso? Devo dare un percorso o qualcosa del genere?
Usama Zafar,

1
Come posso accedere alla mia immagine dalla memoria?
Usama Zafar,

Ho modificato la risposta. Per accedere all'immagine dalla memoria. Come stai impostando l'immagine sulla tua immagine ?? Credo che non sia altro che Bitmap, la stessa istanza che puoi passare alla funzione.
Brijesh Thakur,

Perchè no. Vedi la funzione, restituisce il percorso del file. che puoi usare per recuperarlo e mostrarlo a imageview. Ho inserito anche il codice per recuperare l'immagine
Brijesh Thakur,

4
Dovresti davvero chiudere lo stream da un blocco finally, non dall'interno del blocco 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;
    }
}

uso

  • Salvare:

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

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

Modificare:

Aggiunto ImageSaver.setExternal(boolean)per supportare il salvataggio su memoria esterna basata sull'esempio di Google .


13
Ecco un altro metodo utile per mettere in classe:public boolean deleteFile(){ File file = createFile(); return file.delete(); }
Micro

quando voglio condividere l'immagine salvata, restituisce "Directory non creata" e l'immagine si arresta in modo anomalo. Mi potete aiutare?
A. N

potresti aggiungere una dichiarazione sulla licenza con cui questo codice è disponibile, per rendere possibile l'inclusione in un progetto?
Don Park,

2
@DonPark Non c'è bisogno, qualsiasi codice su StackOverflow è sotto licenza StackOverflow, puoi usarlo senza preoccupazioni :)
Ilya Gazman

Sto cercando di utilizzare questo, ma ho riscontrato problemi. Qualche aiuto su questa domanda che ho pubblicato? stackoverflow.com/questions/51276641/cannot-find-image-stored @IlyaGazman
Lion789

28

Oggi ho risposto a questa domanda ed è così che lo faccio. Basta chiamare questa funzione con i parametri richiesti

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();
    }
}

Allo stesso modo, per leggere lo stesso, usa questo

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;
}

Come si passa l'argomento balla funzione saveImage. Ho inserito le immagini sul mio dispositivo Android, ma non riesco a trovare il loro percorso. Se non riesco a trovare il loro percorso, non posso passarli come argomenti alla funzione saveImage.
Autonomo

Ho quella foto sul dispositivo. Posso vederlo attraverso le app di esplorazione dei file e la shell adb, ma non sono stato in grado di ottenere il suo indirizzo a livello di codice. Così però ho lasciato che lo scrivessi usando il codice e poi lo leggessi di nuovo. La lettura è il mio obiettivo finale, ma ottengo sempre nilquando provo a leggere quella foto.
Autonomo

1
ok quindi quando dici che lo scrivi di nuovo, suppongo che tu abbia quei dati immagine come bitmap o dati grezzi sotto forma di array di byte. Se si dispone di bitmap, è possibile utilizzare direttamente le funzioni sopra. Se lo hai sotto forma di array di byte, utilizzalo per convertirlo in bitmap Bitmap bitmap = BitmapFactory.decodeByteArray (bitmapdata, 0, bitmapdata .length); O anche se è in qualsiasi altra forma, è sufficiente convertirlo in bitmap e utilizzare le funzioni sopra.
Anurag,

"Modificato la risposta" con l'estensione, nel mio caso sono stati sollevati problemi, quindi dopo tutto ho riscontrato il problema che l'estensione dovrebbe essere aggiunta come parametro.
Naveed Ahmad,

Grazie per la modifica, ho ipotizzato che l'estensione facesse parte del nome stesso.
Anurag,

6

Per gli utenti di Kotlin, ho creato una ImageStorageManagerclasse che gestirà facilmente le operazioni di salvataggio, acquisizione ed eliminazione delle immagini:

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()
        }
    }
}

Leggi di più qui


Devi usare il percorso assoluto ricevuto da saveToInternalStorage () per recuperarlo con getImageFromInternalStorage () o solo il nome del file?
Leo Droidcoder

1
Basta la imageFileNamevolontà di recuperarlo
Amiraslan,

Amico, ho sprecato 10 ore per questo
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);
    }

la domanda riguarda la memoria interna.
Denny Kurniawan,

0

// recupero dell'immagine multipla

 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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.