将位图转换为文件


127

我知道使用BitmapFactory可以将文件转换为位图,但是有什么方法可以将位图图像转换为文件吗?

Answers:


82

试试这个:

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

看到这个


10
但是我不想要一个FileOutputStream,只是一个文件。有没有解决的办法?
Mxyk 2011年

9
另外,什么是quality
Mxyk 2011年

1
FileOutputStream是您写入文件的方式。请参阅developer.android.com/reference/java/io/FileOutputStream.html
Torid

我真的不明白你的意思。。。您使用FileOutputStream创建文件。而且,您可以使用File实例(例如在amsiddh的示例中)创建FileOutputStream,可以将位图导出到该文件。有了它(一个File实例,一个在文件系统上的实际文件以及FileOutputStream),您应该拥有所需的一切,不是吗?
P.Melch,2011年

235

希望对您有帮助:

//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
不要忘记刷新并关闭输出流:)
Ben Holland

3
代码可以正常工作,但是compress方法需要很多时间。有没有解决的办法?
Shail Adi

10
如果人们想知道什么是质量指标。它是0到100的小数位数,类似于photoshop export等。如上所述,对于PNG忽略了它,但是您可能希望使用CompressFormat.JPEG。按照谷歌doco:提示压缩机,0-100。0表示小尺寸压缩,100表示​​最大质量压缩。某些格式(例如无损的PNG)将忽略质量设置
有线00 2013年

3
缓存目录中的文件会自动删除吗?
Shajeel Afzal

1
为什么使用a ByteArrayOutputStream,从中获取一个字节数组,然后将该数组写入a FileOutputStream?为什么不只是FileOutputStreamBitmap.compress
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:打开失败:EROFS(只读文件系统)
Prasad

1
@Prasad确保您将正确的路径传递给File()构造函数。
fraggjkee 2015年

它有默认路径吗?
Nathiel Barros

完美的解决方案
Xan

什么是bitmap.compress?为什么此功能使用JPEG格式?100是多少?
roghayeh hosseini

11

转换BitmapFile需要在后台完成(不在主线程中),如果bitmap较大,则会挂起UI

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

    }
}

称呼它

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

您必须使用filein onPostExecute

要更改file要存储在缓存中的目录,请替换行:

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

与:

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

1
这使我有时出现“ FileNotFound”异常。我仍在调查为什么会这样。另外,也许您应该考虑将.webp扩展名保存为wile,其大小比JPG少40-50%
Pranaysharma

我猜想“ FileNotFound”异常发生在保存到高速缓存时,然后以某种方式清除了高速缓存(有多种方法可以清除高速缓存,也许是通过其他应用程序清除)@Pranaysharma
Mohamed Embaby

构造函数之后不缺少execute():new fileFromBitmap(my_bitmap,getApplicationContext()); ?
安德里亚·莱

1
@AndreaLeganza是的,它不见了,感谢您,我编辑了答案。
Mohamed Embaby '18

将Contex保留在AsyncTask中可能会导致内存泄漏!!!youtube.com/watch?v=bNM_3YkK2Ws
slaviboy

1

大多数答案太长或太短,无法达到目的。对于那些正在寻找Java或Kotlin代码以将位图转换为文件对象的人。这是我就该主题撰写的详细文章。在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

希望这对你有帮助

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

}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.