Zapisz bitmapę do lokalizacji

Pracuję nad funkcją pobierania obrazu z serwera www, wyświetlania go na ekranie, a jeśli użytkownik chce zachować obraz, zapisz go na karcie SD w określonym folderze. Czy istnieje łatwy sposób na pobranie bitmapy i zapisanie jej na karcie SD w wybranym przeze mnie folderze?

Mój problem polega na tym, że mogę pobrać obraz, wyświetlić go na ekranie jako bitmapę. Jedynym sposobem, w jaki udało mi się znaleźć, aby zapisać obraz do określonego folderu, jest użycie FileOutputStream, ale wymaga to tablica bajtów. Nie jestem pewien, jak przekonwertować (jeśli jest to w ogóle właściwy sposób) z bitmapy do tablicy bajtów, więc mogę użyć strumienia plików do zapisu danych.

Inną opcją jaką mam jest użycie MediaStore:

MediaStore.Images.Media.insertImage(getContentResolver(), bm,
    barcodeNumber + ".jpg Card Image", barcodeNumber + ".jpg Card Image");

Który działa dobrze, aby zapisać na karcie SD, ale nie pozwala na dostosowanie folderu.

Author: Sergey Glotov, 2009-03-16

16 answers

try (FileOutputStream 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 (IOException e) {
    e.printStackTrace();
}
 823
Author: Ulrich Scheller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-10 16:57:34

Należy użyć metody Bitmap.compress(), aby zapisać bitmapę jako plik. Skompresuje (jeśli format na to pozwala) Twoje zdjęcie i wypchnie je do strumienia wyjściowego.

Oto przykład instancji bitmapowej uzyskanej przez getImageBitmap(myurl), która może być skompresowana jako JPEG ze stopniem kompresji 85%:

// 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());
 124
Author: JoaquinG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-04 19:46:31
outStream = new FileOutputStream(file);

Wyrzuci wyjątek bez uprawnień w AndroidManifest.xml (przynajmniej w os2.2):

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 34
Author: user996042,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-31 13:26:51

Wewnątrz 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();
}
 23
Author: Alessandro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-14 14:22:38

Niektóre formaty, takie jak PNG, który jest bezstratny, zignorują ustawienie jakości.

 13
Author: shinydev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-09 13:53:48

Dlaczego nie wywołać metody Bitmap.compress z 100 (co brzmi jakby była bezstratna)?

 8
Author: TofuBeer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-19 12:04:29
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) {

}
 8
Author: Ashish Anand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-25 19:49:48

Oto przykładowy kod do zapisania bitmapy do pliku:

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

Teraz wywołaj tę funkcję, aby zapisać bitmapę w pamięci wewnętrznej.

File newfile = savebitmap(bitmap);

Mam nadzieję, że ci to pomoże. Szczęśliwego kodowania życia.
 7
Author: A-Droid Tech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-02 09:41:55

Chciałbym również zapisać zdjęcie. Ale mój problem(?) jest to, że chcę go zapisać z bitmapy, które narysowałem.

Zrobiłem tak:

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

 }
 6
Author: user511895,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-07 07:45:58

Sposób, w jaki znalazłem wysyłanie PNG i przezroczystości.

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")));
 5
Author: JulienGenoud,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-08 09:52:47

Hej, podaj nazwę .bmp

Zrób to:

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**")

To będzie brzmiało, że im tylko wygłupiać ale spróbuj raz to zostanie zapisany w BMP foramt..Cheers

 1
Author: Mayank Saini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-22 11:47:39

Utwórz miniaturę wideo dla filmu. Może zwrócić wartość null, Jeśli film jest uszkodzony lub format nie jest obsługiwany.

private void makeVideoPreview() {
    Bitmap thumbnail = ThumbnailUtils.createVideoThumbnail(videoAbsolutePath, MediaStore.Images.Thumbnails.MINI_KIND);
    saveImage(thumbnail);
}

Aby zapisać bitmapę w sdcard użyj następującego kodu

Store Image

private void storeImage(Bitmap image) {
    File pictureFile = getOutputMediaFile();
    if (pictureFile == null) {
        Log.d(TAG,
                "Error creating media file, check storage permissions: ");// e.getMessage());
        return;
    } 
    try {
        FileOutputStream fos = new FileOutputStream(pictureFile);
        image.compress(Bitmap.CompressFormat.PNG, 90, fos);
        fos.close();
    } catch (FileNotFoundException e) {
        Log.d(TAG, "File not found: " + e.getMessage());
    } catch (IOException e) {
        Log.d(TAG, "Error accessing file: " + e.getMessage());
    }  
}

Aby uzyskać ścieżkę do przechowywania obrazu

/** Create a File for saving an image or video */
private  File getOutputMediaFile(){
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this. 
    File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
            + "/Android/data/"
            + getApplicationContext().getPackageName()
            + "/Files"); 

    // This location works best if you want the created images to be shared
    // between applications and persist after your app has been uninstalled.

    // Create the storage directory if it does not exist
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            return null;
        }
    } 
    // Create a media file name
    String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
    File mediaFile;
        String mImageName="MI_"+ timeStamp +".jpg";
        mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);  
    return mediaFile;
} 
 1
Author: MashukKhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-28 13:17:34

Upewnij się, że katalog jest utworzony przed wywołaniem bitmap.compress:

new File(FileName.substring(0,FileName.lastIndexOf("/"))).mkdirs();
 0
Author: user5480949,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-18 19:44:31

Właściwie nie odpowiedź, ale komentarz. Jestem na komputerze Mac z uruchomionym środowiskiem emulatora i otrzymuję java.io.IOException: Permission denied-error z tym kodem:

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

Dodałem również uses-permission android.pozwolenie.WRITE_EXTERNAL_STORAGE do pliku manifestu (jak zauważyli inni).

 0
Author: stian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-11 17:26:01

// |==| Tworzenie pliku PNG z bitmapy:

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

// |==| Pobierz Bimap z pliku:

Bitmap getBmjFrmFylFnc(String pthAndFylTtlVar)
{
    return BitmapFactory.decodeFile(pthAndFylTtlVar);
}
 0
Author: Sujay U N,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-29 19:22:48

Po Android 4.4 Kitkat, a od 2017 udział Androida 4.4 i less wynosi około 20% i maleje, nie jest możliwe zapisanie na karcie SD przy użyciu klasy File i metody getExternalStorageDirectory(). Ta metoda zwraca wewnętrzną pamięć urządzenia i obrazy zapisane w każdej aplikacji. Możesz również zapisywać obrazy tylko prywatne w aplikacji i do usunięcia, gdy użytkownik usunie aplikację za pomocą metody openFileOutput().

Począwszy od Androida 6.0, możesz sformatować kartę SD jako pamięć wewnętrzną, ale tylko prywatną do twojego urządzenie.(Jeśli sformatujesz samochód SD jako pamięć wewnętrzną, tylko Twoje urządzenie może uzyskać dostęp lub zobaczyć jego zawartość) możesz zapisać na tej karcie SD za pomocą innych odpowiedzi, ale jeśli chcesz użyć wymiennej karty SD, powinieneś przeczytać moją odpowiedź poniżej.

Powinieneś użyć Storage Access Framework, aby uzyskać uri do folderu onActivityResult metoda aktywności, aby uzyskać folder wybrany przez użytkownika, i dodać retreive persistiable permission, aby mieć dostęp do folderu po ponownym uruchomieniu urządzenia przez użytkownika.

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

            }
        }
    }
}

Teraz, zapisz Zapisz folder w preferencjach udostępnionych, aby nie prosić użytkownika o wybranie folderu za każdym razem, gdy chcesz zapisać obraz.

Powinieneś użyć klasy DocumentFile do zapisania obrazu, a nie File lub ParcelFileDescriptor, aby uzyskać więcej informacji możesz sprawdzić ten wątek do zapisania obrazu na kartę SD za pomocą metody compress(CompressFormat.JPEG, 100, out); i klas DocumentFile.

 0
Author: Thracian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-15 11:57:30