如何使用 CameraX API 在图像 EXIF 中添加 Location 信息。我使用 https://codelabs.developers.google.com/codelabs/camerax-getting-started/#4.
创建了自己的应用程序我筛选了https://developer.android.com/training/camerax和https://developer.android.com/jetpack/androidx/releases/exifinterface但没有找到任何指南。
如果你拍了一张照片,你就会覆盖
onImageSaved
。在那里您可以将 exif 数据写入您的照片。我只有Java版的,不过原理是一样的
ExifInterface exif = null;
try {
exif = new ExifInterface(PhotoPath);
} catch (IOException e) {
e.printStackTrace();
}
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, "location");
您可以使用 Metadata.setLocation 方法设置位置
val metadata = Metadata().apply {
location = Location() // set the location here
}
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, System.currentTimeMillis())
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM)
}
val contentUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val outputOptions = OutputFileOptions.Builder(contentResolver, contentUri, contentValues)
.setMetadata(metadata)
.build()
imageCapture.takePicture(outputOptions, mainExecutor, object : OnImageSavedCallback {
override fun onImageSaved(outputFileResults: OutputFileResults) {
Log.d(TAG, "Photo URI ${outputFileResults.savedUri}")
}
override fun onError(exception: ImageCaptureException) {
Log.e(TAG, "Error", exception)
}
})
这是我想找到的答案: 使用 CameraX 时,会自动设置 EXIF 数据,但不会设置 GPS EXIF 标签,因为:
这是我在 onImageSaved() 回调中调用的函数:
fun setCurrentLocationInExif(context: Context, uri : Uri, fusedLocationClient : FusedLocationProviderClient){
// check location permissions
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
) {
throw(Exception("no location found"))
}
else {
// get location (a new one if older than 60s)
val locRequest = CurrentLocationRequest.Builder().setMaxUpdateAgeMillis(60000).build()
fusedLocationClient.getCurrentLocation(locRequest, null)
.addOnSuccessListener { location: Location? ->
// Got last known location. In some rare situations this can be null. In that case we do not go further
if (location != null){
Log.d(TAG, "latitude=${location.latitude}")
Log.d(TAG, "longitude=${location.longitude}")
val uriFd = context.contentResolver.openFileDescriptor(uri, "rw")
if (uriFd != null) {
val uriExif = ExifInterface(uriFd.fileDescriptor)
uriExif.setGpsInfo(location)
uriExif.saveAttributes()
uriFd.close()
}
else{
throw(Exception("Cannot find file for uri=$uri"))
}
}
}
}
}
onImageSaved 中的调用:
override fun onImageSaved(output: ImageCapture.OutputFileResults){
setCurrentLocationInExif(requireContext(), output.savedUri!!, fusedLocationClient)
}
fusedLocationClient 是在 Lateinit 之后在我的主活动 onCreate 中定义的(您需要在 gradle.build(app) 中激活 Play 服务/位置服务:
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)