将位图保存到位置

我正在开发一项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类来保存你的图像,而不是FileParcelFileDescriptor ,更多的信息,你可以检查这个线程保存图像到SD卡的compress(CompressFormat.JPEG, 100, out); 方法和DocumentFile类。