I am developing an Android app and I am trying to save bitmaps as jpeg-images into the Pictures folder of the phone. The code below works mostly fine, but it occasionally happens that the app saves the photo incorrectly (see distorted image below). Any idea what may cause this error and how to fix it? (The app is designed for Android 10+, hence I am working with MediaStore). I am relatively new to Android development, so please let me know if I should add any information to the question. Thanks in advance for your help!
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){
}
While it might not be relevant, I have added the saveExif method for completeness (see below). This method adds some exif metadata to the saved image.
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, SimpleDateFormat("XXX", Locale.getDefault()).format(Date()))
exif.setAttribute(ExifInterface.TAG_OFFSET_TIME, SimpleDateFormat("XXX", Locale.getDefault()).format(Date()))
}
exif.saveAttributes()
}
from JPG image is stored incorrectly on external storage (Android)
No comments:
Post a Comment