@capgo/camera-preview 7.16.2 → 7.16.4
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.
|
@@ -1314,13 +1314,7 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
|
|
|
1314
1314
|
if (transformedPixels) {
|
|
1315
1315
|
Integer fW = (finalWidthOut > 0) ? finalWidthOut : null;
|
|
1316
1316
|
Integer fH = (finalHeightOut > 0) ? finalHeightOut : null;
|
|
1317
|
-
bytes = injectExifInMemory(
|
|
1318
|
-
bytes,
|
|
1319
|
-
originalCaptureBytes,
|
|
1320
|
-
fW,
|
|
1321
|
-
fH,
|
|
1322
|
-
/*normalizeOrientation*/true
|
|
1323
|
-
);
|
|
1317
|
+
bytes = injectExifInMemory(bytes, originalCaptureBytes, fW, fH);
|
|
1324
1318
|
}
|
|
1325
1319
|
|
|
1326
1320
|
// Save to gallery asynchronously if requested, copy EXIF to file
|
|
@@ -1495,8 +1489,7 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
|
|
|
1495
1489
|
byte[] targetJpeg,
|
|
1496
1490
|
byte[] sourceJpegWithExif,
|
|
1497
1491
|
Integer finalWidth,
|
|
1498
|
-
Integer finalHeight
|
|
1499
|
-
boolean normalizeOrientation
|
|
1492
|
+
Integer finalHeight
|
|
1500
1493
|
) {
|
|
1501
1494
|
try {
|
|
1502
1495
|
// Quick signature check for JPEG (FF D8 FF)
|
|
@@ -1524,19 +1517,27 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
|
|
|
1524
1517
|
: new org.apache.commons.imaging.formats.tiff.write.TiffOutputSet();
|
|
1525
1518
|
|
|
1526
1519
|
// Update orientation if requested (normalize to 1)
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
);
|
|
1537
|
-
}
|
|
1520
|
+
org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory rootDir =
|
|
1521
|
+
outputSet.getOrCreateRootDirectory();
|
|
1522
|
+
rootDir.removeField(
|
|
1523
|
+
org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants.TIFF_TAG_ORIENTATION
|
|
1524
|
+
);
|
|
1525
|
+
rootDir.add(
|
|
1526
|
+
org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants.TIFF_TAG_ORIENTATION,
|
|
1527
|
+
(short) 1
|
|
1528
|
+
);
|
|
1538
1529
|
|
|
1539
|
-
|
|
1530
|
+
if (finalWidth != null || finalHeight != null) {
|
|
1531
|
+
try {
|
|
1532
|
+
updateResizedDimensions(outputSet, finalWidth, finalHeight);
|
|
1533
|
+
} catch (Exception dimensionUpdateError) {
|
|
1534
|
+
Log.w(
|
|
1535
|
+
TAG,
|
|
1536
|
+
"injectExifInMemory: Failed to update resized dimensions",
|
|
1537
|
+
dimensionUpdateError
|
|
1538
|
+
);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1540
1541
|
|
|
1541
1542
|
java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
|
|
1542
1543
|
new org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter()
|
|
@@ -1552,6 +1553,65 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
|
|
|
1552
1553
|
}
|
|
1553
1554
|
}
|
|
1554
1555
|
|
|
1556
|
+
private void updateResizedDimensions(
|
|
1557
|
+
org.apache.commons.imaging.formats.tiff.write.TiffOutputSet outputSet,
|
|
1558
|
+
Integer finalWidth,
|
|
1559
|
+
Integer finalHeight
|
|
1560
|
+
) throws org.apache.commons.imaging.ImagingException {
|
|
1561
|
+
org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory rootDir =
|
|
1562
|
+
outputSet.getOrCreateRootDirectory();
|
|
1563
|
+
if (finalWidth != null) {
|
|
1564
|
+
replaceShortOrLongTag(
|
|
1565
|
+
rootDir,
|
|
1566
|
+
org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants.TIFF_TAG_IMAGE_WIDTH,
|
|
1567
|
+
finalWidth
|
|
1568
|
+
);
|
|
1569
|
+
}
|
|
1570
|
+
if (finalHeight != null) {
|
|
1571
|
+
replaceShortOrLongTag(
|
|
1572
|
+
rootDir,
|
|
1573
|
+
org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants.TIFF_TAG_IMAGE_LENGTH,
|
|
1574
|
+
finalHeight
|
|
1575
|
+
);
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory exifDir =
|
|
1579
|
+
outputSet.getOrCreateExifDirectory();
|
|
1580
|
+
if (finalWidth != null) {
|
|
1581
|
+
replaceShortTag(
|
|
1582
|
+
exifDir,
|
|
1583
|
+
org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants.EXIF_TAG_EXIF_IMAGE_WIDTH,
|
|
1584
|
+
finalWidth
|
|
1585
|
+
);
|
|
1586
|
+
}
|
|
1587
|
+
if (finalHeight != null) {
|
|
1588
|
+
replaceShortTag(
|
|
1589
|
+
exifDir,
|
|
1590
|
+
org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants.EXIF_TAG_EXIF_IMAGE_LENGTH,
|
|
1591
|
+
finalHeight
|
|
1592
|
+
);
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
private void replaceShortOrLongTag(
|
|
1597
|
+
org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory directory,
|
|
1598
|
+
org.apache.commons.imaging.formats.tiff.taginfos.TagInfoShortOrLong tagInfo,
|
|
1599
|
+
int value
|
|
1600
|
+
) throws org.apache.commons.imaging.ImagingException {
|
|
1601
|
+
directory.removeField(tagInfo);
|
|
1602
|
+
directory.add(tagInfo, value);
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
private void replaceShortTag(
|
|
1606
|
+
org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory directory,
|
|
1607
|
+
org.apache.commons.imaging.formats.tiff.taginfos.TagInfoShort tagInfo,
|
|
1608
|
+
int value
|
|
1609
|
+
) throws org.apache.commons.imaging.ImagingException {
|
|
1610
|
+
int sanitizedValue = Math.max(0, Math.min(value, 0xFFFF));
|
|
1611
|
+
directory.removeField(tagInfo);
|
|
1612
|
+
directory.add(tagInfo, (short) sanitizedValue);
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1555
1615
|
private static final String[][] EXIF_TAGS = new String[][] {
|
|
1556
1616
|
{ ExifInterface.TAG_APERTURE_VALUE, "ApertureValue" },
|
|
1557
1617
|
{ ExifInterface.TAG_ARTIST, "Artist" },
|
|
@@ -393,7 +393,6 @@ extension CameraController {
|
|
|
393
393
|
fileVideoOutput.connections.forEach { $0.videoOrientation = videoOrientation }
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
-
|
|
397
396
|
// Set up preview layer session in the same configuration block
|
|
398
397
|
if let layer = self.previewLayer {
|
|
399
398
|
layer.session = captureSession
|
|
@@ -716,7 +715,6 @@ extension CameraController {
|
|
|
716
715
|
gridOverlayView = nil
|
|
717
716
|
}
|
|
718
717
|
|
|
719
|
-
|
|
720
718
|
func updateVideoOrientation() {
|
|
721
719
|
// Get orientation in a thread-safe way
|
|
722
720
|
let videoOrientation = self.getVideoOrientation()
|
|
@@ -771,14 +769,14 @@ extension CameraController {
|
|
|
771
769
|
if device.supportsSessionPreset(.hd4K3840x2160) { return .hd4K3840x2160 }
|
|
772
770
|
if device.supportsSessionPreset(.hd1920x1080) { return .hd1920x1080 }
|
|
773
771
|
if device.supportsSessionPreset(.hd1280x720) { return .hd1280x720 }
|
|
774
|
-
if device.supportsSessionPreset(.high)
|
|
775
|
-
if device.supportsSessionPreset(.photo)
|
|
772
|
+
if device.supportsSessionPreset(.high) { return .high }
|
|
773
|
+
if device.supportsSessionPreset(.photo) { return .photo } // safe, though 4:3
|
|
776
774
|
return .vga640x480
|
|
777
775
|
} else {
|
|
778
776
|
// 4:3 or unknown: prefer photo → high → 1080p → 720p → vga
|
|
779
|
-
if device.supportsSessionPreset(.photo)
|
|
780
|
-
if device.supportsSessionPreset(.high)
|
|
781
|
-
if device.supportsSessionPreset(.hd1920x1080){ return .hd1920x1080 }
|
|
777
|
+
if device.supportsSessionPreset(.photo) { return .photo }
|
|
778
|
+
if device.supportsSessionPreset(.high) { return .high }
|
|
779
|
+
if device.supportsSessionPreset(.hd1920x1080) { return .hd1920x1080 }
|
|
782
780
|
if device.supportsSessionPreset(.hd1280x720) { return .hd1280x720 }
|
|
783
781
|
return .vga640x480
|
|
784
782
|
}
|
|
@@ -1097,7 +1095,7 @@ extension CameraController {
|
|
|
1097
1095
|
|
|
1098
1096
|
// Validate crop rect is within image bounds
|
|
1099
1097
|
if cropRect.minX < 0 || cropRect.minY < 0 ||
|
|
1100
|
-
|
|
1098
|
+
cropRect.maxX > imageSize.width || cropRect.maxY > imageSize.height {
|
|
1101
1099
|
print("[CameraPreview] cropImageToAspectRatio - Warning: Crop rect \(cropRect) exceeds image bounds \(imageSize)")
|
|
1102
1100
|
// Adjust crop rect to fit within image bounds
|
|
1103
1101
|
cropRect = cropRect.intersection(CGRect(origin: .zero, size: imageSize))
|