在Android中从内存中保存和读取位图/图像


161

我要做的是将图像保存到手机的内部存储器中(不是SD卡)

我该怎么做?

我已经将图像直接从相机获取到应用程序中的图像视图,并且一切正常。

现在,我想要的是将该图像从“图像视图”保存到我的android设备的内存中,并在需要时访问它。

谁能指导我该怎么做?

我对android有点陌生,所以,请提供详细的程序,不胜感激。


嗨,/data/data/yourapp/app_data/imageDir确切的位置在哪里?stackoverflow.com/questions/40323126/…–
哈利勒·克拉夫

Answers:


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

}

我注意到您已经发表了某些评论,您可以指导我暗示什么吗?喜欢一条关于道路的路吗?我需要给个路径吗?
Usama Zafar

1
如何从内存访问图像?
Usama Zafar

我编辑了答案。从内存访问图像。您如何将图像设置为图像?我相信它只是Bitmap,您可以传递给该函数相同的实例。
Brijesh Thakur

为什么不。参见函数,它返回文件路径。您可以使用它来检索它并将其显示到imageview。我已经把代码来获取图像,以及
Brijesh塔库尔

4
您应该真正从finally块关闭流,而不是从try块内部关闭流。
肯恩·卡尔

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

用法

  • 保存:

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

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

编辑:

添加ImageSaver.setExternal(boolean)以支持基于googles示例保存到外部存储。


13
这是上课的另一种有用方法:public boolean deleteFile(){ File file = createFile(); return file.delete(); }
Micro

当我要共享保存的图像时,它返回“未创建目录”,并且图像崩溃了。你能帮助我吗?
A. N

您是否可以添加有关此代码可使用的许可证的声明,以使其可以包含在项目中?
Don Park

2
@DonPark不需要,stackoverflowis上的任何代码都受stackoverflow许可,您可以毫无后顾之忧地使用它:)
Ilya Gazman

我正在尝试使用它,但是遇到了问题。对我发布的这个问题有帮助吗?stackoverflow.com/questions/51276641/cannot-find-image-stored @IlyaGazman
Lion789 '18

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
2014年

我在设备上有这张照片。我可以通过文件资源管理器应用程序和adb shell看到它,但是我无法以编程方式获取其地址。所以我虽然让我使用代码编写它,然后再次读取它。阅读是我的最终目标,但是nil当我尝试阅读这张照片时,我总能做到。
2014年

1
好的,所以当您说要再次写入时,我想您将图像数据作为位图或原始数据以字节数组的形式存储。如果有位图,则可以直接利用上述功能。如果您以字节数组的形式获取它,请使用它将其转换为位图。位图bitmap = BitmapFactory.decodeByteArray(bitmapdata,0,bitmapdata .length); 或者,即使采用任何其他形式,也可以将其转换为位图并使用上述功能。
阿努拉格

带有扩展名的“编辑答案”,在我的情况下,出现了问题,所以我最终发现应该将扩展名作为参数添加的问题。
Naveed Ahmad 2015年

感谢您的编辑,我认为扩展名是名称本身的一部分。
阿努拉格2015年

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()或仅使用文件名来检索它?
Leo Droidcoder

1
只需imageFileName将足以找回它
Amiraslan

我为此花了10个小时
铅研究

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

问题是关于内部存储。
Denny Kurniawan

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();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.