Android/Java: сохранение байтового массива в файл (.jpeg)
Я разрабатываю приложение для Android, и часть приложения должна делать снимки и сохранять их на SD-карте. Метод onPictureTaken возвратил массив байтов с данными захваченного изображения.
Все, что мне нужно сделать, это сохранить массив байтов в файл образа .jpeg. Я попытался сделать это с помощью BitmapFactory.decodeByteArray(чтобы получить Bitmap), а затем bImage.compress(к OutputStream), простой OutputStream и BufferedOutputStream. Все три этих метода, похоже, дают мне ту же странную ошибку. Мой Android-телефон (8-мегапиксельная камера и приличный процессор), кажется, сохраняет фотографию (размер выглядит правильно), но поврежденным способом (изображение нарезано и каждый срез сдвинут, или я просто получаю почти горизонтальные линии разных цветов); И странно, что планшет Android с 5-мегапиксельной камерой и быстрым процессором, похоже, правильно сохраняет изображение.
Поэтому я подумал, что, возможно, процессор не может справиться с сохранением больших изображений, потому что я получил OutOfMemory Exceptions после 3 снимков (даже при качестве сжатия 40). Но тогда, как это делает встроенное приложение Camera, и намного быстрее? Я уверен (от отладки), что OutputStream записывает все данные (байты), и это должно быть хорошо, но оно все еще повреждено.
*** Короче говоря, каков наилучший/быстрый способ (который работает) для сохранения байтового массива в файл jpeg?
Спасибо заранее,
Марк
код, который я пробовал (и некоторые другие небольшие варианты):
try {
Bitmap image = BitmapFactory.decodeByteArray(args, 0, args.length);
OutputStream fOut = new FileOutputStream(externalStorageFile);
long time = System.currentTimeMillis();
image.compress(Bitmap.CompressFormat.JPEG,
jpegQuality, fOut);
System.out.println(System.currentTimeMillis() - time);
fOut.flush();
fOut.close();
} catch (Exception e) {
}
и
try {
externalStorageFile.createNewFile();
FileOutputStream fos = new FileOutputStream(externalStorageFile);
fos.write(args);
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
Ответы
Ответ 1
Все, что мне нужно сделать, это сохранить массив байтов в файл изображения .jpeg.
Просто напишите файл. Он уже находится в формате JPEG. Вот пример приложения, демонстрирующий это. Вот ключевой фрагмент кода:
class SavePhotoTask extends AsyncTask<byte[], String, String> {
@Override
protected String doInBackground(byte[]... jpeg) {
File photo=new File(Environment.getExternalStorageDirectory(), "photo.jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos=new FileOutputStream(photo.getPath());
fos.write(jpeg[0]);
fos.close();
}
catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
return(null);
}
}
Ответ 2
Этот код идеально подходит для сохранения изображения в хранилище, из байта []...
обратите внимание, что здесь "image" - это byte []...., взятый как "byte [] image" как параметр в функцию.
File photo=new File(Environment.getExternalStorageDirectory(), "photo.jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos=new FileOutputStream(photo.getPath());
Toast.makeText(this, photo.getPath(), Toast.LENGTH_SHORT).show();
fos.write(image);
fos.close();
}
catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
}
Ответ 3
Эй, это коды для котлина
camera.addCameraListener(object : CameraListener(){
override fun onPictureTaken(result: PictureResult) {
val jpeg = result.data //result.data is a ByteArray!
val photo = File(Environment.getExternalStorageDirectory(), "/DCIM/androidify.jpg");
if (photo.exists()) {
photo.delete();
}
try {
val fos = FileOutputStream(photo.getPath() );
fos.write(jpeg);
fos.close();
}
catch (e: IOException) {
Log.e("PictureDemo", "Exception in photoCallback", e)
}
}
})