[WP] 워드프레스 포스트에 사진의 EXIF 정보 출력하기 #4

기존에 사용하던 코드가 동일 포스트에서 같은 사진을 두 번이상 사용하면 사용횟수만큼 EXIF 정보가 중복 출력되는 문제가 있어 이 부분을 수정했다.

<?php

add_filter ('the_content', 'print_exif_info', 100);

// EXIF 정보 출력
function print_exif_info($content)
{
    if(is_single()) {
        if(!$content)
            return $content;

        $photos = get_post_photos($content);

        if(empty($photos))
            return $content;

        foreach($photos as $value) {
            $content = str_replace($value['match'], $value['match'].$value['exif'], $content);
        }
    }

    return $content;
}

// 포스트내 사진 src 및 exif 정보 얻음
function get_post_photos($content)
{
    $photos = array();

    $upload_info = wp_upload_dir();
    $upload_dir = $upload_info['basedir'];
    $upload_url = $upload_info['baseurl'];

    //$pattern = '#<a href="([^"]+)" rel="lightbox\[[0-9]+\]"><img[^>]+></a>#is';
    $pattern = '#<a href="([^"]+)"[^>]+><img[^>]+></a>#is';

    preg_match_all($pattern, $content, $matches);

    $count = count($matches[1]);
    $urls  = array();

    if ( $count > 0 ) {
        for ( $i=0; $i<$count; $i++ ) {
            $url = $matches[1][$i];

            if(in_array($url, $urls))
                continue;

            $urls[] = $url;

            // 로컬 파일인지 체크
            if(strpos( $url, $upload_url ) === false) continue;

            // 이미지 경로 설정
            $rel_path = str_replace( $upload_url, '', $url);
            $img_file = $upload_dir . $rel_path;

            // 이미지 파일인지 체크
            if( !is_file($img_file))
                continue;

            $size = @getimagesize($img_file);
            if($size[2] != 2)
                continue;

            $exif_info = get_exif_info($img_file);
            if($exif_info) {
                $exif = conv_exif_info($exif_info);
                $photos[] = array( 'match' => $matches[0][$i], 'src' => $url, 'exif' => $exif );
            }
        }
    }

    return $photos;
}

// EXIF 정보 변환
function conv_exif_info($exif)
{
    if(!$exif)
        return '';

    $sep = false;
    $sp = '<span class="sep"></span>';
    $str = '<p class="post-exif-info">';

    if(isset($exif['Model'])) {
        if($sep)
            $str .= $sp;
        $str .= $exif['Model'];
        $sep = true;
    }

    if(isset($exif['Mode'])) {
        if($sep)
            $str .= $sp;
        $str .= $exif['Mode'];
        $sep = true;
    }

    if(isset($exif['MeteringModel'])) {
        if($sep)
            $str .= $sp;
        $str .= $exif['MeteringMode'];
        $sep = true;
    }

    if(isset($exif['ShutterSpeed'])) {
        if($sep)
            $str .= $sp;
        $str .= $exif['ShutterSpeed'];
        $sep = true;
    }

    if(isset($exif['FNumber'])) {
        if($sep)
            $str .= $sp;
        $str .= $exif['FNumber'];
        $sep = true;
    }

    if(isset($exif['ExposureBias'])) {
        if($sep)
            $str .= $sp;
        $str .= $exif['ExposureBias'];
        $sep = true;
    }

    if(isset($exif['FocalLength'])) {
        if($sep)
            $str .= $sp;
        $str .= $exif['FocalLength'];
        $sep = true;
    }

    if(isset($exif['ISO'])) {
        if($sep)
            $str .= $sp;
        $str .= 'ISO-'.$exif['ISO'];
        $sep = true;
    }

    if(isset($exif['Datetime'])) {
        if($sep)
            $str .= $sp;
        $time = explode(' ', $exif['Datetime']);
        $str .= str_replace(':', '-', $time[0]).' '.$time[1];
        $sep = true;
    }

    $str .= '</p>';
    return $str;
}

// EXIF 정보를 배열로 리턴
function get_exif_info($file)
{
    if(!is_file($file))
        return false;

    // EXIF Data
    $exif = @exif_read_data($file, 'EXIF', 0);

    if($exif === false)
        return false;

    // 제조사
    if(array_key_exists('Make', $exif))
        $result['Maker'] = $exif['Make'];

    // 모델
    if(array_key_exists('Model', $exif))
        $result['Model'] = $exif['Model'];

    // 조리개값
    if(array_key_exists('ApertureFNumber', $exif['COMPUTED']))
        $result['FNumber'] = strtolower($exif['COMPUTED']['ApertureFNumber']);

    // 셔터스피드
    if(array_key_exists('ExposureTime', $exif)) {
        $t = explode("/", $exif['ExposureTime']);
        $t1 = (int)$t[0];
        $t2 = (int)$t[1];

        if($t2 > 0) {
            if($t1 >= $t2) {
                $exp = $t1 / $t2;
            } else {
                $exp = $t1 / $t1 .'/'. floor($t2 / $t1);
            }
        } else {
            $exp = $t1;
        }

        $result['ShutterSpeed'] = $exp.'sec';
    }

    // 촬영모드
    if(array_key_exists('ExposureProgram', $exif)) {
        switch($exif['ExposureProgram']) {
            case 0:
                $mode = 'Auto Mode';
                break;
            case 1:
                $mode = 'Manual';
                break;
            case 2:
                $mode = 'Auto Mode';
                break;
            case 3:
                $mode = 'Aperture Priority';
                break;
            case 4:
                $mode = 'Shutter Priority';
                break;
        }

        $result['Mode'] = $mode;
    }

    // 촬영일시
    if(array_key_exists('DateTimeOriginal', $exif))
        $result['Datetime'] = $exif['DateTimeOriginal'];

    // ISO
    if(array_key_exists('ISOSpeedRatings', $exif)) {
        if(is_array($exif['ISOSpeedRatings']))
            $result['ISO'] = $exif['ISOSpeedRatings'][0];
        else
            $result['ISO'] = $exif['ISOSpeedRatings'];
    }

    // 초점거리
    if(array_key_exists('FocalLength', $exif)) {
        $t = explode("/", $exif['FocalLength']);
        $result['FocalLength'] = round(((int)$t[0] / (int)$t[1]), 1).'mm';
    } else if(array_key_exists('FocalLengthIn35mmFilm', $exif)) {
        $t = explode("/", $exif['FocalLengthIn35mmFilm']);
        $result['FocalLength'] = (int)$t[0] / (int)$t[1].'mm';
    }

    // 노출보정
    if(array_key_exists('ExposureBiasValue', $exif)) {
        $t = explode("/", $exif['ExposureBiasValue']);
        $bias = round(((int)$t[0] / (int)$t[1]), 2);

        $result['ExposureBias'] = $bias.'EV';
    }

    // 측광
    if(array_key_exists('MeteringMode', $exif)) {
        switch($exif['MeteringMode']) {
            case 1:
                $mode = 'Average';
                break;
            case 2:
                $mode = 'Center Weighted Average';
                break;
            case 3:
                $mode = 'Spot';
                break;
            case 5:
                $mode = 'Multi Segment';
                break;
            case 6:
                $mode = 'Partial';
                break;
            default:
                $mode = 'Unknown';
                break;
        }

        $result['MeteringMode'] = $mode;
    }

    // 화이트밸런스
    if(array_key_exists('WhiteBalance', $exif)) {
        switch($exif['WhiteBalance']) {
            case 1:
                $mode = 'Manual';
                break;
            default:
                $mode = 'Auto';
                break;
        }

        $result['WhiteBalance'] = $mode;
    }

    // Flash
    if(array_key_exists('Flash', $exif)) {
        switch($exif['Flash']) {
            case 7:
                $mode = 'On';
                break;
            case 9:
                $mode = 'On Compulsory';
                break;
            case 16:
                $mode = 'Off Compulsory';
                break;
            case 73:
                $mode = 'On Compulsory Red-eye reduction';
                break;
            default:
                $mode = 'Unknown';
                break;
        }

        $result['Flash'] = $mode;
    }

    return $result;
}
?>

위의 코드는 exif.lib.php 파일의 코드이며 이 파일을 사용 중인 테마 디렉토리에 파일을 새로 생성하고 테마의 functions.php 파일 하단에 아래의 코드를 추가해주면 사진 이미지 아래에 EXIF 정보가 출력된다.

// Photo EXIF Display
require ( 'exif.lib.php' );

만약 EXIF 정보가 출력되지 않는다면 포스트 내용 중에서 이미지 소스를 추출하기 위한 get_post_photos 함수 중 정규식 패턴을 지정한 $pattern 값을 변경하면서 테스트를 해야 한다.

편리

PHP와 MariaDB, jQuery 등을 사용해 게시판, 쇼핑몰 솔루션을 개발합니다. 그누보드5와 영카트5 개발에 참여 했습니다. Linux와 Nginx는 물론 WordPress, Git 등에도 관심이 많습니다. 자전거 타기 및 사진 촬영을 취미로 하고 있습니다.

2 thoughts to “[WP] 워드프레스 포스트에 사진의 EXIF 정보 출력하기 #4”

  1. 안녕하세요. 검색 통해서 워드프레스 사진에 EXIF 출력 하는걸 좀 봤는데요…

    제가 관련 지식이 너무 없다 보니, 테마 Function.php 와 exif.lib.php 를 추가했는데도 exif 가 나오질 않는데…

    조금 만 더 자세한 설명 좀 들을 수 있을까요?

    1. 테마 또는 사용 중이신 플러그인에 따라서 위 코드를 그대로 적용하면
      exif 출력이 되지 않을 수 있습니다. 포스트의 html 소스 등을 분석해서
      위 코드 중 $pattern = ‘#<a href=”([^”]+)”[^>]+><img[^>]+>#is’; 부분을
      적절히 수정해줘야만 exif 출력이 가능할 수 있습니다.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.