Преобразовать растровое изображение в файл


127

Я понимаю, что с помощью BitmapFactoryможно преобразовать файл в растровое изображение, но есть ли способ преобразовать растровое изображение в файл?

Ответы:


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, в который вы можете экспортировать растровое изображение. С этим (экземпляр File, фактический файл в файловой системе и 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
не забудьте очистить и закрыть выходной поток :)
Бен Холланд,

3
Код работает нормально, но метод сжатия занимает много времени. Любая работа?
Шай Ади

10
Если люди задаются вопросом, что такое показатель качества. Это шкала от 0 до 100, высокая, как при экспорте в фотошоп и т. Д. Как уже упоминалось, он игнорируется для PNG, но вы можете захотеть использовать CompressFormat.JPEG. Согласно Google doco: Подсказка компрессору, 0-100. 0 означает сжатие для малого размера, 100 означает сжатие для максимального качества. Некоторые форматы, например PNG без потерь, будут игнорировать настройку качества
wired00

3
Будет ли файл из каталога кеша удаляться автоматически?
Шажил Афзал

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 failed: EROFS (файловая система только для чтения)
Prasad

1
@Prasad убедитесь, что вы передаете правильный путь своему File()конструктору.
fraggjkee

У него есть путь по умолчанию?
Nathiel Barros 08

идеальное решение
Ксан

что такое 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();

вы ДОЛЖНЫ использовать filein onPostExecute.

Чтобы изменить каталог, fileкоторый будет храниться в кеше, замените строку:

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

с участием :

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

1
Это несколько раз вызывает у меня исключение "FileNotFound". Я все еще пытаюсь выяснить, почему это происходит. Также, возможно, вам стоит подумать о том, чтобы сохранить хитрость с расширением .webp, размер которого примерно на 40-50% меньше, чем у JPG
Pranaysharma 05

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

Не пропущен execute () после конструктора: new fileFromBitmap (my_bitmap, getApplicationContext ()); ?
Андреа Леганца

1
@AndreaLeganza да, его не было, я отредактировал свой ответ, спасибо вам.
Мохамед Эмбаби

Сохранение Contex в AsyncTask может привести к утечке памяти !!! youtube.com/watch?v=bNM_3YkK2Ws
slaviboy

2

Большинство ответов слишком длинные или слишком короткие, что не соответствует цели. Для тех, кто ищет код 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

Надеюсь, это поможет тебе

class 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.