Convertir mapa de bits a archivo

127

Entiendo que usar BitmapFactorypuede convertir un archivo en un mapa de bits, pero ¿hay alguna forma de convertir una imagen de mapa de bits en un archivo?

Mxyk
fuente

Respuestas:

82

Prueba esto:

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

Mira esto

P.Melch
fuente
10
Pero no quiero un FileOutputStream, solo un archivo. ¿Hay alguna forma de evitar esto?
Mxyk
9
Además, ¿qué es quality?
Mxyk
1
Un FileOutputStream es cómo se escribe en un archivo. Ver developer.android.com/reference/java/io/FileOutputStream.html
Torid el
Realmente no sé a qué te refieres ... Usas un FileOutputStream para crear un archivo. Y puede usar una instancia de archivo (como en el ejemplo de amsiddh) para crear un FileOutputStream al que puede exportar el mapa de bits. Con eso (una instancia de archivo, un archivo real en el sistema de archivos y FileOutputStream) debería tener todo lo que necesita, ¿no?
P.Melch
235

Espero que te ayude:

//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
fuente
36
no te olvides de vaciar y cerrar tu flujo de salida :)
Ben Holland
3
El código funciona bien, pero el método de compresión lleva mucho tiempo. Cualquier trabajo alrededor?
Shail Adi
10
en caso de que la gente se pregunte qué es la métrica de calidad. Es una escala de 0 bajo a 100, alta similar a la exportación de Photoshop, etc. Como se mencionó, se ignora para PNG, pero es posible que desee utilizar CompressFormat.JPEG. Según google doco: Sugerencia para el compresor, 0-100. 0 significa compresa para tamaño pequeño, 100 significa compresa para calidad máxima. Algunos formatos, como PNG que no tiene pérdidas, ignorarán la configuración de calidad
wired00
3
¿El archivo del directorio de caché se eliminará automáticamente?
Shajeel Afzal
1
¿Por qué usar a ByteArrayOutputStream, obtener una matriz de bytes de eso y luego escribir la matriz en a FileOutputStream? ¿Por qué no sólo el FileOutputStreamde 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
fuente
java.io.FileNotFoundException: / ruta: error de apertura: EROFS (sistema de archivos de solo lectura)
Prasad
1
@Prasad, asegúrese de pasar una ruta correcta a su File()constructor.
fraggjkee
Tiene una ruta predeterminada?
Nathiel Barros
solución perfecta
Xan
¿Qué es bitmap.compress? ¿Por qué esta función da formato JPEG? y que es 100
roghayeh hosseini
11

La conversión Bitmapa Filedebe hacerse en segundo plano (NO EN EL HILO PRINCIPAL) cuelga la interfaz de usuario especialmente si bitmapera 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);

    }
}

Llamándolo

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

DEBES usar el filein onPostExecute.

Para cambiar el directorio fileque se almacenará en la caché, reemplace la línea:

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

con :

file  = new File(context.getCacheDir(), "temporary_file.jpg");
Mohamed Embaby
fuente
1
Esto me da la excepción "FileNotFound" algunas veces. Todavía estoy investigando por qué sucede esto. Además, tal vez debería considerar guardar el wile con la extensión .webp, es aproximadamente un 40-50% menor que el JPG
Pranaysharma
Supongo que la excepción "FileNotFound" ocurre cuando se guarda en la memoria caché y de alguna manera se borra la memoria caché (hay muchas maneras de borrar la memoria caché, tal vez por otra aplicación) @Pranaysharma
Mohamed Embaby
No falta el execute () después del constructor: new fileFromBitmap (my_bitmap, getApplicationContext ()); ?
Andrea Leganza
1
@AndreaLeganza sí, faltaba, edité mi respuesta, gracias a ti.
Mohamed Embaby
¡Mantener el Contex en AsyncTask puede provocar pérdidas de memoria! youtube.com/watch?v=bNM_3YkK2Ws
slaviboy
2

La mayoría de las respuestas son demasiado largas o demasiado cortas y no cumplen el propósito. Para aquellos que buscan código Java o Kotlin para convertir mapa de bits en objeto de archivo. Aquí está el artículo detallado que he escrito sobre el tema. Convertir mapa de bits a archivo en 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
fuente
0

Espero que esto te ayude

clase 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
fuente