Перетворити растровий файл у файл


127

Я розумію, що за допомогою програми BitmapFactoryможна перетворити файл у біт-карту, але чи є спосіб перетворити зображення Bitmap у файл?

Відповіді:


82

Спробуйте це:

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

Дивіться це


10
Але я не хочу FileOutputStream, а Файл. Чи є шлях до цього?
Mxyk

9
Також, що таке quality?
Mxyk

1
FileOutputStream - це спосіб запису у файл. Дивіться developer.android.com/reference/java/io/FileOutputStream.html
Torid

я насправді не знаю, що ви маєте на увазі ... Ви використовуєте FileOutputStream для створення файлу. І ви можете використовувати екземпляр File (як у прикладі 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
Код працює чудово, але метод стиснення займає багато часу. Будь-яка робота навколо?
Шайль Аді

10
на випадок, коли люди цікавляться, що таке показник якості. Він масштабується від 0 низького до 100, високий схожий з експортом фотошопу і т. Д. Як уже згадувалося, його ігнорують для PNG, але ви можете використовувати його CompressFormat.JPEG. Відповідно до google doco: Підказка компресору, 0-100. 0 значить компрес для невеликих розмірів, 100 значення компрес для максимальної якості. Деякі формати, як-от PNG без втрат, ігнорують налаштування якості
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: відкрито не вдалося: EROFS (файлова система лише для читання)
Prasad

1
@Prasad переконайтеся, що ви пройшли правильний шлях до свого File()конструктора.
fraggjkee

Це шлях за замовчуванням?
Натієль Баррос

ідеальне рішення
Xan

що таке bitmap.compress? чому ця функція надає формат JPEG? а що 100?
roghayeh hosseini

11

Перетворення Bitmapна Fileпотреби потрібно здійснити у фоновому режимі (НЕ В ГОЛОВНІЙ РІЗКІ), він висить інтерфейс спеціально, якщо розмір 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, приблизно на 40-50% меншим розміром, ніж JPG
Pranaysharma

Я вважаю, що виняток "FileNotFound" трапляється, коли зберегти в кеш, тоді кеш якось очищається (існує чимало способів очистити кеш, можливо, іншим додатком) @Pranaysharma
Mohamed Embaby

Не пропускає Execute () після конструктора: new fileFromBitmap (my_bitmap, getApplicationContext ()); ?
Андреа Леганса

1
@AndreaLeganza так, це не було, я відредагував свою відповідь, завдяки вам.
Мохаммед Ембабі

Зберігання Contex у AsyncTask може призвести до витоку пам'яті !!! youtube.com/watch?v=bNM_3YkK2Ws
slaviboy

2

Більшість відповідей занадто довгі або занадто короткі, щоб не відповідати меті. Для тих, хто шукає код Java або Котліна для перетворення растрових файлів у файл-об’єкт. Ось детальна стаття, яку я написав на цю тему. Перетворити растровий файл у файл в 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)
}

}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.