Save bitmap to location

前端 未结 19 2307
悲哀的现实
悲哀的现实 2020-11-22 00:20

I am working on a function to download an image from a web server, display it on the screen, and if the user wishes to keep the image, save it on the SD card in a certain fo

相关标签:
19条回答
  • 2020-11-22 00:54

    After Android 4.4 Kitkat, and as of 2017 share of Android 4.4 and less is about 20% and decreasing, it's not possible to save to SD card using File class and getExternalStorageDirectory() method. This method returns your device internal memory and images save visible to every app. You can also save images only private to your app and to be deleted when user deletes your app with openFileOutput() method.

    Starting with Android 6.0, you can format your SD card as an internal memory but only private to your device.(If you format SD car as internal memory, only your device can access or see it's contents) You can save to that SD card using other answers but if you want to use a removable SD card you should read my answer below.

    You should use Storage Access Framework to get uri to folder onActivityResult method of activity to get folder selected by user, and add retreive persistiable permission to be able to access folder after user restarts the device.

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

    Now, save save folder to shared preferences not to ask user to select folder every time you want to save an image.

    You should use DocumentFile class to save your image, not File or ParcelFileDescriptor, for more info you can check this thread for saving image to SD card with compress(CompressFormat.JPEG, 100, out); method and DocumentFile classes.

    0 讨论(0)
  • 2020-11-22 00:56
    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) {
    
    }
    
    0 讨论(0)
  • 2020-11-22 00:57

    I know this question is old, but now we can achieve the same result without WRITE_EXTERNAL_STORAGE permission. Instead of we can use File provider.

    private fun storeBitmap(bitmap: Bitmap, file: File){
            requireContext().getUriForFile(file)?.run {
                requireContext().contentResolver.openOutputStream(this)?.run {
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, this)
                    close()
                }
            }
        }
    

    How to retrieve file from provider ?

    fun Context.getUriForFile(file: File): Uri? {
            return FileProvider.getUriForFile(
                this,
                "$packageName.fileprovider",
                file
            )
        }
    

    Also do not forget register your provider in Android manifest

    <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"/>
        </provider>
    
    0 讨论(0)
  • 2020-11-22 00:58

    Some formats, like PNG which is lossless, will ignore the quality setting.

    0 讨论(0)
  • 2020-11-22 00:59

    I would also like to save a picture. But my problem(?) is that I want to save it from a bitmap that ive drawed.

    I made it like this:

     @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();
                }
    
     }
    
    0 讨论(0)
  • 2020-11-22 00:59

    Make sure the directory is created before you call bitmap.compress:

    new File(FileName.substring(0,FileName.lastIndexOf("/"))).mkdirs();
    
    0 讨论(0)
提交回复
热议问题