replate-camera 0.4.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1255,63 +1255,107 @@ class ReplateCameraController: NSObject {
1255
1255
  return context.createCGImage(ciImage, from: ciImage.extent)
1256
1256
  }
1257
1257
 
1258
- func saveImageAsJPEG(_ image: UIImage) -> URL? {
1259
- let cameraTransform = getCameraTransformString(from: ReplateCameraView.arView.session)
1260
-
1261
- guard let imageData = image.jpegData(compressionQuality: 1),
1262
- let source = CGImageSourceCreateWithData(imageData as CFData, nil) else {
1263
- return nil
1264
- }
1265
-
1266
- let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
1267
- let uniqueFilename = "image_\(Date().timeIntervalSince1970).jpg"
1268
- let fileURL = temporaryDirectoryURL.appendingPathComponent(uniqueFilename)
1269
-
1270
- guard let imageProperties = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) as? [CFString: Any] else {
1271
- return nil
1272
- }
1273
-
1274
- var mutableMetadata = imageProperties
1275
- mutableMetadata[kCGImagePropertyExifDictionary] = [
1276
- kCGImagePropertyExifUserComment: cameraTransform
1277
- ]
1278
-
1279
- guard let destination = CGImageDestinationCreateWithURL(
1280
- fileURL as CFURL,
1281
- kUTTypeJPEG,
1282
- 1,
1283
- nil
1284
- ) else {
1285
- return nil
1286
- }
1287
-
1288
- CGImageDestinationAddImageFromSource(
1289
- destination,
1290
- source,
1291
- 0,
1292
- mutableMetadata as CFDictionary
1293
- )
1294
-
1295
- guard CGImageDestinationFinalize(destination) else {
1296
- return nil
1297
- }
1298
-
1299
- return fileURL
1258
+ func saveImageAsJPEG(_ image: UIImage) -> URL? {
1259
+ guard let imageData = image.jpegData(compressionQuality: 1),
1260
+ let source = CGImageSourceCreateWithData(imageData as CFData, nil) else {
1261
+ return nil
1300
1262
  }
1301
-
1302
- func getCameraTransformString(from session: ARSession) -> String? {
1303
- guard let currentFrame = session.currentFrame else {
1304
- return nil
1305
- }
1306
-
1307
- let transform = currentFrame.camera.transform
1308
- return """
1309
- \(transform.columns.0.x),\(transform.columns.0.y),\(transform.columns.0.z),\(transform.columns.0.w);
1310
- \(transform.columns.1.x),\(transform.columns.1.y),\(transform.columns.1.z),\(transform.columns.1.w);
1311
- \(transform.columns.2.x),\(transform.columns.2.y),\(transform.columns.2.z),\(transform.columns.2.w);
1312
- \(transform.columns.3.x),\(transform.columns.3.y),\(transform.columns.3.z),\(transform.columns.3.w)
1313
- """
1263
+
1264
+ let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
1265
+ let uniqueFilename = "image_\(Date().timeIntervalSince1970).jpg"
1266
+ let fileURL = temporaryDirectoryURL.appendingPathComponent(uniqueFilename)
1267
+
1268
+ guard let imageProperties = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) as? [CFString: Any] else {
1269
+ return nil
1270
+ }
1271
+
1272
+ var mutableMetadata = imageProperties
1273
+ mutableMetadata[kCGImagePropertyExifDictionary] = [
1274
+ kCGImagePropertyExifUserComment: getTransformJSON(session: ReplateCameraView.arView.session)
1275
+ ]
1276
+
1277
+ guard let destination = CGImageDestinationCreateWithURL(
1278
+ fileURL as CFURL,
1279
+ kUTTypeJPEG,
1280
+ 1,
1281
+ nil
1282
+ ) else {
1283
+ return nil
1314
1284
  }
1285
+
1286
+ CGImageDestinationAddImageFromSource(
1287
+ destination,
1288
+ source,
1289
+ 0,
1290
+ mutableMetadata as CFDictionary
1291
+ )
1292
+
1293
+ guard CGImageDestinationFinalize(destination) else {
1294
+ return nil
1295
+ }
1296
+
1297
+ return fileURL
1298
+ }
1299
+
1300
+ func getTransformJSON(session: ARSession) -> String {
1301
+ let transform = session.currentFrame?.camera.transform ?? simd_float4x4()
1302
+ // Extract translation
1303
+ let translation = [
1304
+ "x": transform.columns.3.x,
1305
+ "y": transform.columns.3.y,
1306
+ "z": transform.columns.3.z
1307
+ ]
1308
+
1309
+ // Extract scale by calculating the length of each column vector
1310
+ let scale = [
1311
+ "x": simd_length(simd_float3(transform.columns.0.x, transform.columns.0.y, transform.columns.0.z)),
1312
+ "y": simd_length(simd_float3(transform.columns.1.x, transform.columns.1.y, transform.columns.1.z)),
1313
+ "z": simd_length(simd_float3(transform.columns.2.x, transform.columns.2.y, transform.columns.2.z))
1314
+ ]
1315
+
1316
+ // Extract rotation by normalizing each axis and converting it into a 3x3 rotation matrix
1317
+ let rotationMatrix = simd_float3x3(columns: (
1318
+ simd_float3(transform.columns.0.x / scale["x"]!, transform.columns.0.y / scale["x"]!, transform.columns.0.z / scale["x"]!),
1319
+ simd_float3(transform.columns.1.x / scale["y"]!, transform.columns.1.y / scale["y"]!, transform.columns.1.z / scale["y"]!),
1320
+ simd_float3(transform.columns.2.x / scale["z"]!, transform.columns.2.y / scale["z"]!, transform.columns.2.z / scale["z"]!)
1321
+ ))
1322
+
1323
+ // Convert rotation matrix to quaternion
1324
+ let quaternion = simd_quatf(rotationMatrix)
1325
+ let rotation = [
1326
+ "x": quaternion.vector.x,
1327
+ "y": quaternion.vector.y,
1328
+ "z": quaternion.vector.z,
1329
+ "w": quaternion.vector.w
1330
+ ]
1331
+
1332
+ // Get the gravity vector from the AR session
1333
+ var gravityVector: [String: Any] = [:]
1334
+ if let currentFrame = session.currentFrame {
1335
+ let gravityEulerAngles = currentFrame.camera.eulerAngles
1336
+ gravityVector = [
1337
+ "x": gravityEulerAngles.x,
1338
+ "y": gravityEulerAngles.y,
1339
+ "z": gravityEulerAngles.z
1340
+ ]
1341
+ }
1342
+
1343
+ // Format as JSON
1344
+ let jsonObject: [String: Any] = [
1345
+ "translation": translation,
1346
+ "rotation": rotation,
1347
+ "scale": scale,
1348
+ "gravityVector": gravityVector
1349
+ ]
1350
+
1351
+ // Convert dictionary to JSON string
1352
+ if let jsonData = try? JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted),
1353
+ let jsonString = String(data: jsonData, encoding: .utf8) {
1354
+ return jsonString
1355
+ } else {
1356
+ return "{}" // Return empty JSON if conversion fails
1357
+ }
1358
+ }
1315
1359
  }
1316
1360
 
1317
1361
  extension ARView: ARCoachingOverlayViewDelegate {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replate-camera",
3
- "version": "0.4.1",
3
+ "version": "0.5.1",
4
4
  "description": "Camera component for Replate Manager",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",