如何解决使用 exif 元数据保存图像时 JPEG 损坏
我正在开发一个 Android 应用程序,它将位图作为 jpeg 图像保存到外部存储。偶尔会发生 JPEG 损坏的情况(见下图)。我意识到只有在调用 saveExif() 时才会发生损坏(最终)。如果我注释掉 saveExif(),损坏就不会发生。这意味着它是由与 EXIF 相关的东西而不是压缩过程引起的。 我已经使用软件 (Bad Peggy) 分析了 jpeg,由于数据段过早结束,该软件检测到图像已损坏。
知道如何修复它吗?
这是我最初保存图像的方式:
lateinit var uri: Uri
val imageOutStream: OutputStream
val contentResolver = context.contentResolver
val mimeType = "image/jpeg"
val mediaContentUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val values = ContentValues().apply {
put(MediaStore.Images.Media.disPLAY_NAME,fileName)
put(MediaStore.Images.Media.MIME_TYPE,mimeType)
put(MediaStore.Images.Media.RELATIVE_PATH,directory)
}
contentResolver.run {
uri = context.contentResolver.insert(mediaContentUri,values)
?: return
imageOutStream = openOutputStream(uri) ?: return
}
try {
imageOutStream.use { bitmap.compress(Bitmap.CompressFormat.JPEG,photoCompression,it) }
} catch (e: java.lang.Exception) {
e.printstacktrace()
} finally {
imageOutStream.close()
}
try {
context.contentResolver.openInputStream(uri).use {
val exif = ExifInterface(context.contentResolver.openFileDescriptor(uri,"rw")!!.fileDescriptor)
saveExif(exif,context) //method ads exif Metadata to image
}
}catch (e: java.lang.Exception){
}
这是我在 JPEG 存储后添加 Exif 元数据的方式:
private fun saveExif(exif: ExifInterface,context: Context){
if (referenceWithCaptionExif != "" && notesExif != "") {
exif.setAttribute(ExifInterface.TAG_USER_COMMENT,"$referenceWithCaptionExif | $notesExif")
} else {
exif.setAttribute(ExifInterface.TAG_USER_COMMENT,"$referenceWithCaptionExif$notesExif")
}
if (companyExif != "") {
exif.setAttribute(ExifInterface.TAG_CAMERA_OWNER_NAME,companyExif)
val yearForExif = SimpleDateFormat("yyyy",Locale.getDefault()).format(Date())
exif.setAttribute(ExifInterface.TAG_copYRIGHT,"copyright (c) $companyExif $yearForExif")
}
if (projectExif != "") {
exif.setAttribute(ExifInterface.TAG_IMAGE_DESCRIPTION,projectExif)
}
exif.setAttribute(ExifInterface.TAG_MAKER_NOTE,"Project[$projectExif] Company[$companyExif] " +
"Notes[$notesExif] Reference[$referenceExif] ReferenceType[$referenceTypeExif] Coordinates[$coordinatesExif] " +
"CoordinateSystem[$coordinateSystemExif] Accuracy[$accuracyExif] Altitude[$altitudeExif] " +
"Date[$dateTimeExif] Address[$addressExif]")
exif.setAttribute(ExifInterface.TAG_ARTIST,"${android.os.Build.MANUFACTURER} ${android.os.Build.MODEL}")
exif.setAttribute(ExifInterface.TAG_SOFTWARE,context.resources.getString(R.string.app_name))
exif.setAttribute(ExifInterface.TAG_MAKE,(android.os.Build.MANUFACTURER).toString())
exif.setAttribute(ExifInterface.TAG_MODEL,(android.os.Build.MODEL).toString())
exif.setAttribute(ExifInterface.TAG_COMPRESSION,7.toString())
exif.setAttribute(ExifInterface.TAG_IMAGE_WIDTH,"${bitmapToProcess.width} px")
exif.setAttribute(ExifInterface.TAG_IMAGE_LENGTH,"${bitmapToProcess.height} px")
exif.setAttribute(ExifInterface.TAG_PIXEL_X_DIMENSION,"${bitmapToProcess.width} px")
exif.setAttribute(ExifInterface.TAG_PIXEL_Y_DIMENSION,"${bitmapToProcess.height} px")
exif.setAttribute(ExifInterface.TAG_GPS_ALTITUDE,altitudeExif)
exif.setAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF,0.toString())
exif.setAltitude(altitudeMetricExif)
exif.setLatLong(latitudewgs84Exif,longitudewgs84Exif)
exif.setAttribute(ExifInterface.TAG_GPS_TIMESTAMP,timeGPSExif)
exif.setAttribute(ExifInterface.TAG_GPS_DATESTAMP,dateGPSExif)
exif.setAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD,"GPS")
exif.setAttribute(ExifInterface.TAG_DATETIME,dateTimeOriginalExif)
exif.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL,dateTimeOriginalExif)
exif.setAttribute(ExifInterface.TAG_DATETIME_DIGITIZED,dateTimeOriginalExif)
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_DIGITIZED,SimpleDateFormat("XXX",Locale.getDefault()).format(Date()))
exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL,Locale.getDefault()).format(Date()))
exif.setAttribute(ExifInterface.TAG_OFFSET_TIME,Locale.getDefault()).format(Date()))
}
exif.saveAttributes()
}
解决方法
您可以一次注释掉每个元数据,看看是否有特定的元数据导致损坏。其中一些需要进行大量编程,所以我想知道这是否与不正确的字符串类型有关。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。