Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rounding error in Shutter Speed value? #352

Open
TheHulmaren opened this issue Dec 12, 2023 · 1 comment
Open

Rounding error in Shutter Speed value? #352

TheHulmaren opened this issue Dec 12, 2023 · 1 comment

Comments

@TheHulmaren
Copy link

Hello, I'm using this library to get EXIF data from images, and encountered a possible rounding error when getting the Shutter Speed tag value.

For example, when the actual shutter speed of the image is 1/30 sec, but somehow in the processed tag description, it says 1/29 sec.

What I'm thinking is that the rounding logic in the method below is a source of the problem.

protected string? GetShutterSpeedDescription(int tagId)
        {
            // I believe this method to now be stable, but am leaving some alternative snippets of
            // code in here, to assist anyone who's looking into this (given that I don't have a public CVS).
            //        float apexValue = _directory.getFloat(ExifSubIFDDirectory.TAG_SHUTTER_SPEED);
            //        int apexPower = (int)Math.pow(2.0, apexValue);
            //        return "1/" + apexPower + " sec";
            // TODO test this method
            // thanks to Mark Edwards for spotting and patching a bug in the calculation of this
            // description (spotted bug using a Canon EOS 300D)
            // thanks also to Gli Blr for spotting this bug
            if (!Directory.TryGetSingle(tagId, out float apexValue))
                return null;

            if (apexValue <= 1)
            {
                var apexPower = (float)(1 / Math.Exp(apexValue * Math.Log(2)));
                var apexPower10 = (long)Math.Round(apexPower * 10.0);
                var fApexPower = apexPower10 / 10.0f;
                return fApexPower + " sec";
            }
            else
            {
                var apexPower = (int)Math.Exp(apexValue * Math.Log(2));
                return "1/" + apexPower + " sec";
            }
        }

For the case when apexValue > 1, I think the code should be like this:

else
            {
                var apexPower = (int)Math.Round(Math.Exp(apexValue * Math.Log(2)));
                return "1/" + apexPower + " sec";
            }

So compared to just naively converting it to int, the value falls to the nearest integer.

I started using this library about 5 hours ago, and new to this area.
Therefore I could be wrong about this.

Thank you for reading.

@drewnoakes
Copy link
Owner

I believe you're right!

Would you like to submit a pull request? Apologies for the delay in responding. This got lost in my notifications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants