0

EDIT: Resolved, I answered the question below.

I am using the following to get metadata for PHAssets:

let data = NSData.init(contentsOf: url!)!
if let imageSource = CGImageSourceCreateWithData(data, nil) { 
    let metadata = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)! as NSDictionary
}

The metadata dictionary has all the values I am looking for. However a few fields like ShutterSpeedValue, ExposureTime which have fractions get printed as decimals:

ExposureTime = "0.05"
ShutterSpeedValue = "4.321956769055745"

When I look at this data on my Mac's preview app and exiftool, it shows:

ExposureTime = 1/20
ShutterSpeedValue = 1/20

How can I get the correct fraction string instead of the decimal string?

EDIT: I tried simply converting the decimal to a fraction string using this from SO code but this isn't correct:

func rationalApproximation(of x0 : Double, withPrecision eps : Double = 1.0E-6) -> String {
    var x = x0
    var a = x.rounded(.down)
    var (h1, k1, h, k) = (1, 0, Int(a), 1)

    while x - a > eps * Double(k) * Double(k) {
        x = 1.0/(x - a)
        a = x.rounded(.down)
        (h1, k1, h, k) = (h, k, h1 + Int(a) * h, k1 + Int(a) * k)
    }
    return "\(h)/\(k)"
}

As you notice, the decimal value of ShutterSpeedValue printed as 4.321956769055745 isn't even equal to 1/20.

StarGeek
  • 4,948
  • 2
  • 19
  • 30
  • That code [looks familiar](https://stackoverflow.com/a/35895607/1187415) – Martin R Apr 05 '19 at 04:33
  • @MartinR yep. It's your code. As I mentioned in my question "using this from SO code". Btw, by "not correct", I am not referring to the code. I am referring to how 1/20 isn't equal to `4.321956769055745`, so simply converting a decimal to fraction using math isn't enough. Something else is needed I think. – sudoExclaimationExclaimation Apr 05 '19 at 04:35

1 Answers1

0

Resolved.

As per

https://www.dpreview.com/forums/post/54376235

ShutterSpeedValue is defined as APEX value, where:
ShutterSpeed = -log2(ExposureTime)

So -log2(1/20) is 4.3219, just as what I observed.

So to get the ShutterSpeedValue, I use the following:

"1/\(ceil(pow(2, Double(4.321956769055745))))"

I tested 3 different photos and 1/20, 1/15 and 1/1919 were all correctly calculated using your formula.