php - Display FNumber (aperture) as a number versus a fraction

admin2025-06-04  3

I'm a newbie at even trying to work with PHP, but thinking there may be a simple solution to this. EXIF exposure data is only displaying an "s", so there must be an error.

I'd also like to display FNumber as "Aperture" with common f-stop, such as "f2.8", but it shows a fraction 28/10. Is there PHP code that can be inserted directly to the template file to convert this? In Wordpress image.php, there is code for simplifying fractions, but these values are not being passed through the file - they are being modified directly in the template file. There's definitely something wrong with this...

<dt>EXIF data:</dt>
<dd><ul>
<?php foreach ($exif as $key => $value): 
    if (($key != "Width") && ($key != "Height") && ($key !="DateTime")): ?><li><strong><?php
        if ($key == "model") { 
            echo "Camera"; 
        } elseif ($key == "ExposureTime") { 
            echo "Exposure"; 
            $newvalue = explode("(", $value);
            $newvalue = substr($newvalue[2], 0, -1)."s";
        } elseif ($key == "FNumber") { 
            echo "Aperture"; 
        } else { 
            echo $key; 
        } ?></strong>: <?php if (!$newvalue) { echo $value; } else { echo $newvalue; $newvalue = ''; } ?></li>
    <?php endif; 
endforeach; ?>
</ul></dd></dl>

Here is the var_export($exif) info:

array (
  'Model' => 'Canon EOS 30D',
  'DateTime' => '2006:12:23 08:35:02',
  'ExposureTime' => '1/100',
  'FNumber' => '28/10',
  'ExposureProgram' => 3,
  'ISOSpeedRatings' => 200,
  'ExifVersion' => '0221',
  'ApertureValue' => '194698/65536',
  'ExposureBiasValue' => '-1/3',
  'MeteringMode' => 5,
  'FocalLength' => '70/1',
)

I'm a newbie at even trying to work with PHP, but thinking there may be a simple solution to this. EXIF exposure data is only displaying an "s", so there must be an error.

I'd also like to display FNumber as "Aperture" with common f-stop, such as "f2.8", but it shows a fraction 28/10. Is there PHP code that can be inserted directly to the template file to convert this? In Wordpress image.php, there is code for simplifying fractions, but these values are not being passed through the file - they are being modified directly in the template file. There's definitely something wrong with this...

<dt>EXIF data:</dt>
<dd><ul>
<?php foreach ($exif as $key => $value): 
    if (($key != "Width") && ($key != "Height") && ($key !="DateTime")): ?><li><strong><?php
        if ($key == "model") { 
            echo "Camera"; 
        } elseif ($key == "ExposureTime") { 
            echo "Exposure"; 
            $newvalue = explode("(", $value);
            $newvalue = substr($newvalue[2], 0, -1)."s";
        } elseif ($key == "FNumber") { 
            echo "Aperture"; 
        } else { 
            echo $key; 
        } ?></strong>: <?php if (!$newvalue) { echo $value; } else { echo $newvalue; $newvalue = ''; } ?></li>
    <?php endif; 
endforeach; ?>
</ul></dd></dl>

Here is the var_export($exif) info:

array (
  'Model' => 'Canon EOS 30D',
  'DateTime' => '2006:12:23 08:35:02',
  'ExposureTime' => '1/100',
  'FNumber' => '28/10',
  'ExposureProgram' => 3,
  'ISOSpeedRatings' => 200,
  'ExifVersion' => '0221',
  'ApertureValue' => '194698/65536',
  'ExposureBiasValue' => '-1/3',
  'MeteringMode' => 5,
  'FocalLength' => '70/1',
)
Share Improve this question edited Jan 8, 2019 at 3:26 Dave Romsey 17.9k11 gold badges56 silver badges70 bronze badges asked Jan 7, 2019 at 20:37 GratzoGratzo 134 bronze badges 3
  • Can you do a var_dump() of $exif for us? – Justin Waulters Commented Jan 7, 2019 at 22:32
  • dump is above - you can see that the array values are what appear to be just the raw data, unformatted. It would be great to get the FNumber to f/2.8 instead of 28/10 and ExposureTime to 1/100sec (instead of 1/100) - just add the "sec" to the output (somehow). – Gratzo Commented Jan 8, 2019 at 1:11
  • Thanks for the var_export() it was extremely helpful. Please see my answer below. – Justin Waulters Commented Jan 10, 2019 at 2:44
Add a comment  | 

2 Answers 2

Reset to default 0

Assuming it is appropriate to do so, you can change your code to this:

<dt>EXIF data:</dt>
<dd><ul>
<?php foreach ($exif as $key => $value): 
    if (($key != "Width") && ($key != "Height") && ($key !="DateTime")): ?><li><strong><?php
        if ($key == "model") { 
            echo "Camera"; 
        } elseif ($key == "ExposureTime") { 
            echo "Exposure"; 
            //$newvalue = explode("(", $value);
            //$newvalue = substr($newvalue[2], 0, -1)."s";
              $newvalue = $value . "s"; // see note 1
        } elseif ($key == "FNumber") {
            echo "Aperture";
            $fraction_parts = explode("/", $value);
            $newvalue = $fraction_parts[0] / $fraction_parts[1] // see note 2
        } else { 
            echo $key; 
        } ?></strong>: <?php if (!$newvalue) { echo $value; } else { echo $newvalue; $newvalue = ''; } ?></li>
    <?php endif; 
endforeach; ?>
</ul></dd></dl>

I didn't test it, so please let me know if it doesn't work and i'll fix it.

Note 1 it was only outputting the "s" for the shutter speed because the expode was trying to break the string apart based on ( but there was not a ( in the string. So, when the substr() function was looking at newvalue[2] it wasn't getting anything. Also, you were probably getting a warning from PHP that an array key did not exist (you can check it in your PHP logs).

Since your data from the dump you provided looks like fine output already, I just appended "s" to it.

Note 2 To get the decimal value of the fraction I exploded it by "/" which made an array with the numerator as the first value and the denominator as the second value. Then, since $newvalue is set to print (instead of $value) if it exists, I set $newvalue to the result of dividing the numerator by the denominator.

I hope this helps.

Cheers!

Edit 1 To get it to show as "sec" instead of "s", just change where the code says . "s" to say . "sec". Then, to get it to show "f/" in front of the focal number you can add "f/" . before fraction_parts[0]. Note how the period (.) is used to join strings.

Edit 2 About the additional request posted in the comment below, this is how you can edit other outputs from your $exif array:

<dt>EXIF data:</dt>
<dd><ul>
<?php foreach ($exif as $key => $value): 
    if (($key != "Width") && ($key != "Height") && ($key !="DateTime")): ?><li><strong><?php
        if ($key == "model") { 
            echo "Camera"; 
        } elseif ($key == "ExposureTime") { 
            echo "Exposure"; 
            //$newvalue = explode("(", $value);
            //$newvalue = substr($newvalue[2], 0, -1)."s";
              $newvalue = $value . "s"; // see note 1
        } elseif ($key == "FNumber") {
            echo "Aperture";
            $fraction_parts = explode("/", $value);
            $newvalue = $fraction_parts[0] / $fraction_parts[1] // see note 2
        } elseif ($key == "ExposureProgram") { // see note 3
            echo "Exposure Program";
            $value_definitions = array(
                '2' => "Auto",
                '3' => "Aperture Priority",
                '4' => "Shutter Priority"
            );
            if( array_key_exists( $value, $value_definitions ) ) {
                $newvalue = $value_definitions[$value];
            }
        } else { 
            echo $key; 
        } ?></strong>: <?php if (!$newvalue) { echo $value; } else { echo $newvalue; $newvalue = ''; } ?></li>
    <?php endif; 
endforeach; ?>
</ul></dd></dl>

Note 3 This is a conditional that works just like the other ones. It sets the $newvalue variable which is used to replace the $value variable. However, this one will only set the $newvalue if the $value is one of the keys in the $value_definitions array. If $value matches a key in the $value_definitions array, $newvalue will be set to the value assigned to the matching key.

While you can directly compute the FNumber using eval(), I don't advise doing an eval() function.

In your case 28/10 is equal to 2.8 and then just append f on it. You can check this function that parses the value and then return the value with an f concatenated in the beginning.

function getfStop($fstop){

if(preg_match('/(\d+)(?:\s*)([\+\-\*\/])(?:\s*)(\d+)/', $fstop, $val) !== FALSE){
    $operator = $val[2];

    switch($operator){
        case '+':
            $p = $val[1] + $val[3];
            break;
        case '-':
            $p = $val[1] - $val[3];
            break;
        case '*':
            $p = $val[1] * $val[3];
            break;
        case '/':
            $p = $val[1] / $val[3];
            break;
    }

    return 'f'.$p;
   }
}

To use this function, just pass the value of FNumber e.g. getfStop(THE_VALUE_OF_FNumber); and that should work I believe.

Hope this helps!

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1749023418a315705.html

最新回复(0)