Skip to content

Commit

Permalink
Merge pull request #60 from iiKurt/extract-plist
Browse files Browse the repository at this point in the history
Extract plist with -e
  • Loading branch information
mczachurski authored May 22, 2022
2 parents bffdeb8 + 4df83d8 commit 447854d
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 23 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ wallpapper -e Catalina.heic

Metadata should be printed as output on the console.

Also it's possible to extract and save whole `plist` file:

```bash
wallpapper -e Catalina.heic -o output.plist
```

### Calculating sun position

If your photos contains GPS Exif metadata and creation time you can use `wallpapper-exif` application to generate `json` file with Sun `altitude` and `azimuth`. Example application usage:
Expand Down
7 changes: 4 additions & 3 deletions Sources/Wallpapper/Program.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Program {

let consoleIO = ConsoleIO()
var inputFileName = ""
var outputFileName = "output.heic"
var outputFileName: String? = nil
var shouldExtract = false

func run() -> Bool {
Expand Down Expand Up @@ -46,7 +46,8 @@ class Program {

let baseURL = fileURL.deletingLastPathComponent()
let wallpaperGenerator = WallpaperGenerator()
try wallpaperGenerator.generate(pictureInfos: pictureInfos, baseURL: baseURL, outputFileName: self.outputFileName);
let fileName = self.outputFileName ?? "output.heic"
try wallpaperGenerator.generate(pictureInfos: pictureInfos, baseURL: baseURL, outputFileName: fileName);
} catch (let error as WallpapperError) {
self.consoleIO.writeMessage("Unexpected error occurs: \(error.message)", to: .error)
return false
Expand All @@ -65,7 +66,7 @@ class Program {
let inputFileContents = try Data(contentsOf: fileURL)

let dynamicWallpaperExtractor = DynamicWallpaperExtractor()
try dynamicWallpaperExtractor.extract(imageData: inputFileContents)
try dynamicWallpaperExtractor.extract(imageData: inputFileContents, outputFileName: self.outputFileName)
} catch {
self.consoleIO.writeMessage("Error occurs during metadata extraction: \(error)", to: .error)
return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import AppKit
import AVFoundation

public class DynamicWallpaperExtractor {

let consoleIO = ConsoleIO()

public init() {
}

public func extract(imageData: Data) throws {
public func extract(imageData: Data, outputFileName: String?) throws {
let imageSource = CGImageSourceCreateWithData(imageData as CFData, nil)
guard let imageSourceValue = imageSource else {
throw MetadataExtractorError.imageSourceNotCreated
Expand All @@ -27,67 +28,87 @@ public class DynamicWallpaperExtractor {
CGImageMetadataEnumerateTagsUsingBlock(imageMetadataValue, nil, nil) { (value, metadataTag) -> Bool in

let valueString = value as String
print("---------------------------------------------------")
print("Metadata key: \(valueString)")
self.consoleIO.writeMessage("---------------------------------------------------")
self.consoleIO.writeMessage("Metadata key: \(valueString)")

let tag = CGImageMetadataTagCopyValue(metadataTag)

guard let valueTag = tag as? String else {
print("\tError during convert tag into string")
self.consoleIO.writeMessage("\tError during convert tag into string")
return true
}

if valueString.starts(with: "apple_desktop:solar") || valueString.starts(with: "apple_desktop:h24") {
guard let decodedData = Data(base64Encoded: valueTag) else {
print("\tError during convert tag into binary data")
self.consoleIO.writeMessage("\tError during convert tag into binary data")
return true
}

if let outputFileName = outputFileName {
self.saveImage(decodedData: decodedData, outputFileName: outputFileName)
}

let decoder = PropertyListDecoder()
guard let sequenceInfo = try? decoder.decode(SequenceInfo.self, from: decodedData) else {
print("\tError during convert tag into object")
self.consoleIO.writeMessage("\tError during convert tag into object")
return true
}

if let apperance = sequenceInfo.apperance {
print("[APPERANCE]")
print("\timage index: \(apperance.darkIndex), dark")
print("\timage index: \(apperance.lightIndex), light")
self.consoleIO.writeMessage("[APPERANCE]")
self.consoleIO.writeMessage("\timage index: \(apperance.darkIndex), dark")
self.consoleIO.writeMessage("\timage index: \(apperance.lightIndex), light")
}

if let solarItems = sequenceInfo.sequenceItems {
print("[SOLAR]")
self.consoleIO.writeMessage("[SOLAR]")
for solarItem in solarItems {
print("\timage index: \(solarItem.imageIndex), azimuth: \(solarItem.azimuth), altitude: \(solarItem.altitude)")
self.consoleIO.writeMessage("\timage index: \(solarItem.imageIndex), azimuth: \(solarItem.azimuth), altitude: \(solarItem.altitude)")
}
}

if let timeItems = sequenceInfo.timeItems {
print("[TIME]")
self.consoleIO.writeMessage("[TIME]")
for timeItem in timeItems {
print("\timage index: \(timeItem.imageIndex), time: \(timeItem.time)")
self.consoleIO.writeMessage("\timage index: \(timeItem.imageIndex), time: \(timeItem.time)")
}
}
} else if valueString.starts(with: "apple_desktop:apr") {
guard let decodedData = Data(base64Encoded: valueTag) else {
print("\tError during convert tag into binary data")
self.consoleIO.writeMessage("\tError during convert tag into binary data")
return false
}

if let outputFileName = outputFileName {
self.saveImage(decodedData: decodedData, outputFileName: outputFileName)
}

let decoder = PropertyListDecoder()
guard let apperance = try? decoder.decode(Apperance.self, from: decodedData) else {
print("\tError during convert tag into object")
self.consoleIO.writeMessage("\tError during convert tag into object")
return false
}

print("[APPERANCE]")
print("\timage index: \(apperance.darkIndex), dark")
print("\timage index: \(apperance.lightIndex), light")
self.consoleIO.writeMessage("[APPERANCE]")
self.consoleIO.writeMessage("\timage index: \(apperance.darkIndex), dark")
self.consoleIO.writeMessage("\timage index: \(apperance.lightIndex), light")
} else {
print("\tvalue: \(valueTag)")
self.consoleIO.writeMessage("\tvalue: \(valueTag)")
}

return true
}
}

private func saveImage(decodedData: Data, outputFileName: String) {
let path = URL(fileURLWithPath: FileManager.default.currentDirectoryPath)
let plistFile = path.appendingPathComponent(outputFileName)
do {
try decodedData.write(to: plistFile)
self.consoleIO.writeMessage("\tSaved plist file: \(plistFile)")
}
catch {
self.consoleIO.writeMessage("\tError during writing plist file: \(plistFile)")
}
}
}

0 comments on commit 447854d

Please sign in to comment.