Salvando e lendo bitmaps / imagens da memória interna no Android

161

O que eu quero fazer é salvar uma imagem na memória interna do telefone (não no cartão SD) .

Como eu posso fazer isso?

Eu tenho a imagem diretamente da câmera para a visualização da imagem no meu aplicativo, tudo está funcionando bem.

Agora, o que eu quero é salvar esta imagem do Image View na memória interna do meu dispositivo Android e também acessá-la quando necessário.

Alguém pode me guiar como fazer isso?

Eu sou um pouco novo para o Android, então, por favor, gostaria de ter um procedimento detalhado.

Usama Zafar
fonte
Olá, onde está /data/data/yourapp/app_data/imageDirlocalizado exatamente? stackoverflow.com/questions/40323126/…
Khalil Khalaf

Respostas:

344

Use o código abaixo para salvar a imagem no diretório 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();
    }

Explicação:

1.O Diretório será criado com o nome fornecido. Javadocs é para dizer onde exatamente ele criará o diretório.

2.Você terá que dar o nome da imagem com o qual deseja salvá-la.

Para ler o arquivo da memória interna. Use o código abaixo

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
fonte
Percebo que você colocou certos comentários. Você pode me orientar sobre o que está implicando? Como a do caminho? Eu tenho que dar um caminho ou algo assim?
Osama Zafar
1
Como posso acessar minha imagem da memória?
Osama Zafar
Eu editei a resposta. Para acessar a imagem da memória. Como você está definindo a imagem para a sua imagem? Eu acredito que não passa de Bitmap, a mesma instância que você pode passar para a função.
Brijesh Thakur
Por que não. Veja a função, ela retorna o caminho do arquivo. que você pode usar para recuperá-lo e mostrá-lo na visualização de imagens. Eu coloquei o código para recuperar a imagem bem
Brijesh Thakur
4
Você realmente deve fechar o fluxo de um bloco final, não de dentro do bloco try.
quer
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

  • Salvar:

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

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

Editar:

Adicionado ImageSaver.setExternal(boolean)para oferecer suporte à gravação em armazenamento externo com base no exemplo do Google .

Ilya Gazman
fonte
13
Aqui está outro método útil para colocar na classe:public boolean deleteFile(){ File file = createFile(); return file.delete(); }
Micro
quando quero compartilhar a imagem salva, ele retorna "Diretório não criado" e a imagem cai. pode me ajudar?
A. N
você poderia adicionar uma declaração sobre a licença sob a qual este código está disponível, para possibilitar a inclusão em um projeto?
Don Park
2
@DonPark Não há necessidade, qualquer código em stackoverflowis está sob licença stackoverflow, você pode usar este sem preocupações :)
Ilya gazman
Estou tentando usar isso, mas estou enfrentando problemas. Alguma ajuda sobre esta questão eu postei? O que você precisa
saber para
28

Hoje me deparei com essa questão e é assim que eu faço. Basta chamar esta função com os parâmetros necessários

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

Da mesma forma, para ler o mesmo, use este

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
fonte
Como você passar o argumento bpara a função saveImage. Coloquei as imagens no meu dispositivo Android, mas não consigo encontrar o caminho delas. Se não consigo encontrar o caminho deles, não posso passá-los como argumentos para a função saveImage.
Autônomo
Eu tenho essa foto no dispositivo. Consigo vê-lo através de aplicativos exploradores de arquivos e do shell adb, mas não consegui obter o endereço programaticamente. Então, eu deixei que eu escrevesse usando código e depois o lesse novamente. A leitura é o meu objetivo final, mas sempre consigo nilquando tento ler essa foto.
Autónomo
1
ok, então quando você diz que escreve novamente, suponho que você tenha esses dados de imagem como bitmap ou dados brutos na forma de matriz de bytes. Se você tiver bitmap, poderá utilizar diretamente as funções acima. Se você o tiver na forma de matriz de bytes, use-o para convertê-lo em bitmap Bitmap bitmap = BitmapFactory.decodeByteArray (bitmapdata, 0, bitmapdata .length); Ou mesmo se estiver em qualquer outra forma, basta convertê-lo em bitmap e usar as funções acima.
Anurag
"Editado a resposta" com extensão, no meu caso, foram levantados problemas, então, afinal, achei o problema de que a extensão deveria ser adicionada como parâmetro.
Naveed Ahmad
Obrigado pela edição, assumi que a extensão fazia parte do próprio nome.
Anurag 25/03
6

Para usuários do Kotlin, criei uma ImageStorageManagerclasse que manipulará salvar, obter e excluir ações de imagens facilmente:

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

Leia mais aqui

Amiraslan
fonte
Você precisa usar o caminho absoluto recebido de saveToInternalStorage () para recuperá-lo com getImageFromInternalStorage () ou apenas o nome do arquivo?
Leo Droidcoder 14/10/19
1
Apenas imageFileNameserá suficiente para recuperá-lo
Amiraslan
Cara, eu perdi 10 horas por isso
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
fonte
pergunta é sobre armazenamento interno.
Denny Kurniawan
0

// recuperação de imagem múltipla

 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();
Conheça Bhavsar
fonte