Zapisywanie i odczytywanie bitmap / obrazów z pamięci wewnętrznej w systemie Android


161

To, co chcę zrobić, to zapisać obraz w wewnętrznej pamięci telefonu (nie na karcie SD) .

Jak mogę to zrobić?

Mam obraz bezpośrednio z aparatu do widoku obrazu w mojej aplikacji, wszystko działa dobrze.

Teraz chcę zapisać ten obraz z widoku obrazu w pamięci wewnętrznej mojego urządzenia z Androidem, a także uzyskać do niego dostęp w razie potrzeby.

Czy ktoś może mi pomóc, jak to zrobić?

Jestem trochę nowy w Androidzie, więc proszę, byłbym wdzięczny za szczegółową procedurę.


Cześć, gdzie /data/data/yourapp/app_data/imageDirdokładnie się znajduje? stackoverflow.com/questions/40323126/…
— Khalil Khalaf

Odpowiedzi:


344

Użyj poniższego kodu, aby zapisać obraz w katalogu wewnętrznym.

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

Wyjaśnienie:

1. Katalog zostanie utworzony pod podaną nazwą. Javadocs służy do informowania, gdzie dokładnie utworzy katalog.

2. Będziesz musiał podać nazwę obrazu, pod którą chcesz go zapisać.

Odczytać plik z pamięci wewnętrznej. Użyj poniższego kodu

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

}

Zauważyłem, że zamieściłeś pewne komentarze, czy możesz mi pokierować, co sugerują? Jak ta o ścieżce? Czy muszę wskazywać ścieżkę, czy coś?
— Usama Zafar,

1
Jak mogę uzyskać dostęp do mojego obrazu z pamięci?
— Usama Zafar,

Zredagowałem odpowiedź. Dostęp do obrazu z pamięci. Jak ustawiasz obraz do swojego obrazu? Uważam, że to nic innego jak Bitmap, ta sama instancja, którą możesz przekazać do funkcji.
— Brijesh Thakur,

Dlaczego nie. Zobacz funkcję, zwraca ścieżkę pliku. którego możesz użyć, aby go odzyskać i pokazać w widoku obrazu. Wpisałem również kod, aby odzyskać obraz
— Brijesh Thakur

4
Naprawdę powinieneś zamknąć strumień z bloku last, a nie z wnętrza bloku 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;
    }
}

Stosowanie

  • Zapisać:

    new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            save(bitmap);
  • Załadować:

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

Edytować:

Dodano ImageSaver.setExternal(boolean)obsługę zapisywania w pamięci zewnętrznej na podstawie przykładu Google .


13
Oto kolejna przydatna metoda do umieszczenia na zajęciach:public boolean deleteFile(){ File file = createFile(); return file.delete(); }
— Mikro

kiedy chcę udostępnić zapisany obraz, zwraca „Katalog nie został utworzony” i obraz jest uszkodzony. możesz mi pomóc?
— A. N

czy mógłbyś dodać oświadczenie o licencji, na której ten kod jest dostępny, aby umożliwić włączenie go do projektu?
— Don Park

2
@DonPark Nie ma potrzeby, każdy kod na stackoverflowis jest objęty licencją stackoverflow, możesz go używać bez obaw :)
— Ilya Gazman

Próbuję to wykorzystać, ale napotykam na problemy. Jakaś pomoc dotycząca tego pytania, które zamieściłem? stackoverflow.com/questions/51276641/cannot-find-image-stored @IlyaGazman
— Lion789

28

Dzisiaj przyszło mi do głowy to pytanie i tak to robię. Po prostu wywołaj tę funkcję z wymaganymi parametrami

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

Podobnie, aby przeczytać to samo, użyj tego

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

Jak przekazać argument bdo funkcji saveImage. Umieściłem obrazy na moim urządzeniu z Androidem, ale nie mogę znaleźć ich ścieżki. Jeśli nie mogę znaleźć ich ścieżki, nie mogę przekazać ich jako argumentów do funkcji saveImage.
— Autonomiczny

Mam to zdjęcie na urządzeniu. Widzę to za pomocą aplikacji eksploratora plików, a także powłoki adb, ale nie byłem w stanie uzyskać programowego adresu. Pomyślałem więc, że napiszę to za pomocą kodu, a następnie ponownie przeczytam. Czytanie jest moim ostatecznym celem, ale zawsze otrzymuję, nilgdy próbuję przeczytać to zdjęcie.
— Autonomiczny

1
ok, więc kiedy mówisz, że piszesz to ponownie, przypuszczam, że masz dane obrazu w postaci mapy bitowej lub surowych danych w postaci tablicy bajtów. Jeśli masz mapę bitową, możesz bezpośrednio wykorzystać powyższe funkcje. Jeśli masz go w postaci tablicy bajtów, użyj tego, aby przekonwertować go na mapę bitową Bitmap bitmap = BitmapFactory.decodeByteArray (bitmapdata, 0, bitmapdata .length); Lub nawet jeśli jest w jakiejkolwiek innej formie, po prostu przekonwertuj go na bitmapę i użyj powyższych funkcji.
— Anurag

„Edytowałem odpowiedź” z rozszerzeniem, w moim przypadku pojawiły się problemy, więc w końcu stwierdziłem, że rozszerzenie powinno być dodane jako parametr.
— Naveed Ahmad

Dzięki za edycję, założyłem, że rozszerzenie będzie częścią samej nazwy.
— Anurag

6

Dla użytkowników Kotlin stworzyłem ImageStorageManagerklasę, która z łatwością obsłuży zapisywanie, pobieranie i usuwanie akcji dla obrazów:

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

Przeczytaj więcej tutaj


Czy musisz użyć bezwzględnej ścieżki otrzymanej z saveToInternalStorage (), aby ją pobrać za pomocą getImageFromInternalStorage (), czy po prostu nazwę pliku?
— Leo Droidcoder

1
Wystarczy imageFileName, żeby go odzyskać
— Amiraslan,

Człowieku, zmarnowałem na to 10 godzin
— 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);
    }

pytanie dotyczy pamięci wewnętrznej.
— Denny Kurniawan

0

// pobieranie wielu obrazów

 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();
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.