mirror of git://jb55.com/damus
privacy: add function to strip location data from photos
Add a function to strip GPS data from images before uploading to hosting service. Lightning-address: kernelkind@getalby.com Signed-off-by: kernelkind <kernelkind@gmail.com> Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
parent
58326f679e
commit
8d815fe4d6
|
@ -628,6 +628,8 @@
|
|||
E02B54182B4DFADA0077FF42 /* Bech32ObjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E02B54172B4DFADA0077FF42 /* Bech32ObjectTests.swift */; };
|
||||
E04A37C62B544F090029650D /* URIParsing.swift in Sources */ = {isa = PBXBuildFile; fileRef = E04A37C52B544F090029650D /* URIParsing.swift */; };
|
||||
E0E024112B7C19C20075735D /* TranslationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0E024102B7C19C20075735D /* TranslationTests.swift */; };
|
||||
E06336AA2B75832100A88E6B /* ImageMetadataTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E06336A92B75832100A88E6B /* ImageMetadataTest.swift */; };
|
||||
E06336AB2B75850100A88E6B /* img_with_location.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = E06336A82B7582E000A88E6B /* img_with_location.jpeg */; };
|
||||
E4FA1C032A24BB7F00482697 /* SearchSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FA1C022A24BB7F00482697 /* SearchSettingsView.swift */; };
|
||||
E990020F2955F837003BBC5A /* EditMetadataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E990020E2955F837003BBC5A /* EditMetadataView.swift */; };
|
||||
E9E4ED0B295867B900DD7078 /* ThreadView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E4ED0A295867B900DD7078 /* ThreadView.swift */; };
|
||||
|
@ -1404,6 +1406,8 @@
|
|||
E02B54172B4DFADA0077FF42 /* Bech32ObjectTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bech32ObjectTests.swift; sourceTree = "<group>"; };
|
||||
E04A37C52B544F090029650D /* URIParsing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URIParsing.swift; sourceTree = "<group>"; };
|
||||
E0E024102B7C19C20075735D /* TranslationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslationTests.swift; sourceTree = "<group>"; };
|
||||
E06336A82B7582E000A88E6B /* img_with_location.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = img_with_location.jpeg; sourceTree = "<group>"; };
|
||||
E06336A92B75832100A88E6B /* ImageMetadataTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageMetadataTest.swift; sourceTree = "<group>"; };
|
||||
E4FA1C022A24BB7F00482697 /* SearchSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchSettingsView.swift; sourceTree = "<group>"; };
|
||||
E990020E2955F837003BBC5A /* EditMetadataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditMetadataView.swift; sourceTree = "<group>"; };
|
||||
E9E4ED0A295867B900DD7078 /* ThreadView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadView.swift; sourceTree = "<group>"; };
|
||||
|
@ -2471,6 +2475,7 @@
|
|||
4CE6DEF627F7A08200C66700 /* damusTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E06336A72B7582D600A88E6B /* Assets */,
|
||||
D72A2D032AD9C165002AFF62 /* Mocking */,
|
||||
4C9B0DEC2A65A74000CBDA21 /* Util */,
|
||||
4C0C03962A61E2670098B3B8 /* Fixtures */,
|
||||
|
@ -2507,6 +2512,7 @@
|
|||
D7315A2B2ACDF4DA0036E30A /* DamusCacheManagerTests.swift */,
|
||||
B501062C2B363036003874F5 /* AuthIntegrationTests.swift */,
|
||||
E0E024102B7C19C20075735D /* TranslationTests.swift */,
|
||||
E06336A92B75832100A88E6B /* ImageMetadataTest.swift */,
|
||||
);
|
||||
path = damusTests;
|
||||
sourceTree = "<group>";
|
||||
|
@ -2695,6 +2701,14 @@
|
|||
path = DamusNotificationService;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E06336A72B7582D600A88E6B /* Assets */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E06336A82B7582E000A88E6B /* img_with_location.jpeg */,
|
||||
);
|
||||
path = Assets;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F71694E82A66221E001F4053 /* Onboarding */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -2918,6 +2932,7 @@
|
|||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E06336AB2B75850100A88E6B /* img_with_location.jpeg in Resources */,
|
||||
4C0C039A2A61E27B0098B3B8 /* bool_setting.wasm in Resources */,
|
||||
4C0C03992A61E27B0098B3B8 /* primal.wasm in Resources */,
|
||||
);
|
||||
|
@ -3452,6 +3467,7 @@
|
|||
B501062D2B363036003874F5 /* AuthIntegrationTests.swift in Sources */,
|
||||
4CB883AE2976FA9300DC99E7 /* FormatTests.swift in Sources */,
|
||||
D72A2D052AD9C1B5002AFF62 /* MockDamusState.swift in Sources */,
|
||||
E06336AA2B75832100A88E6B /* ImageMetadataTest.swift in Sources */,
|
||||
4C363AA02828A8DD006E126D /* LikeTests.swift in Sources */,
|
||||
4C90BD1C283AC38E008EE7EF /* Bech32Tests.swift in Sources */,
|
||||
50A50A8D29A09E1C00C01BE7 /* RequestTests.swift in Sources */,
|
||||
|
|
|
@ -211,3 +211,31 @@ func process_image_metadatas(cache: EventCache, ev: NostrEvent) {
|
|||
}
|
||||
}
|
||||
|
||||
func removeGPSDataFromImage(fromImageURL imageURL: URL) -> Bool {
|
||||
guard let source = CGImageSourceCreateWithURL(imageURL as CFURL, nil) else {
|
||||
print("Failed to create image source.")
|
||||
return false
|
||||
}
|
||||
let data = NSMutableData()
|
||||
guard let type = CGImageSourceGetType(source),
|
||||
let destination = CGImageDestinationCreateWithData(data, type, 1, nil) else {
|
||||
print("Failed to create image destination.")
|
||||
return false
|
||||
}
|
||||
|
||||
let removeGPSProperties: CFDictionary = [kCGImagePropertyGPSDictionary as String: kCFNull] as CFDictionary
|
||||
|
||||
CGImageDestinationAddImageFromSource(destination, source, 0, removeGPSProperties)
|
||||
if CGImageDestinationFinalize(destination) {
|
||||
do {
|
||||
try data.write(to: imageURL, options: .atomic)
|
||||
return true
|
||||
} catch {
|
||||
print("Failed to write image data: \(error)")
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
print("Failed to finalize image destination.")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 321 KiB |
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// LocationStrippingTest.swift
|
||||
// damusTests
|
||||
//
|
||||
// Created by KernelKind on 2/8/24.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import damus
|
||||
|
||||
final class ImageMetadataTest : XCTestCase {
|
||||
func testRemoveGPSData() {
|
||||
let bundle = Bundle(for: type(of: self))
|
||||
guard let imageURL = bundle.url(forResource: "img_with_location", withExtension: "jpeg"),
|
||||
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
|
||||
else {
|
||||
XCTFail("Failed to load test image from bundle")
|
||||
return
|
||||
}
|
||||
|
||||
let testOutputURL = documentsDirectory.appendingPathComponent("img_with_location.jpeg")
|
||||
do {
|
||||
if FileManager.default.fileExists(atPath: testOutputURL.path) {
|
||||
try FileManager.default.removeItem(at: testOutputURL)
|
||||
}
|
||||
try FileManager.default.copyItem(at: imageURL, to: testOutputURL)
|
||||
} catch {
|
||||
XCTFail("Setup failed: Unable to copy test image to documents directory - \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
let removalSuccess = removeGPSDataFromImage(fromImageURL: testOutputURL)
|
||||
|
||||
XCTAssertTrue(removalSuccess, "GPS data removal was not successful")
|
||||
|
||||
guard let sourceAfterRemoval = CGImageSourceCreateWithURL(testOutputURL as CFURL, nil),
|
||||
let imagePropertiesAfterRemoval = CGImageSourceCopyPropertiesAtIndex(sourceAfterRemoval, 0, nil) as? [String: Any],
|
||||
imagePropertiesAfterRemoval[kCGImagePropertyGPSDictionary as String] == nil else {
|
||||
XCTFail("GPS data was not removed from the image")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue