Converter bitmap em arquivo

127

Entendo que o uso BitmapFactorypode converter um arquivo em um bitmap, mas existe alguma maneira de converter uma imagem de bitmap em um arquivo?

Mxyk
fonte

Respostas:

82

Tente o seguinte:

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

Veja isso

P.Melch
fonte
10
Mas eu não quero um FileOutputStream, apenas um arquivo. Existe uma maneira de contornar isso?
Mxyk
9
Além disso, o que é quality?
Mxyk
1
Um FileOutputStream é como você escreve em um arquivo. Veja developer.android.com/reference/java/io/FileOutputStream.html
Torid
Eu realmente não sei o que você quer dizer ... Você usa um FileOutputStream para criar um arquivo. E você pode usar uma instância de arquivo (como no exemplo de amsiddh) para criar um FileOutputStream para o qual você pode exportar o bitmap. Com isso (uma instância de arquivo, um arquivo real no sistema de arquivos e no FileOutputStream), você deve ter tudo o que precisa, não?
P.Melch
235

Espero que ajude você:

//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();
amsiddh
fonte
36
não se esqueça de flush e fechar o fluxo de saída :)
Ben Holland
3
O código funciona bem, mas o método de compactação leva muito tempo. Alguma solução?
quer
10
caso as pessoas estejam se perguntando o que é métrica de qualidade. É uma escala de 0 a 100, alta semelhante à exportação do photoshop etc. Como mencionado, é ignorado para PNG, mas você pode usar CompressFormat.JPEG. Conforme google doco: Dica para o compressor, 0-100. 0 significa comprimir para tamanho pequeno, 100 significa comprimir para qualidade máxima. Alguns formatos, como PNG, que é sem perdas, irá ignorar a configuração de qualidade
wired00
3
O arquivo do diretório de cache será excluído automaticamente?
Shajeel Afzal 01/08/2015
1
Por que usar a ByteArrayOutputStream, obter uma matriz de bytes disso e depois gravar a matriz em a FileOutputStream? Por que não apenas o FileOutputStreamin Bitmap.compress?
InsanityOnABun
39
File file = new File("path");
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
os.close();
fraggjkee
fonte
java.io.FileNotFoundException: / path: open falhou: EROFS (sistema de arquivos somente leitura)
Prasad
1
@ Prasad certifique-se de passar um caminho correto para o seu File()construtor.
fraggjkee
Tem um caminho padrão?
Nathiel Barros
solução perfeita
Xan
o que é bitmap.compress? por que essa função fornece formato JPEG? e o que é 100?
hosseini roghayeh
11

A conversão Bitmappara Fileprecisa ser feita em segundo plano (NÃO NA LINHA PRINCIPAL) trava a interface do usuário, especialmente se ela bitmapfor grande

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

    }
}

Chamando

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

Você deve usar o fileno onPostExecute.

Para alterar o diretório filea ser armazenado no cache, substitua a linha:

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

com:

file  = new File(context.getCacheDir(), "temporary_file.jpg");
Mohamed Embaby
fonte
1
Isso me dá a exceção "FileNotFound" algumas vezes. Ainda estou investigando por que isso acontece. Também talvez você deve considerar salvar o wile com .webp extensão de seu tamanho em torno de 40-50% menor do que JPG
Pranaysharma
Suponho "FileNotFound" exceção acontece quando salvar para o cache, em seguida, de alguma forma cache é limpo (há muitas maneiras de obter o cache apuradas, talvez por outra aplicação) @Pranaysharma
Mohamed Embaby
Não está faltando o execute () após o construtor: new fileFromBitmap (my_bitmap, getApplicationContext ()); ?
Andrea Leganza 10/10
1
@AndreaLeganza sim, estava faltando, editei minha resposta, graças a você.
Mohamed Embaby 10/10
Manter o Contex no AsyncTask pode levar a vazamentos de memória !!! youtube.com/watch?v=bNM_3YkK2Ws
slaviboy 03/06
2

A maioria das respostas é muito longa ou muito curta, não cumprindo o objetivo. Para aqueles que procuram código Java ou Kotlin para converter bitmap em objeto de arquivo. Aqui está o artigo detalhado que escrevi sobre o tópico. Converter Bitmap em arquivo no 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
        }
    }
Asad Ali Choudhry
fonte
0

Espero que isso ajude você

classe 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)
}

}

brkcnplt
fonte