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

我想做的,是保存一个图像的内部存储器的手机 (不是 SD 卡)

我该怎么做?

我已经得到的图像直接从相机的图像视图在我的应用程序它的所有工作都很好。

现在我想要的是保存这个图像从图像视图到我的机器人设备的内部存储器,并在需要时访问它。

有人能告诉我怎么做吗?

我是一个有点新的机器人,所以请,我会感激如果我能有一个详细的程序。

299545 次浏览

使用下面的代码将图像保存到内部目录。

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


}
今天碰到这个问题,我就是这么做的。 只需使用所需的参数

调用这个函数
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;
}
/**
* 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);
    
  • To load:

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

Edit:

Added ImageSaver.setExternal(boolean) to support saving to external storage based on googles example.

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

阅读更多 给你

//多重图像检索

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

如果你想按照 Android 10的实践在存储器中编写代码,请点击这里 如果你只想图像是应用程序特定的,给你 例如,如果你想存储一个图像只是为了你的应用程序使用:

viewModelScope.launch(Dispatchers.IO) {
getApplication<Application>().openFileOutput(filename, Context.MODE_PRIVATE).use {
bitmap.compress(Bitmap.CompressFormat.PNG, 50, it)
}
}
GetApplication 是一种为 ViewModel 提供上下文的方法,它是 AndroidViewModel 的一部分 稍后,如果你想阅读它:

viewModelScope.launch(Dispatchers.IO) {
val savedBitmap = BitmapFactory.decodeStream(
getApplication<App>().openFileInput(filename).readBytes().inputStream()
)
}

确保使用 WEBP 作为媒体格式,以同样的质量节省更多的空间:

fun saveImage(context: Context, bitmap: Bitmap, name: String): String {
context.openFileOutput(name, Context.MODE_PRIVATE).use { fos ->
bitmap.compress(Bitmap.CompressFormat.WEBP, 25, fos)
}
return context.filesDir.absolutePath
}

此代码将支持 UptoAndroid11 + 。

< strong > 在片段/活动上声明一个权限结果 我正在使用一个片段

private val askPermissions =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
val isGranted = permissions.entries.all {
it.value == true
}


if (isGranted) {
viewModel.saveImageToGallery(requireContext().contentResolver,
getString(R.string.my_deshi_qr_code),
bitmap)
} else {
askForWritePermission()
}
}

触发事件

bindingView.downloadQrButton.setOnClickListener {
requestPermission()
}
private fun requestPermission() {
val minSDK = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
val isWritePermissionGranted = (ContextCompat.checkSelfPermission(requireContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) || minSDK


if (!isWritePermissionGranted) {
askForWritePermission()
} else {
viewModel.saveImageToGallery(requireContext().contentResolver,
getString(R.string.my_deshi_qr_code),
bitmap)
}
}




private fun askForWritePermission() {
askPermissions.launch(listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE).toTypedArray())
}

视图模型

fun saveImageToGallery(contentResolver: ContentResolver, imageName: String, bitmap: Bitmap?) {
val imageUri: Uri?
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "$imageName.jpg")
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
bitmap?.let {
put(MediaStore.Images.Media.WIDTH, bitmap.width)
put(MediaStore.Images.Media.HEIGHT, bitmap.height)
}
}


imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH,
Environment.DIRECTORY_PICTURES + File.separator.toString() + "YourFolderName")
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
} else {
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
}


try {
val uri = contentResolver.insert(imageUri, contentValues)
val fos = uri?.let { contentResolver.openOutputStream(it) }
bitmap?.compress(Bitmap.CompressFormat.JPEG, 100, fos)
Objects.requireNonNull(fos)
_showMessage.postValue(Event("Image Saved"))
} catch (e: Exception) {
_showMessage.postValue(Event("Image Not Saved \n$e"))
}
}