开发者

Parsing EXIF's "ExposureTime" using PHP

开发者 https://www.devze.com 2023-01-03 09:37 出处:网络
Re, One photo with exposure being 1/640 has the EXIF fi开发者_如何学编程eld of \"ExposureTime\" eq. \"15625/10000000\". I am not sure why some photos display this value in a readable format (e.g., \"

Re,

One photo with exposure being 1/640 has the EXIF fi开发者_如何学编程eld of "ExposureTime" eq. "15625/10000000". I am not sure why some photos display this value in a readable format (e.g., "1/100"), but I need to convert this "15625" back to "1/640". How? :)

Thanks.


It's simple mathematics: simply divide the top and bottom of the fraction by the top value.

  15625 / 10000000
= (15625/15625) / (10000000/15625)
= 1 / 640

In PHP, you can do it like this:

$exposure = "15625/10000000";
$parts = explode("/", $exposure);
$exposure = implode("/", array(1, $parts[1]/$parts[0]));

echo $exposure;


I improved upon ZZ Coders implementation with a few sanity checks and special cases. It seems to work well with my images with several special cases thrown at it. Please let me know if there are any issues and we'll improve it.

// Exposure Time
$exif = exif_read_data($fullPath, 'IFD0', true);
$arrExposureTime = explode('/', $exif['EXIF']['ExposureTime']);
// Sanity check for zero denominator.
if ($arrExposureTime[1] == 0) {
    $ExposureTime = '<sup>1</sup>/? sec';
// In case numerator is zero.
} elseif ($arrExposureTime[0] == 0) {
    $ExposureTime = '<sup>0</sup>/' . $arrExposureTime[1] . ' sec';
// When denominator is 1, display time in whole seconds, minutes, and/or hours.
} elseif ($arrExposureTime[1] == 1) {
    // In the Seconds range.
    if ($arrExposureTime[0] < 60) {
        $ExposureTime = $arrExposureTime[0] . ' s';
    // In the Minutes range.
    } elseif (($arrExposureTime[0] >= 60) && ($arrExposureTime[0] < 3600)) {
        $ExposureTime = gmdate("i\m:s\s", $arrExposureTime[0]);
    // In the Hours range.
    } else {
        $ExposureTime = gmdate("H\h:i\m:s\s", $arrExposureTime[0]);
    }
// When inverse is evenly divisable, show reduced fractional exposure.
} elseif (($arrExposureTime[1] % $arrExposureTime[0]) == 0) {
    $ExposureTime = '<sup>1</sup>/' . $arrExposureTime[1]/$arrExposureTime[0] . ' sec';
// If the value is greater or equal to 3/10, which is the smallest standard
// exposure value that doesn't divid evenly, show it in decimal form.
} elseif (($arrExposureTime[0]/$arrExposureTime[1]) >= 3/10) { 
    $ExposureTime = round(($arrExposureTime[0]/$arrExposureTime[1]), 1) . ' sec';
// If all else fails, just display it as it was found.
} else {
    $ExposureTime = '<sup>' . $arrExposureTime[0] . '</sup>/' . $arrExposureTime[1] . ' sec';
}


This is the code I use to normalize the exposure,

                    if (($bottom % $top) == 0) {
                            $data = '1/'.round($bottom/$top, 0).' sec';
                    }       else {
                            if ($bottom == 1) {
                                    $data = $top.' sec';
                            } else {
                                    $data = $top.'/'.$bottom.' sec';
                            }
                    }

It handles most exposures correctly but I see some weird ones once a while.


You can use Euclid's algorithm to find the greatest common divisor, which will help you reduce the fraction.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号