我正在研究从web服务器下载图像的功能,在屏幕上显示它,如果用户希望保持图像,将其保存在SD卡的某个文件夹中。有没有一种简单的方法来获取位图并将其保存到我选择的SD卡文件夹中?
我的问题是,我可以下载图像,在屏幕上显示为位图。我能够找到的将图像保存到特定文件夹的唯一方法是使用FileOutputStream,但这需要一个字节数组。我不知道如何转换(如果这是正确的方式)从位图到字节数组,所以我可以使用FileOutputStream写入数据。
我的另一个选择是使用MediaStore:
MediaStore.Images.Media.insertImage(getContentResolver(), bm,
barcodeNumber + ".jpg Card Image", barcodeNumber + ".jpg Card Image");
它可以很好地保存到SD卡,但不允许您自定义文件夹。
保存位图到您的图库没有压缩。
private File saveBitMap(Context context, Bitmap Final_bitmap) {
File pictureFileDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Your Folder Name");
if (!pictureFileDir.exists()) {
boolean isDirectoryCreated = pictureFileDir.mkdirs();
if (!isDirectoryCreated)
Log.i("TAG", "Can't create directory to save the image");
return null;
}
String filename = pictureFileDir.getPath() + File.separator + System.currentTimeMillis() + ".jpg";
File pictureFile = new File(filename);
try {
pictureFile.createNewFile();
FileOutputStream oStream = new FileOutputStream(pictureFile);
Final_bitmap.compress(Bitmap.CompressFormat.PNG, 100, oStream);
oStream.flush();
oStream.close();
Toast.makeText(Full_Screen_Activity.this, "Save Image Successfully..", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Log.i("TAG", "There was an issue saving the image.");
}
scanGallery(context, pictureFile.getAbsolutePath());
return pictureFile;
}
private void scanGallery(Context cntx, String path) {
try {
MediaScannerConnection.scanFile(cntx, new String[]{path}, null, new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Toast.makeText(Full_Screen_Activity.this, "Save Image Successfully..", Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
e.printStackTrace();
Log.i("TAG", "There was an issue scanning gallery.");
}
}
在Android 4.4 Kitkat之后,截至2017年,Android 4.4及以下的份额约为20%并且正在下降,使用File类和getExternalStorageDirectory()方法保存到SD卡是不可能的。这个方法返回你的设备内部内存和图像保存为每个应用程序可见。你也可以只保存你的应用程序私有的图像,当用户使用openFileOutput()方法删除你的应用程序时删除。
从Android 6.0开始,您可以将SD卡格式化为内部内存,但只能对您的设备私有。(如果你格式化SD车作为内部存储器,只有你的设备可以访问或看到它的内容)你可以使用其他答案保存到SD卡,但如果你想使用一个可移动的SD卡,你应该阅读下面我的回答。
您应该使用存储访问框架获取uri到activity的onActivityResult方法来获取用户选择的文件夹,并添加检索持久权限,以便用户重新启动设备后能够访问文件夹。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
// selectDirectory() invoked
if (requestCode == REQUEST_FOLDER_ACCESS) {
if (data.getData() != null) {
Uri treeUri = data.getData();
tvSAF.setText("Dir: " + data.getData().toString());
currentFolder = treeUri.toString();
saveCurrentFolderToPrefs();
// grantUriPermission(getPackageName(), treeUri,
// Intent.FLAG_GRANT_READ_URI_PERMISSION |
// Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
final int takeFlags = data.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Check for the freshest data.
getContentResolver().takePersistableUriPermission(treeUri, takeFlags);
}
}
}
}
现在,保存保存文件夹到共享首选项,而不是每次你想保存图像时都要求用户选择文件夹。
你应该使用DocumentFile类来保存你的图像,而不是File或ParcelFileDescriptor,要了解更多信息,你可以检查这个线程保存图像到SD卡压缩(CompressFormat.JPEG, 100, out);方法和DocumentFile类。
Bitmap bbicon;
bbicon=BitmapFactory.decodeResource(getResources(),R.drawable.bannerd10);
//ByteArrayOutputStream baosicon = new ByteArrayOutputStream();
//bbicon.compress(Bitmap.CompressFormat.PNG,0, baosicon);
//bicon=baosicon.toByteArray();
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
OutputStream outStream = null;
File file = new File(extStorageDirectory, "er.PNG");
try {
outStream = new FileOutputStream(file);
bbicon.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
} catch(Exception e) {
}
您想要保存位图到您选择的目录。我做了一个ImageWorker库,使用户能够加载,保存和转换位图/绘图/base64图像。
最小SDK - 14
先决条件
保存文件需要WRITE_EXTERNAL_STORAGE权限。
检索文件需要READ_EXTERNAL_STORAGE权限。
储蓄位图/ Drawable Base64
ImageWorker.to(context).
directory("ImageWorker").
subDirectory("SubDirectory").
setFileName("Image").
withExtension(Extension.PNG).
save(sourceBitmap,85)
加载位图
val bitmap: Bitmap? = ImageWorker.from(context).
directory("ImageWorker").
subDirectory("SubDirectory").
setFileName("Image").
withExtension(Extension.PNG).
load()
实现
添加依赖关系
在项目级别Gradle
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
在应用级Gradle
dependencies {
implementation 'com.github.ihimanshurawat:ImageWorker:0.51'
}
你可以在https://github.com/ihimanshurawat/ImageWorker/blob/master/README.md上阅读更多