Сохранение и чтение растровых изображений / изображений из внутренней памяти в Android

161

Что я хочу сделать, это сохранить изображение во внутренней памяти телефона (не на SD-карте) .

Как мне это сделать?

Я получил изображение прямо с камеры на просмотр изображений в моем приложении, все работает нормально.

Теперь я хочу сохранить это изображение из просмотра изображений во внутренней памяти моего устройства Android, а также получить к нему доступ при необходимости.

Кто-нибудь может подсказать, пожалуйста, как это сделать?

Я немного новичок в Android, поэтому, пожалуйста, я был бы признателен, если у меня может быть подробная процедура.

Усама Зафар
источник
Привет, Где /data/data/yourapp/app_data/imageDirименно находится? stackoverflow.com/questions/40323126/…
Халил Халаф

Ответы:

344

Используйте приведенный ниже код, чтобы сохранить изображение во внутреннем каталоге.

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

Пояснение:

1. Каталог будет создан с указанным именем. Javadocs для того, чтобы сказать, где именно он будет создавать каталог.

2. Вам нужно будет указать имя изображения, под которым вы хотите его сохранить.

Читать файл из внутренней памяти. Используйте код ниже

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

}
Бриеш Тхакур
источник
Я заметил, что вы разместили определенные комментарии, можете ли вы указать мне, что намекает? Как тот, который о пути? Должен ли я дать путь или что-то?
Усама Зафар
1
Как я могу получить доступ к своему изображению из памяти?
Усама Зафар
Я отредактировал ответ. Для доступа к изображению из памяти. Как вы устанавливаете изображение для вашего изображения? Я верю, что это ничто иное, как Bitmap, тот же экземпляр, который вы можете передать функции.
Брижеш Тхакур
Почему нет. Смотрите функцию, она возвращает путь к файлу. который вы можете использовать, чтобы получить его и показать его для просмотра изображений. Я поставил код для получения изображения
Брижеш Тхакур
4
Вы должны действительно закрыть поток из блока finally, а не из блока try.
Кенн Кэл
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;
    }
}

использование

  • Сохранить:

    new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            save(bitmap);
  • Загружать:

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

Редактировать:

Добавлена ImageSaver.setExternal(boolean)поддержка сохранения во внешнее хранилище на основе примера Google .

Илья Газман
источник
13
Вот еще один полезный метод в классе:public boolean deleteFile(){ File file = createFile(); return file.delete(); }
Микро
когда я хочу поделиться сохраненным изображением, он возвращает «Каталог не создан», и изображение падает. Вы можете помочь мне?
А. N
Не могли бы вы добавить заявление о лицензии, под которой этот код доступен, чтобы сделать возможным включение в проект?
Дон Парк
2
@ DonPark Нет необходимости, любой код на stackoverflow находится под лицензией stackoverflow, вы можете использовать это без забот :)
Илья Газман
Я пытаюсь использовать это, но сталкиваюсь с проблемами. Любая помощь по этому вопросу я разместил? stackoverflow.com/questions/51276641/cannot-find-image-stored @IlyaGazman
Lion789
28

Наткнулся сегодня на этот вопрос и вот как я это делаю. Просто вызовите эту функцию с необходимыми параметрами

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

Точно так же, чтобы прочитать то же самое, используйте этот

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;
}
Анураг
источник
Как вы передаете аргумент bв функцию saveImage. Я поместил изображения на свое устройство Android, но не могу найти их путь. Если я не могу получить их путь, я не могу передать их в качестве аргументов функции saveImage.
Автономное
У меня есть это фото на устройстве. Я вижу это через приложения для просмотра файлов, а также через оболочку adb, но мне не удалось получить его адрес программным путем. Поэтому я позволил мне написать это с использованием кода, а затем снова прочитать его. Чтение - моя конечная цель, но я всегда получаю, nilкогда пытаюсь прочитать эту фотографию.
Автономное
1
Итак, когда вы говорите, что пишете это снова, я предполагаю, что у вас есть эти данные изображения в виде растрового изображения или необработанных данных в виде байтового массива. Если у вас есть растровое изображение, вы можете напрямую использовать вышеуказанные функции. Если он у вас есть в виде байтового массива, используйте его для преобразования его в растровое изображение. Bitmap bitmap = BitmapFactory.decodeByteArray (bitmapdata, 0, bitmapdata .length); Или даже если это в любой другой форме, просто преобразуйте его в растровое изображение и используйте вышеуказанные функции.
Анураг
«Отредактировал ответ» с расширением, в моем случае были подняты проблемы, поэтому в конце концов я обнаружил проблему, что расширение должно быть добавлено в качестве параметра.
Навид Ахмад
Спасибо за редактирование, я предположил, что расширение является частью самого имени.
Анураг
6

Для пользователей Kotlin я создал ImageStorageManagerкласс, который будет легко обрабатывать действия сохранения, получения и удаления изображений:

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

Узнайте больше здесь

Амираслан
источник
Нужно ли использовать абсолютный путь, полученный от saveToInternalStorage (), чтобы получить его с помощью getImageFromInternalStorage () или просто имя файла?
Лев Droidcoder
1
Просто imageFileNameбудет достаточно , чтобы получить его
Амираслан
Человек, которого я потратил 10 часов на это
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);
    }
Анил Сингхания
источник
Вопрос о внутренней памяти.
Денни Курниаван
0

// извлечение нескольких изображений

 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();
Познакомьтесь с Бхавсаром
источник