Guardar y leer mapas de bits / imágenes desde la memoria interna en Android

161

Lo que quiero hacer es guardar una imagen en la memoria interna del teléfono (no en la tarjeta SD) .

¿Cómo puedo hacerlo?

Tengo la imagen directamente de la cámara a la vista de imagen en mi aplicación, todo funciona bien.

Ahora lo que quiero es guardar esta imagen de la Vista de imagen en la memoria interna de mi dispositivo Android y también acceder a ella cuando sea necesario.

¿Alguien puede guiarme cómo hacer esto?

Soy un poco nuevo en Android, así que agradecería si puedo tener un procedimiento detallado.

Usama Zafar
fuente
Hola, ¿Dónde se /data/data/yourapp/app_data/imageDirencuentra exactamente? stackoverflow.com/questions/40323126/…
Khalil Khalaf

Respuestas:

344

Use el siguiente código para guardar la imagen en el directorio interno.

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

Explicacion:

1. El Directorio se creará con el nombre dado. Javadocs es para decir dónde exactamente creará el directorio.

2.Deberá indicar el nombre de la imagen con la que desea guardarlo.

Leer el archivo desde la memoria interna. Use el siguiente código

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
fuente
Me doy cuenta de que has colocado ciertos comentarios, ¿puedes guiarme por lo que implican? ¿Como el del camino? ¿Tengo que dar un camino o algo?
Usama Zafar
1
¿Cómo puedo acceder a mi imagen desde la memoria?
Usama Zafar
Edité la respuesta. Para acceder a la imagen desde la memoria. ¿Cómo está configurando la imagen a su imagen? Creo que no es más que Bitmap, la misma instancia que puede pasar a la función.
Brijesh Thakur
Por qué no. Vea la función, devuelve la ruta del archivo. que puede usar para recuperarlo y mostrarlo en la vista de imagen. También puse el código para recuperar la imagen
Brijesh Thakur
44
Realmente deberías cerrar la secuencia desde un bloque finalmente, no desde el interior del bloque try.
Kenn Cal
71
/**
 * 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

  • Ahorrar:

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

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

Editar:

Se agregó ImageSaver.setExternal(boolean)para admitir el almacenamiento en almacenamiento externo según el ejemplo de Google .

Ilya Gazman
fuente
13
Aquí hay otro método útil para poner en la clase:public boolean deleteFile(){ File file = createFile(); return file.delete(); }
Micro
cuando quiero compartir la imagen guardada, me devuelve "Directorio no creado" y la imagen se bloquea. ¿me puedes ayudar?
A. N
¿podría agregar una declaración sobre la licencia con la que está disponible este código para que sea posible incluirlo en un proyecto?
Don Park
2
@DonPark No es necesario, cualquier código en stackoverflowis está bajo licencia stackoverflow, puede usar esto sin preocupaciones :)
Ilya Gazman
Estoy tratando de usar esto, pero me encuentro con problemas. ¿Alguna ayuda sobre esta pregunta que publiqué? stackoverflow.com/questions/51276641/cannot-find-image-stored @IlyaGazman
Lion789
28

Encontré esta pregunta hoy y así es como lo hago. Simplemente llame a esta función con los parámetros requeridos

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

Del mismo modo, para leer lo mismo, use esto

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
fuente
¿Cómo pasa el argumento ba la función saveImage? He puesto las imágenes en mi dispositivo Android, pero no puedo entender su camino. Si no puedo obtener su camino, no puedo pasarlos como argumentos a la función saveImage.
Autónomo
Tengo esa foto en el dispositivo. Puedo verlo a través de aplicaciones de explorador de archivos, así como a través de adb shell, pero no pude obtener su dirección mediante programación. Así que pensé en escribirlo usando código y luego volver a leerlo. Leer es mi objetivo final, pero siempre lo consigo nilcuando intento leer esa foto.
Autónomo el
1
ok, entonces cuando dices que lo escribes de nuevo, supongo que tienes esos datos de imagen como un mapa de bits o datos sin formato en forma de matriz de bytes. Si tiene un mapa de bits, puede utilizar directamente las funciones anteriores. Si lo tiene en forma de matriz de bytes, use esto para convertirlo en mapa de bits Mapa de bits mapa de bits = BitmapFactory.decodeByteArray (bitmapdata, 0, bitmapdata .length); O incluso si está en cualquier otra forma, simplemente conviértalo en mapa de bits y use las funciones anteriores.
Anurag
"Edité la respuesta" con la extensión, en mi caso surgieron problemas, así que después de todo encontré el problema de que la extensión debería agregarse como parámetro.
Naveed Ahmad
Gracias por la edición, asumí que la extensión es parte del nombre en sí.
Anurag
6

Para los usuarios de Kotlin, creé una ImageStorageManagerclase que manejará las acciones de guardar, obtener y eliminar las imágenes fácilmente:

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

Lee más aquí

Amiraslan
fuente
¿Tiene que usar la ruta absoluta recibida de saveToInternalStorage () para recuperarla con getImageFromInternalStorage () o simplemente el nombre del archivo?
Leo Droidcoder
1
Solo imageFileNameserá suficiente para recuperarlo
Amiraslan
Hombre, perdí 10 horas para esto
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
fuente
La pregunta es sobre el almacenamiento interno.
Denny Kurniawan
0

// recuperar múltiples imágenes

 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();
Conoce a Bhavsar
fuente