使用CameraX设置EXIF地理位置信息

3
3个回答

0

你可以使用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)
            }
        })


0
如果你拍照了,你可以重写onImageSaved方法。在那里,你可以将exif数据写入你的照片。我只有Java语言的示例,但原理是相同的。
 ExifInterface exif = null;
      try {
          exif = new ExifInterface(PhotoPath);
      } catch (IOException e) {
          e.printStackTrace();
      }
 exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, "location");

您可以在此处查找不同的标签。如何获取位置信息请参考此处,如果您需要更多关于如何将位置信息存储在exif中的信息,请查看此处


0
这是我想要找到的答案: 使用CameraX时,EXIF数据会自动设置,但不会设置GPS EXIF标签,因为:
- 需要权限来访问位置信息 - 有多种获取位置信息的方式,不同的选项对电池寿命有不同的影响,因此有控制权是很好的。 - 获取GPS位置信息可能需要很长时间(使用辅助GPS可能需要10秒,不使用辅助GPS可能需要长达10分钟)。
这是我在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)
}

在我的主活动的onCreate方法中定义了fusedLocationClient,它在lateinit之后(您需要在gradle.build(app)中激活Play Services/位置服务):
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接