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:没有。jpegbyte[]...,所以 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)的主要内容,如果未能解决你的问题,请参考以下文章

用于 ScintillaNET 的字节数组到文本

如何将字节数组从android java类传递给JNI C NDK?

如何将字节数组(即 byte[])保存到 Azure Blob 存储?

成功将文件上传到MySQL中的字节数组,但是下载时内容不可读

将字节数组从服务器传输到浏览器

将字节数组转换为 wav 文件