capacitor-plugin-camera-forked 3.0.99 → 3.0.100

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.
@@ -1235,74 +1235,80 @@ public class CameraPreviewPlugin: CAPPlugin, AVCaptureVideoDataOutputSampleBuffe
1235
1235
  private func calculateBlurScore(image: UIImage) -> Double {
1236
1236
  guard let cgImage = image.cgImage else { return 0.0 }
1237
1237
 
1238
- let context = CIContext()
1239
- let ciImage = CIImage(cgImage: cgImage)
1238
+ let width = cgImage.width
1239
+ let height = cgImage.height
1240
1240
 
1241
- // Convert to grayscale for better blur detection
1242
- let grayscaleFilter = CIFilter(name: "CIColorControls")!
1243
- grayscaleFilter.setValue(ciImage, forKey: kCIInputImageKey)
1244
- grayscaleFilter.setValue(0.0, forKey: kCIInputSaturationKey)
1241
+ // Create bitmap context to access pixel data
1242
+ let bytesPerPixel = 4
1243
+ let bytesPerRow = bytesPerPixel * width
1244
+ let bitsPerComponent = 8
1245
1245
 
1246
- guard let grayscaleImage = grayscaleFilter.outputImage else { return 0.0 }
1246
+ guard let context = CGContext(
1247
+ data: nil,
1248
+ width: width,
1249
+ height: height,
1250
+ bitsPerComponent: bitsPerComponent,
1251
+ bytesPerRow: bytesPerRow,
1252
+ space: CGColorSpaceCreateDeviceRGB(),
1253
+ bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue
1254
+ ) else { return 0.0 }
1247
1255
 
1248
- // Apply Laplacian filter for edge detection
1249
- let laplacianKernel: [Float] = [
1250
- 0, -1, 0,
1251
- -1, 4, -1,
1252
- 0, -1, 0
1253
- ]
1254
-
1255
- let convolutionFilter = CIFilter(name: "CIConvolution3X3")!
1256
- convolutionFilter.setValue(grayscaleImage, forKey: kCIInputImageKey)
1257
- convolutionFilter.setValue(CIVector(values: laplacianKernel, count: 9), forKey: "inputWeights")
1258
-
1259
- guard let filteredImage = convolutionFilter.outputImage else { return 0.0 }
1260
-
1261
- // Calculate variance of the Laplacian
1262
- let extent = filteredImage.extent
1263
- let inputExtent = CIVector(x: extent.origin.x, y: extent.origin.y, z: extent.size.width, w: extent.size.height)
1264
-
1265
- let averageFilter = CIFilter(name: "CIAreaAverage")!
1266
- averageFilter.setValue(filteredImage, forKey: kCIInputImageKey)
1267
- averageFilter.setValue(inputExtent, forKey: kCIInputExtentKey)
1268
-
1269
- guard let averageImage = averageFilter.outputImage else { return 0.0 }
1270
-
1271
- var bitmap = [UInt8](repeating: 0, count: 4)
1272
- context.render(averageImage, toBitmap: &bitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil)
1256
+ // Draw image into context
1257
+ context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
1273
1258
 
1274
- let average = Double(bitmap[0]) / 255.0
1275
-
1276
- // Calculate variance by processing small samples of the image
1277
- let sampleSize = min(100, Int(extent.width), Int(extent.height))
1278
- let stepX = extent.width / Double(sampleSize)
1279
- let stepY = extent.height / Double(sampleSize)
1259
+ guard let pixelData = context.data else { return 0.0 }
1260
+ let data = pixelData.bindMemory(to: UInt8.self, capacity: width * height * bytesPerPixel)
1280
1261
 
1262
+ // Convert to grayscale and apply Laplacian kernel (same as Android/Web)
1281
1263
  var variance = 0.0
1282
- var sampleCount = 0
1264
+ var count = 0
1283
1265
 
1284
- for i in 0..<sampleSize {
1285
- for j in 0..<sampleSize {
1286
- let x = extent.origin.x + Double(i) * stepX
1287
- let y = extent.origin.y + Double(j) * stepY
1288
- let sampleRect = CGRect(x: x, y: y, width: 1, height: 1)
1266
+ // Sample every 4th pixel for performance (same as Android/Web)
1267
+ let step = 4
1268
+ for y in stride(from: step, to: height - step, by: step) {
1269
+ for x in stride(from: step, to: width - step, by: step) {
1270
+ let idx = (y * width + x) * bytesPerPixel
1289
1271
 
1290
- let sampleFilter = CIFilter(name: "CIAreaAverage")!
1291
- sampleFilter.setValue(filteredImage, forKey: kCIInputImageKey)
1292
- sampleFilter.setValue(CIVector(cgRect: sampleRect), forKey: kCIInputExtentKey)
1272
+ // Convert to grayscale using same formula as Android/Web
1273
+ let r = Double(data[idx])
1274
+ let g = Double(data[idx + 1])
1275
+ let b = Double(data[idx + 2])
1276
+ let gray = 0.299 * r + 0.587 * g + 0.114 * b
1293
1277
 
1294
- if let sampleImage = sampleFilter.outputImage {
1295
- var sampleBitmap = [UInt8](repeating: 0, count: 4)
1296
- context.render(sampleImage, toBitmap: &sampleBitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil)
1297
-
1298
- let value = Double(sampleBitmap[0]) / 255.0
1299
- variance += pow(value - average, 2)
1300
- sampleCount += 1
1301
- }
1278
+ // Calculate neighbors for 3x3 Laplacian kernel
1279
+ let neighbors: [Double] = [
1280
+ // Top row
1281
+ getGrayscaleValue(data: data, x: x-1, y: y-1, width: width, bytesPerPixel: bytesPerPixel),
1282
+ getGrayscaleValue(data: data, x: x, y: y-1, width: width, bytesPerPixel: bytesPerPixel),
1283
+ getGrayscaleValue(data: data, x: x+1, y: y-1, width: width, bytesPerPixel: bytesPerPixel),
1284
+ // Middle row (left and right)
1285
+ getGrayscaleValue(data: data, x: x-1, y: y, width: width, bytesPerPixel: bytesPerPixel),
1286
+ getGrayscaleValue(data: data, x: x+1, y: y, width: width, bytesPerPixel: bytesPerPixel),
1287
+ // Bottom row
1288
+ getGrayscaleValue(data: data, x: x-1, y: y+1, width: width, bytesPerPixel: bytesPerPixel),
1289
+ getGrayscaleValue(data: data, x: x, y: y+1, width: width, bytesPerPixel: bytesPerPixel),
1290
+ getGrayscaleValue(data: data, x: x+1, y: y+1, width: width, bytesPerPixel: bytesPerPixel)
1291
+ ]
1292
+
1293
+ // Apply 3x3 Laplacian kernel (matches Android/Web implementation)
1294
+ let laplacian = -neighbors[0] - neighbors[1] - neighbors[2] +
1295
+ -neighbors[3] + 8 * gray - neighbors[4] +
1296
+ -neighbors[5] - neighbors[6] - neighbors[7]
1297
+
1298
+ variance += laplacian * laplacian
1299
+ count += 1
1302
1300
  }
1303
1301
  }
1304
1302
 
1305
- return sampleCount > 0 ? variance / Double(sampleCount) : 0.0
1303
+ return count > 0 ? variance / Double(count) : 0.0
1304
+ }
1305
+
1306
+ private func getGrayscaleValue(data: UnsafePointer<UInt8>, x: Int, y: Int, width: Int, bytesPerPixel: Int) -> Double {
1307
+ let idx = (y * width + x) * bytesPerPixel
1308
+ let r = Double(data[idx])
1309
+ let g = Double(data[idx + 1])
1310
+ let b = Double(data[idx + 2])
1311
+ return 0.299 * r + 0.587 * g + 0.114 * b
1306
1312
  }
1307
1313
 
1308
1314
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-plugin-camera-forked",
3
- "version": "3.0.99",
3
+ "version": "3.0.100",
4
4
  "description": "A capacitor camera plugin - A custom Capacitor camera plugin with additional features.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",