Camera.takePicture返回旋转的byteArray

问题描述

我正在尝试使用xxd -r <<< '0 4455' 制作自定义相机应用。

我已经实现了hardware.camera,当拍摄照片时它将写入具有特定路径的文件。写入文件的PictureCallback是照相机API中的data返回的ByteArray

因此,在写入文件后,我注意到垂直拍摄的图片是水平保存的。问题不是因为takePicture标签导致byteArray在写入文件之前和之后都具有Exif

写入文件的ORIENTATION_NORMAL是照相机API中的data返回的ByteArray

takePicturetakePicture中是这样的:

Camera.Java

这是 public final void takePicture(ShutterCallback shutter,PictureCallback raw,PictureCallback jpeg) { takePicture(shutter,raw,null,jpeg); } 的一部分,它将捕获照片:

相机预览代码

CameraPreview

ImageProcessor.kt的代码

    val imageProcessor = ImageProcessor()
    private val fileSaver = FileSaver(context)
    fun capture() {
        val callback = PictureCallback { data,_ ->
            imageProcessor.process(data)?.apply {
                val file = fileSaver.saveBitmap(this,outputFileName ?: DEFAULT_FILE_NAME)
                onCaptureTaken?.invoke(file)
            }
        }
        camera?.takePicture(null,callback)
    }

FileSaver.kt的代码

class ImageProcessor {

    fun process(data: ByteArray): Bitmap? {
        val options = BitmapFactory.Options().apply {
            inMutable = true
        }

        val bitmap = BitmapFactory.decodeByteArray(data,data.size,options)
        return fixImageRotation(data,bitmap)
    }
    private fun fixImageRotation(picture: ByteArray,bitmap: Bitmap): Bitmap? {
        return when (exifPostProcessor(picture)) {
            ExifInterface.ORIENTATION_ROTATE_90 ->
                rotateImage(bitmap,90F)
            ExifInterface.ORIENTATION_ROTATE_180 ->
                rotateImage(bitmap,180F)
            ExifInterface.ORIENTATION_ROTATE_270 ->
                rotateImage(
                    bitmap,270F
                )
            ExifInterface.ORIENTATION_NORMAL -> bitmap
            else -> bitmap
        }
    }

    private fun rotateImage(source: Bitmap,angle: Float): Bitmap? {
        val matrix = Matrix()
        matrix.postRotate(angle)
        return Bitmap.createBitmap(
            source,source.width,source.height,matrix,true
        )
    }

    private fun exifPostProcessor(picture: ByteArray?): Int {
        try {
            return getExifOrientation(ByteArrayInputStream(picture))
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return -1
    }

    @Throws(IOException::class)
    private fun getExifOrientation(inputStream: InputStream): Int {
        val exif = ExifInterface(inputStream)
        return exif.getAttributeInt(
            ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL
        )
    }
}

有什么建议吗?

编辑: 我打印了Exif标签,结果是internal class FileSaver(context: Context) { private val context: Context = context.applicationContext fun saveBitmap(bitmap: Bitmap,fileName: String): File { val file = File(mkdirsCacheFolder(),fileName) try { FileOutputStream(file).use { out -> bitmap.compress(Bitmap.CompressFormat.JPEG,ORIGINAL_QUALITY,out) } bitmap.recycle() } catch (e: IOException) { e.printStackTrace() } return file } private fun mkdirsCacheFolder(): File { return File(context.externalCacheDir,CACHE_DIRECTORY).apply { if (!exists()) { mkdirs() } } } companion object { private const val ORIGINAL_QUALITY = 100 private const val CACHE_DIRECTORY = "/Lens" } } ,所以我真的不知道它是否旋转过。

编辑2: 示例图片以人像模式拍摄并从文件管理器中打开[! 并非如此,这些结果已在模拟器和真正的android手机上进行了测试,它们是相同的。 预习: Preview

从文件管理器捕获的图像: Captured image from file manager

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)