mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-02-24 10:28:50 +01:00
Retain EXIF in enhanced files
This commit is contained in:
parent
6d0f612c7b
commit
9469ee1d6f
2 changed files with 147 additions and 6 deletions
|
@ -54,6 +54,7 @@ dependencies {
|
|||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
|
||||
implementation "androidx.annotation:annotation:1.3.0"
|
||||
implementation "androidx.core:core-ktx:1.7.0"
|
||||
implementation "androidx.exifinterface:exifinterface:1.3.3"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'org.tensorflow:tensorflow-lite:2.8.0'
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import android.util.Log
|
|||
import androidx.core.app.NotificationChannelCompat
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.exifinterface.media.ExifInterface
|
||||
import com.nkming.nc_photos.plugin.image_processor.ZeroDce
|
||||
import java.io.File
|
||||
import java.net.HttpURLConnection
|
||||
|
@ -235,6 +236,115 @@ private data class ImageProcessorCommand(
|
|||
private open class ImageProcessorCommandTask(context: Context) :
|
||||
AsyncTask<ImageProcessorCommand, Unit, MessageEvent>() {
|
||||
companion object {
|
||||
private val exifTagOfInterests = listOf(
|
||||
ExifInterface.TAG_IMAGE_DESCRIPTION,
|
||||
ExifInterface.TAG_MAKE,
|
||||
ExifInterface.TAG_MODEL,
|
||||
ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.TAG_X_RESOLUTION,
|
||||
ExifInterface.TAG_Y_RESOLUTION,
|
||||
ExifInterface.TAG_DATETIME,
|
||||
ExifInterface.TAG_ARTIST,
|
||||
ExifInterface.TAG_COPYRIGHT,
|
||||
ExifInterface.TAG_EXPOSURE_TIME,
|
||||
ExifInterface.TAG_F_NUMBER,
|
||||
ExifInterface.TAG_EXPOSURE_PROGRAM,
|
||||
ExifInterface.TAG_SPECTRAL_SENSITIVITY,
|
||||
ExifInterface.TAG_PHOTOGRAPHIC_SENSITIVITY,
|
||||
ExifInterface.TAG_OECF,
|
||||
ExifInterface.TAG_SENSITIVITY_TYPE,
|
||||
ExifInterface.TAG_STANDARD_OUTPUT_SENSITIVITY,
|
||||
ExifInterface.TAG_RECOMMENDED_EXPOSURE_INDEX,
|
||||
ExifInterface.TAG_ISO_SPEED,
|
||||
ExifInterface.TAG_ISO_SPEED_LATITUDE_YYY,
|
||||
ExifInterface.TAG_ISO_SPEED_LATITUDE_ZZZ,
|
||||
ExifInterface.TAG_EXIF_VERSION,
|
||||
ExifInterface.TAG_DATETIME_ORIGINAL,
|
||||
ExifInterface.TAG_DATETIME_DIGITIZED,
|
||||
ExifInterface.TAG_OFFSET_TIME,
|
||||
ExifInterface.TAG_OFFSET_TIME_ORIGINAL,
|
||||
ExifInterface.TAG_OFFSET_TIME_DIGITIZED,
|
||||
ExifInterface.TAG_SHUTTER_SPEED_VALUE,
|
||||
ExifInterface.TAG_APERTURE_VALUE,
|
||||
ExifInterface.TAG_BRIGHTNESS_VALUE,
|
||||
ExifInterface.TAG_EXPOSURE_BIAS_VALUE,
|
||||
ExifInterface.TAG_MAX_APERTURE_VALUE,
|
||||
ExifInterface.TAG_SUBJECT_DISTANCE,
|
||||
ExifInterface.TAG_METERING_MODE,
|
||||
ExifInterface.TAG_LIGHT_SOURCE,
|
||||
ExifInterface.TAG_FLASH,
|
||||
ExifInterface.TAG_FOCAL_LENGTH,
|
||||
ExifInterface.TAG_SUBJECT_AREA,
|
||||
ExifInterface.TAG_MAKER_NOTE,
|
||||
ExifInterface.TAG_USER_COMMENT,
|
||||
ExifInterface.TAG_SUBSEC_TIME,
|
||||
ExifInterface.TAG_SUBSEC_TIME_ORIGINAL,
|
||||
ExifInterface.TAG_SUBSEC_TIME_DIGITIZED,
|
||||
ExifInterface.TAG_FLASHPIX_VERSION,
|
||||
ExifInterface.TAG_FLASH_ENERGY,
|
||||
ExifInterface.TAG_SPATIAL_FREQUENCY_RESPONSE,
|
||||
ExifInterface.TAG_FOCAL_PLANE_X_RESOLUTION,
|
||||
ExifInterface.TAG_FOCAL_PLANE_Y_RESOLUTION,
|
||||
ExifInterface.TAG_FOCAL_PLANE_RESOLUTION_UNIT,
|
||||
ExifInterface.TAG_SUBJECT_LOCATION,
|
||||
ExifInterface.TAG_EXPOSURE_INDEX,
|
||||
ExifInterface.TAG_SENSING_METHOD,
|
||||
ExifInterface.TAG_FILE_SOURCE,
|
||||
ExifInterface.TAG_SCENE_TYPE,
|
||||
ExifInterface.TAG_CFA_PATTERN,
|
||||
ExifInterface.TAG_CUSTOM_RENDERED,
|
||||
ExifInterface.TAG_EXPOSURE_MODE,
|
||||
ExifInterface.TAG_WHITE_BALANCE,
|
||||
ExifInterface.TAG_DIGITAL_ZOOM_RATIO,
|
||||
ExifInterface.TAG_FOCAL_LENGTH_IN_35MM_FILM,
|
||||
ExifInterface.TAG_SCENE_CAPTURE_TYPE,
|
||||
ExifInterface.TAG_GAIN_CONTROL,
|
||||
ExifInterface.TAG_CONTRAST,
|
||||
ExifInterface.TAG_SATURATION,
|
||||
ExifInterface.TAG_SHARPNESS,
|
||||
ExifInterface.TAG_DEVICE_SETTING_DESCRIPTION,
|
||||
ExifInterface.TAG_SUBJECT_DISTANCE_RANGE,
|
||||
ExifInterface.TAG_IMAGE_UNIQUE_ID,
|
||||
ExifInterface.TAG_CAMERA_OWNER_NAME,
|
||||
ExifInterface.TAG_BODY_SERIAL_NUMBER,
|
||||
ExifInterface.TAG_LENS_SPECIFICATION,
|
||||
ExifInterface.TAG_LENS_MAKE,
|
||||
ExifInterface.TAG_LENS_MODEL,
|
||||
ExifInterface.TAG_GAMMA,
|
||||
ExifInterface.TAG_GPS_VERSION_ID,
|
||||
ExifInterface.TAG_GPS_LATITUDE_REF,
|
||||
ExifInterface.TAG_GPS_LATITUDE,
|
||||
ExifInterface.TAG_GPS_LONGITUDE_REF,
|
||||
ExifInterface.TAG_GPS_LONGITUDE,
|
||||
ExifInterface.TAG_GPS_ALTITUDE_REF,
|
||||
ExifInterface.TAG_GPS_ALTITUDE,
|
||||
ExifInterface.TAG_GPS_TIMESTAMP,
|
||||
ExifInterface.TAG_GPS_SATELLITES,
|
||||
ExifInterface.TAG_GPS_STATUS,
|
||||
ExifInterface.TAG_GPS_MEASURE_MODE,
|
||||
ExifInterface.TAG_GPS_DOP,
|
||||
ExifInterface.TAG_GPS_SPEED_REF,
|
||||
ExifInterface.TAG_GPS_SPEED,
|
||||
ExifInterface.TAG_GPS_TRACK_REF,
|
||||
ExifInterface.TAG_GPS_TRACK,
|
||||
ExifInterface.TAG_GPS_IMG_DIRECTION_REF,
|
||||
ExifInterface.TAG_GPS_IMG_DIRECTION,
|
||||
ExifInterface.TAG_GPS_MAP_DATUM,
|
||||
ExifInterface.TAG_GPS_DEST_LATITUDE_REF,
|
||||
ExifInterface.TAG_GPS_DEST_LATITUDE,
|
||||
ExifInterface.TAG_GPS_DEST_LONGITUDE_REF,
|
||||
ExifInterface.TAG_GPS_DEST_LONGITUDE,
|
||||
ExifInterface.TAG_GPS_DEST_BEARING_REF,
|
||||
ExifInterface.TAG_GPS_DEST_BEARING,
|
||||
ExifInterface.TAG_GPS_DEST_DISTANCE_REF,
|
||||
ExifInterface.TAG_GPS_DEST_DISTANCE,
|
||||
ExifInterface.TAG_GPS_PROCESSING_METHOD,
|
||||
ExifInterface.TAG_GPS_AREA_INFORMATION,
|
||||
ExifInterface.TAG_GPS_DATESTAMP,
|
||||
ExifInterface.TAG_GPS_DIFFERENTIAL,
|
||||
ExifInterface.TAG_GPS_H_POSITIONING_ERROR,
|
||||
)
|
||||
|
||||
private const val TAG = "ImageProcessorCommandTask"
|
||||
}
|
||||
|
||||
|
@ -263,7 +373,7 @@ private open class ImageProcessorCommandTask(context: Context) :
|
|||
"Unknown method: ${cmd.method}"
|
||||
)
|
||||
}
|
||||
saveBitmap(output, cmd.filename)
|
||||
saveBitmap(output, cmd.filename, file)
|
||||
} finally {
|
||||
file.delete()
|
||||
}
|
||||
|
@ -302,12 +412,42 @@ private open class ImageProcessorCommandTask(context: Context) :
|
|||
}
|
||||
}
|
||||
|
||||
private fun saveBitmap(bitmap: Bitmap, filename: String): Uri {
|
||||
return MediaStoreUtil.writeFileToDownload(
|
||||
context, {
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, it)
|
||||
}, filename, "Photos (for Nextcloud)/Enhanced Photos"
|
||||
private fun saveBitmap(
|
||||
bitmap: Bitmap, filename: String, srcFile: File
|
||||
): Uri {
|
||||
val outFile = File.createTempFile("out", null, getTempDir(context))
|
||||
outFile.outputStream().use {
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, it)
|
||||
}
|
||||
|
||||
// then copy the EXIF tags
|
||||
try {
|
||||
val iExif = ExifInterface(srcFile)
|
||||
val oExif = ExifInterface(outFile)
|
||||
copyExif(iExif, oExif)
|
||||
oExif.saveAttributes()
|
||||
} catch (e: Throwable) {
|
||||
Log.e(TAG, "[copyExif] Failed while saving EXIF", e)
|
||||
}
|
||||
|
||||
// move file to user accessible storage
|
||||
val uri = MediaStoreUtil.copyFileToDownload(
|
||||
context, Uri.fromFile(outFile), filename,
|
||||
"Photos (for Nextcloud)/Enhanced Photos"
|
||||
)
|
||||
outFile.delete()
|
||||
return uri
|
||||
}
|
||||
|
||||
private fun copyExif(from: ExifInterface, to: ExifInterface) {
|
||||
// only a subset will be copied over
|
||||
for (t in exifTagOfInterests) {
|
||||
try {
|
||||
from.getAttribute(t)?.let { to.setAttribute(t, it) }
|
||||
} catch (e: Throwable) {
|
||||
Log.e(TAG, "[copyExif] Failed while copying tag: $t", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
|
|
Loading…
Reference in a new issue