แปลงบิตแมปเป็นไฟล์


127

ฉันเข้าใจว่าการใช้BitmapFactoryสามารถแปลงไฟล์เป็นบิตแมป แต่มีวิธีใดในการแปลงภาพบิตแมปเป็นไฟล์หรือไม่

คำตอบ:


82

ลองสิ่งนี้:

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

ดูนี่


10
แต่ฉันไม่ต้องการFileOutputStreamแค่ File มีวิธีแก้ปัญหานี้หรือไม่?
Mxyk

9
นอกจากนี้คือqualityอะไร?
Mxyk

1
FileOutputStream คือวิธีที่คุณเขียนลงในไฟล์ ดูdeveloper.android.com/reference/java/io/FileOutputStream.html
Torid

ฉันไม่รู้จริงๆว่าคุณหมายถึงอะไร ... คุณใช้ FileOutputStream เพื่อสร้างไฟล์ และคุณสามารถใช้อินสแตนซ์ไฟล์ (เช่นในตัวอย่างของ amsiddh) เพื่อสร้าง FileOutputStream ที่คุณสามารถส่งออกบิตแมปไปได้ ด้วยสิ่งนั้น (อินสแตนซ์ไฟล์ไฟล์จริงบนระบบไฟล์และ FileOutputStream) คุณควรมีทุกสิ่งที่คุณต้องการใช่ไหม?
P.Melch

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
รหัสทำงานได้ดี แต่วิธีการบีบอัดใช้เวลามาก ทำงานรอบ ๆ ?
Shail Adi

10
ในกรณีที่ผู้คนสงสัยว่าเมตริกคุณภาพคืออะไร มันเป็นระดับ 0 ถึง 100 ต่ำสูงคล้ายกับ photoshop ส่งออก ฯลฯ เป็นที่กล่าวถึงละเว้นสำหรับ PNG, CompressFormat.JPEGแต่คุณอาจต้องการที่จะใช้ ตาม google doco: คำแนะนำสำหรับคอมเพรสเซอร์ 0-100 0 ความหมายการบีบอัดสำหรับขนาดเล็ก 100 ความหมายการบีบอัดเพื่อคุณภาพสูงสุด บางรูปแบบเช่น PNG ซึ่งเป็น lossless จะไม่สนใจการตั้งค่าคุณภาพ
wired00

3
ไฟล์จากไดเรกทอรีแคชจะถูกลบโดยอัตโนมัติหรือไม่?
Shajeel Afzal

1
ทำไมต้องใช้ a ByteArrayOutputStreamรับอาร์เรย์ไบต์จากนั้นจึงเขียนอาร์เรย์ไปยัง a FileOutputStream? ทำไมไม่เพียงแค่FileOutputStreamใน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();

java.io.FileNotFoundException: / path: open ล้มเหลว: EROFS (ระบบไฟล์แบบอ่านอย่างเดียว)
Prasad

1
@Prasad ตรวจสอบให้แน่ใจว่าคุณผ่านเส้นทางที่ถูกต้องไปยังผู้File()สร้างของคุณ
fraggjkee

มีเส้นทางเริ่มต้น?
Nathiel Barros

โซลูชั่นที่สมบูรณ์แบบ
Xan

bitmap.compress คืออะไร? เหตุใดฟังก์ชันนี้จึงให้รูปแบบ JPEG แล้ว 100 คืออะไร?
roghayeh hosseini

11

แปลงBitmapที่จะFileตอบสนองความต้องการที่จะทำในพื้นหลัง (ไม่ได้อยู่ใน MAIN ด้าย) มันแฮงค์ UI พิเศษถ้าbitmapมีขนาดใหญ่

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

คุณต้องใช้fileในonPostExecute .

ในการเปลี่ยนไดเร็กทอรีfileที่จะเก็บไว้ในแคชแทนที่บรรทัด:

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

กับ:

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

1
สิ่งนี้ทำให้ฉันมีข้อยกเว้น "FileNotFound" ในบางครั้ง ฉันยังคงตรวจสอบสาเหตุที่เกิดขึ้น นอกจากนี้คุณควรพิจารณาบันทึก wile ด้วยนามสกุล. webp ซึ่งมีขนาดน้อยกว่า JPG ประมาณ 40-50%
Pranaysharma

ฉันคิดว่าข้อยกเว้น "FileNotFound" เกิดขึ้นเมื่อบันทึกลงในแคชจากนั้นแคชจะถูกล้าง (มีหลายวิธีในการล้างแคชอาจใช้แอปพลิเคชันอื่น) @Pranaysharma
Mohamed Embaby

ไม่หายไป execute () หลัง constructor: new fileFromBitmap (my_bitmap, getApplicationContext ()); ?
Andrea Leganza

1
@AndreaLeganza ใช่มันหายไปฉันแก้ไขคำตอบแล้วขอบคุณ
Mohamed Embaby

การเก็บ Contex ไว้ใน AsyncTask อาจทำให้หน่วยความจำรั่ว !!! youtube.com/watch?v=bNM_3YkK2Ws
slaviboy

2

คำตอบส่วนใหญ่ยาวเกินไปหรือสั้นเกินไปไม่เป็นไปตามวัตถุประสงค์ สำหรับผู้ที่กำลังมองหาโค้ด Java หรือ Kotlin เพื่อแปลงบิตแมปเป็น File Object นี่คือบทความโดยละเอียดที่ฉันเขียนในหัวข้อนี้ แปลงบิตแมปเป็นไฟล์ใน 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)
}

}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.