【问题标题】:Android/Java: Saving a byte array to a file (.jpeg)Android/Java:将字节数组保存到文件 (.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();
    }

【问题讨论】:

  • 你试过这样做吗:stackoverflow.com/questions/4263375/…
  • 我认为这可能是我的确切问题:stackoverflow.com/questions/5859876/… 这不是出于愿望,而是在 HTC 手机上
  • 是的,我尝试了他们所做的,这似乎是问题所在。现在如何修复它...有人知道如何修复它吗?因为 Paper Camera 和 Camera ZOOM FX 等应用程序具有工作预览(它们不会扭曲)并且可以很好地拍照。如果没有,我想我要么必须使相机预览失真,但图片可以;或者让预览看起来不错,并让它无法在某些 HTC 设备上运行...

标签: android bytearray jpeg android-camera


【解决方案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)
       {
      
       }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-10-18
        • 1970-01-01
        • 2021-05-25
        • 2013-10-19
        • 1970-01-01
        • 2013-10-27
        • 1970-01-01
        • 1970-01-01
        • 2016-09-21
        相关资源
        最近更新 更多