Konwertuj mapę bitową na plik


127

Rozumiem, że za pomocą BitmapFactorymożna przekonwertować plik na mapę bitową, ale czy istnieje sposób na przekonwertowanie obrazu mapy bitowej na plik?

Odpowiedzi:


82

Spróbuj tego:

bitmap.compress(Bitmap.CompressFormat.PNG, quality, outStream);

Zobacz


10
Ale ja nie chcę FileOutputStreamtylko pliku. Czy jest na to sposób?
Mxyk

9
A co to jest quality?
Mxyk,

1
FileOutputStream to sposób, w jaki piszesz do pliku. Zobacz developer.android.com/reference/java/io/FileOutputStream.html
Torid

Naprawdę nie wiem, co masz na myśli ... Używasz FileOutputStream do tworzenia pliku. Możesz też użyć instancji File (jak w przykładzie amsiddh), aby utworzyć FileOutputStream, do którego możesz wyeksportować bitmapę. Dzięki temu (instancja File, rzeczywisty plik w systemie plików i FileOutputStream) powinieneś mieć wszystko, czego potrzebujesz, nie?
P.Melch

235

Mam nadzieję, że to ci pomoże:

//create a file to write bitmap data
File f = new File(context.getCacheDir(), filename);
f.createNewFile();

//Convert bitmap to byte array
Bitmap bitmap = your bitmap;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();

//write the bytes in file
FileOutputStream fos = new FileOutputStream(f);
fos.write(bitmapdata);
fos.flush();
fos.close();

36
nie zapomnij opróżnić i zamknąć strumienia wyjściowego :)
Ben Holland

3
Kod działa dobrze, ale metoda kompresji zajmuje dużo czasu. Jakieś obejście?
Shail Adi

10
na wypadek, gdyby ludzie zastanawiali się, czym jest wskaźnik jakości Jest to skala od 0 do 100, wysoka podobnie do eksportu w Photoshopie itp. Jak wspomniano, jest ignorowana dla PNG, ale możesz chcieć użyć CompressFormat.JPEG. Jak w google doco: wskazówka do kompresora, 0-100. 0 oznacza kompresję dla małego rozmiaru, 100 oznacza kompresję dla maksymalnej jakości. Niektóre formaty, takie jak PNG, który jest bezstratny, ignorują ustawienie jakości
wired00

3
Czy plik z katalogu pamięci podręcznej zostanie automatycznie usunięty?
Shajeel Afzal

1
Po co używać a ByteArrayOutputStream, pobrać z tego tablicę bajtów, a następnie zapisać tablicę do a FileOutputStream? Dlaczego nie tylko FileOutputStreamw Bitmap.compressśrodku?
InsanityOnABun

39
File file = new File("path");
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
os.close();

java.io.FileNotFoundException: / path: open failed: EROFS (system plików tylko do odczytu)
Prasad

1
@Prasad upewnij się, że przekazujesz poprawną ścieżkę do swojego File()konstruktora.
fraggjkee,

Ma domyślną ścieżkę?
Nathiel Barros

idealne rozwiązanie
Xan

co to jest bitmap.compress? dlaczego ta funkcja daje format JPEG? a co to jest 100?
roghayeh hosseini

11

Konwersja Bitmapdo Filemusi być wykonana w tle (NIE W GŁÓWNYM NITKU), zawiesza interfejs użytkownika, szczególnie jeśli bitmapbył duży

File file;

public class fileFromBitmap extends AsyncTask<Void, Integer, String> {

    Context context;
    Bitmap bitmap;
    String path_external = Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg";

    public fileFromBitmap(Bitmap bitmap, Context context) {
        this.bitmap = bitmap;
        this.context= context;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // before executing doInBackground
        // update your UI
        // exp; make progressbar visible
    }

    @Override
    protected String doInBackground(Void... params) {

        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        file = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg");
        try {
            FileOutputStream fo = new FileOutputStream(file);
            fo.write(bytes.toByteArray());
            fo.flush();
            fo.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }


    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        // back to main thread after finishing doInBackground
        // update your UI or take action after
        // exp; make progressbar gone

         sendFile(file);

    }
}

Nazywam to

new fileFromBitmap(my_bitmap, getApplicationContext()).execute();

MUSISZ użyć pliku filein onPostExecute.

Aby zmienić katalog filedo zapisania w linii zastępowania pamięci podręcznej:

 file = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg");

z :

file  = new File(context.getCacheDir(), "temporary_file.jpg");

1
Czasami powoduje to wyjątek „FileNotFound”. Nadal badam, dlaczego tak się dzieje. Również może powinieneś rozważyć zapisanie wile z rozszerzeniem .webp, który jest o około 40-50% mniejszy niż JPG
Pranaysharma

Przypuszczam, że wyjątek „FileNotFound” występuje, gdy zapisywanie w pamięci podręcznej jest w jakiś sposób czyszczone (istnieje wiele sposobów na wyczyszczenie pamięci podręcznej, może przez inną aplikację) @Pranaysharma
Mohamed Embaby

Nie brakuje execute () po konstruktorze: new fileFromBitmap (my_bitmap, getApplicationContext ()); ?
Andrea Leganza

1
@AndreaLeganza tak, brakowało, zredagowałem odpowiedź, dzięki tobie.
Mohamed Embaby

Utrzymanie kontekstu w AsyncTask może prowadzić do wycieków pamięci !!! youtube.com/watch?v=bNM_3YkK2Ws
slaviboy

2

Większość odpowiedzi jest zbyt długich lub zbyt krótkich i nie spełnia celu. Dla tych, którzy szukają kodu Java lub Kotlin do konwersji bitmapy na obiekt pliku. Oto szczegółowy artykuł, który napisałem na ten temat. Konwertuj mapę bitową na plik w systemie Android

public static File bitmapToFile(Context context,Bitmap bitmap, String fileNameToSave) { // File name like "image.png"
        //create a file to write bitmap data
        File file = null;
        try {
            file = new File(Environment.getExternalStorageDirectory() + File.separator + fileNameToSave);
            file.createNewFile();

//Convert bitmap to byte array
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 0 , bos); // YOU can also save it in JPEG
            byte[] bitmapdata = bos.toByteArray();

//write the bytes in file
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(bitmapdata);
            fos.flush();
            fos.close();
            return file;
        }catch (Exception e){
            e.printStackTrace();
            return file; // it will return null
        }
    }

0

Mam nadzieję, że to ci pomoże

class MainActivity: AppCompatActivity () {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Get the bitmap from assets and display into image view
    val bitmap = assetsToBitmap("tulip.jpg")
    // If bitmap is not null
    bitmap?.let {
        image_view_bitmap.setImageBitmap(bitmap)
    }


    // Click listener for button widget
    button.setOnClickListener{
        if(bitmap!=null){
            // Save the bitmap to a file and display it into image view
            val uri = bitmapToFile(bitmap)
            image_view_file.setImageURI(uri)

            // Display the saved bitmap's uri in text view
            text_view.text = uri.toString()

            // Show a toast message
            toast("Bitmap saved in a file.")
        }else{
            toast("bitmap not found.")
        }
    }
}


// Method to get a bitmap from assets
private fun assetsToBitmap(fileName:String):Bitmap?{
    return try{
        val stream = assets.open(fileName)
        BitmapFactory.decodeStream(stream)
    }catch (e:IOException){
        e.printStackTrace()
        null
    }
}


// Method to save an bitmap to a file
private fun bitmapToFile(bitmap:Bitmap): Uri {
    // Get the context wrapper
    val wrapper = ContextWrapper(applicationContext)

    // Initialize a new file instance to save bitmap object
    var file = wrapper.getDir("Images",Context.MODE_PRIVATE)
    file = File(file,"${UUID.randomUUID()}.jpg")

    try{
        // Compress the bitmap and save in jpg format
        val stream:OutputStream = FileOutputStream(file)
        bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream)
        stream.flush()
        stream.close()
    }catch (e:IOException){
        e.printStackTrace()
    }

    // Return the saved bitmap uri
    return Uri.parse(file.absolutePath)
}

}

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.