将位图保存到位置
我正在开发一项function,从networking服务器上下载图像,将其显示在屏幕上,如果用户希望保留图像,请将其保存在SD卡中的某个文件夹中。 有一个简单的方法来获取位图,并将其保存到我select的文件夹中的SD卡?
我的问题是,我可以下载图像,显示在屏幕上的位图。 我已经能够find将图像保存到特定文件夹的唯一方法是使用FileOutputStream,但需要一个字节数组。 我不知道如何转换(如果这是正确的方式)从位图到字节数组,所以我可以使用FileOutputStream来写入数据。
我有另一个select是使用MediaStore:
MediaStore.Images.Media.insertImage(getContentResolver(), bm, barcodeNumber + ".jpg Card Image", barcodeNumber + ".jpg Card Image");
这工作正常,以保存到SD卡,但不允许您自定义文件夹。
FileOutputStream out = null; try { out = new FileOutputStream(filename); bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance // PNG is a lossless format, the compression factor (100) is ignored } catch (Exception e) { e.printStackTrace(); } finally { try { if (out != null) { out.close(); } } catch (IOException e) { e.printStackTrace(); } }
您应该使用Bitmap.compress()
方法将位图保存为文件。 它将压缩(如果使用的格式允许)您的图片,并将其推入OutputStream。
以下是通过getImageBitmap(myurl)
获取的Bitmap实例的一个示例,该实例可以压缩为85%的JPEG压缩率:
// Assume block needs to be inside a Try/Catch block. String path = Environment.getExternalStorageDirectory().toString(); OutputStream fOut = null; Integer counter = 0; File file = new File(path, "FitnessGirl"+counter+".jpg"); // the File to save , append increasing numeric counter to prevent files from getting overwritten. fOut = new FileOutputStream(file); Bitmap pictureBitmap = getImageBitmap(myurl); // obtaining the Bitmap pictureBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fOut); // saving the Bitmap to a file compressed as a JPEG with 85% compression rate fOut.flush(); // Not really required fOut.close(); // do not forget to close the stream MediaStore.Images.Media.insertImage(getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
outStream = new FileOutputStream(file);
将在AndroidManifest.xml中(至less在os2.2中)未经许可引发exception:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
在onActivityResult
里面:
String filename = "pippo.png"; File sd = Environment.getExternalStorageDirectory(); File dest = new File(sd, filename); Bitmap bitmap = (Bitmap)data.getExtras().get("data"); try { FileOutputStream out = new FileOutputStream(dest); bitmap.compress(Bitmap.CompressFormat.PNG, 90, out); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); }
有些格式,如PNG,无损,将忽略质量设置。
为什么不用100调用Bitmap.compress
方法(这听起来像是无损)?
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) { }
我也想保存一张图片。 但是我的问题(?)是我想要从一个位图中保存它。
我是这样做的:
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.save_sign: myView.save(); break; } return false; } public void save() { String filename; Date date = new Date(0); SimpleDateFormat sdf = new SimpleDateFormat ("yyyyMMddHHmmss"); filename = sdf.format(date); try{ String path = Environment.getExternalStorageDirectory().toString(); OutputStream fOut = null; File file = new File(path, "/DCIM/Signatures/"+filename+".jpg"); fOut = new FileOutputStream(file); mBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fOut); fOut.flush(); fOut.close(); MediaStore.Images.Media.insertImage(getContentResolver() ,file.getAbsolutePath(),file.getName(),file.getName()); }catch (Exception e) { e.printStackTrace(); } }
我发现发送PNG和透明度的方式。
String file_path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/CustomDir"; File dir = new File(file_path); if(!dir.exists()) dir.mkdirs(); String format = new SimpleDateFormat("yyyyMMddHHmmss", java.util.Locale.getDefault()).format(new Date()); File file = new File(dir, format + ".png"); FileOutputStream fOut; try { fOut = new FileOutputStream(file); yourbitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut); fOut.flush(); fOut.close(); } catch (Exception e) { e.printStackTrace(); } Uri uri = Uri.fromFile(file); Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.setType("image/*"); intent.putExtra(android.content.Intent.EXTRA_SUBJECT, ""); intent.putExtra(android.content.Intent.EXTRA_TEXT, ""); intent.putExtra(Intent.EXTRA_STREAM, uri); startActivity(Intent.createChooser(intent,"Sharing something")));
以下是将位图保存到文件的示例代码:
public static File savebitmap(Bitmap bmp) throws IOException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.JPEG, 60, bytes); File f = new File(Environment.getExternalStorageDirectory() + File.separator + "testimage.jpg"); f.createNewFile(); FileOutputStream fo = new FileOutputStream(f); fo.write(bytes.toByteArray()); fo.close(); return f; }
现在调用这个函数把位图保存到内存中。
File newfile = savebitmap(bitmap)
;
我希望这会帮助你。 快乐的编码生活。
嘿,把名字给.bmp
做这个:
ByteArrayOutputStream bytes = new ByteArrayOutputStream(); _bitmapScaled.compress(Bitmap.CompressFormat.PNG, 40, bytes); //you can create a new file name "test.BMP" in sdcard folder. File f = new File(Environment.getExternalStorageDirectory() + File.separator + "**test.bmp**")
这听起来是IM只是愚蠢的,但尝试一旦它会得到保存在bmp文件..干杯
确保在调用bitmap.compress
之前创build目录:
new File(FileName.substring(0,FileName.lastIndexOf("/"))).mkdirs();
其实不是一个答案,而是一个评论。 我在运行模拟器环境的Mac上,并得到一个java.io.IOException:权限被拒绝 – 与此代码错误:
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { Log.d("DEBUG", "onActivityResult called"); super.onActivityResult(requestCode, resultCode, imageReturnedIntent); if(requestCode == 0 && resultCode == RESULT_OK) { Log.d("DEBUG", "result is ok"); try{ Bitmap map = (Bitmap) imageReturnedIntent.getExtras().get("data"); File sd = new File(Environment.getExternalStorageDirectory(), "test.png"); sd.mkdirs(); sd.createNewFile(); FileOutputStream out = new FileOutputStream(sd); map.compress(Bitmap.CompressFormat.PNG, 90, out); out.flush(); out.close(); } catch(FileNotFoundException e){ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
我也添加了使用权限android.permission.WRITE_EXTERNAL_STORAGE清单文件(正如其他人所指出的)。
// | == | 从位图创build一个PNG文件:
void devImjFylFnc(String pthAndFylTtlVar, Bitmap iptBmjVar) { try { FileOutputStream fylBytWrtrVar = new FileOutputStream(pthAndFylTtlVar); iptBmjVar.compress(Bitmap.CompressFormat.PNG, 100, fylBytWrtrVar); fylBytWrtrVar.close(); } catch (Exception errVar) { errVar.printStackTrace(); } }
// | == | 从文件获取Bimap:
Bitmap getBmjFrmFylFnc(String pthAndFylTtlVar) { return BitmapFactory.decodeFile(pthAndFylTtlVar); }
在Android 4.4 Kitkat之后,截至2017年Android 4.4及更低版本的份额降低了20%左右,使用File
类和getExternalStorageDirectory()
方法无法保存到SD卡。 此方法会将设备的内部内存和图像保存为每个应用可见。 您还可以将图像保存为专用于您的应用程序,并在用户使用openFileOutput()
方法删除应用程序时将其删除。
从Android 6.0开始,您可以将SD卡格式化为内部存储器,但只能用于您的设备(如果将SD卡格式化为内部存储器,则只有您的设备可以访问或查看其内容)。其他答案,但如果你想使用一个可移动的SD卡,你应该阅读我的答案在下面。
您应该使用Storage Access Framework来获取uri文件夹的onActivityResult
活动方法来获取用户select的文件夹,并且在用户重新启动设备之后添加retreive persistiable权限以便能够访问文件夹。
@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); } } } }
现在,将保存文件夹保存到共享首选项,而不是要求用户在每次要保存图像时select文件夹。
你应该使用DocumentFile
类来保存你的图像,而不是File
或ParcelFileDescriptor
,更多的信息,你可以检查这个线程保存图像到SD卡的compress(CompressFormat.JPEG, 100, out);
方法和DocumentFile
类。