问题描述
我正在尝试使用xxd -r <<< '0 4455'
制作自定义相机应用。
我已经实现了hardware.camera
,当拍摄照片时它将写入具有特定路径的文件。写入文件的PictureCallback
是照相机API中的data
返回的ByteArray
。
因此,在写入文件后,我注意到垂直拍摄的图片是水平保存的。问题不是因为takePicture
标签导致byteArray在写入文件之前和之后都具有Exif
。
写入文件的ORIENTATION_NORMAL
是照相机API中的data
返回的ByteArray
。
takePicture
在takePicture
中是这样的:
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 (将#修改为@)