我正在尝试将android.hardware.camera2图片保存为无损格式。

我已经使用杂乱无章的代码在JPEG(有损)和DMG(原始,但是庞大而又难以使用)上工作了:

private fun save(image: Image, captureResult: TotalCaptureResult) {
    val fileWithoutExtension = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "myimage_${System.currentTimeMillis()}")
    val file: File = when (image.format) {
        ImageFormat.JPEG -> {
            val buffer = image.planes[0].buffer
            val bytes = ByteArray(buffer.remaining())
            buffer.get(bytes)
            val file = File("$fileWithoutExtension.jpg")
            file.writeBytes(bytes)
            file
        }
        ImageFormat.RAW_SENSOR -> {
            val dngCreator = DngCreator(mode.characteristics, captureResult)
            val file = File("$fileWithoutExtension.dmg")
            FileOutputStream(file).use { os ->
                dngCreator.writeImage(os, image)
            }
            file
        }
        else -> TODO("Unsupported image format: ${image.format}")
    }
    Log.i(TAG, "Wrote image:${file.canonicalPath} ${file.length() / 1024}k")
    image.close() // necessary when taking a few shots
}

但是我坚持的是将RAW_SENSOR部分替换为保存为更合理的PNG的内容。是吗
  • 是个坏主意,因为RAW_SENSOR与普通图像格式有很大不同,以至于我不得不经历太多痛苦才能转换它?
  • 是个坏主意,因为我应该将上游捕获设置为捕获更合理的内容,例如FLEX_RGB_888?
  • 是个好主意,因为以下代码中有些愚蠢的错误? (死于Buffer not large enough for pixels at android.graphics.Bitmap.copyPixelsFromBuffer(Bitmap.java:593)

  • 我的尝试:
    fun writeRawImageToPng(image: Image, pngFile: File) {
        Bitmap.createBitmap(image.width, image.height, Bitmap.Config.ARGB_8888).let { latestBitmap->
            latestBitmap.copyPixelsFromBuffer(image.planes[0].buffer!!)
            ByteArrayOutputStream().use { baos ->
                latestBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos)
                pngFile.writeBytes(baos.toByteArray())
            }
        }
    }
    

    最佳答案

    您想要捕获YUV_420_888格式的数据;不管怎么说,这就是JPEG压缩器的开始。

    您必须自己将其转换为RGB位图,但是-没有方便的方法。

    07-27 13:50