Android/Java:将字节数组保存到文件 (.jpeg)
Posted
技术标签:
【中文标题】Android/Java:将字节数组保存到文件 (.jpeg)【英文标题】:Android/Java: Saving a byte array to a file (.jpeg) 【发布时间】:2011-12-20 04:53:43 【问题描述】:我正在为 android 开发一个应用程序,该应用程序的一部分必须拍照并将它们保存到 SD 卡。 onPictureTaken 方法返回一个字节数组,其中包含捕获图像的数据。
我需要做的就是将字节数组保存到 .jpeg 图像文件中。我试图在 BitmapFactory.decodeByteArray(获取 Bitmap)和 bImage.compress(到 OutputStream)、普通 OutputStream 和 BufferedOutputStream 的帮助下做到这一点。所有这三种方法似乎都给了我同样奇怪的错误。我的 Android 手机(8MP 相机和一个不错的处理器),似乎保存了照片(尺寸看起来正确),但是以一种损坏的方式(图像被切片并且每个切片都被移动;或者我只是得到各种颜色的几乎水平线) ;奇怪的是,带有 5MP 摄像头和快速处理器的 Android 平板电脑似乎可以正确保存图像。
所以我认为处理器可能无法跟上保存大图像的速度,因为我在大约 3 张图片后出现 OutOfMemory 异常(即使压缩质量为 40)。但是,内置的相机应用程序是如何做到的,而且速度也快得多?我很确定(来自调试)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();
【问题讨论】:
你试过这样做吗:***.com/questions/4263375/… 我认为这可能是我的确切问题:***.com/questions/5859876/… 这不是出于愿望,而是在 HTC 手机上 是的,我尝试了他们所做的,这似乎是问题所在。现在如何修复它...有人知道如何修复它吗?因为 Paper Camera 和 Camera ZOOM FX 等应用程序具有工作预览(它们不会扭曲)并且可以很好地拍照。如果没有,我想我要么必须使相机预览失真,但图片可以;或者让预览看起来不错,并让它无法在某些 HTC 设备上运行... 【参考方案1】:我需要做的就是将字节数组保存到 .jpeg 图像文件中。
只需将其写入文件即可。它已经是JPEG格式。 Here is a sample application demonstrating this。以下是关键代码:
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);
【讨论】:
这确实回答了我的问题,所以我会选择它。但是,如果您查看 cmets,我发现问题不在于保存,而是某些 HTC 设备在您使用“parameters.setPreviewSize”时似乎损坏了图像您知道如何解决或解决该错误吗?因为如果我不设置最佳预览大小,那么预览会变得很扁,看起来有点怪异。 @Mark:没有线索。您可以考虑发布有关该主题的新问题。 @CommonsWare 我已经使用了你的代码,但我的图像文件损坏了。这意味着我无法打开文件。 我几乎被fos.write(jpeg[0]);
愚弄了,它只在File
中写入了一个字节。在这段代码中,你应该写 fos.write( jpeg );
来写入整个字节数组。
@TheSunshinator:没有。jpeg
是 byte[]...
,所以 jpeg[0]
是 byte[]
。【参考方案2】:
这是 kotlin 的代码
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)
)
【讨论】:
【参考方案3】:此代码非常适合将图像保存在存储中,来自 byte[]... 注意这里的“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);
【讨论】:
【参考方案4】:这是将byte[]转换为image.jpg的函数
public void SavePhotoTask(byte [] jpeg)
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "Life Lapse");
imagesFolder.mkdirs();
final File photo= new File(imagesFolder, "name.jpg");
try
FileOutputStream fos=new FileOutputStream(photo.getPath());
fos.write(jpeg);
fos.close();
catch(Exception e)
【讨论】:
以上是关于Android/Java:将字节数组保存到文件 (.jpeg)的主要内容,如果未能解决你的问题,请参考以下文章
如何将字节数组从android java类传递给JNI C NDK?
如何将字节数组(即 byte[])保存到 Azure Blob 存储?