[WP] 워드프레스 포스트에 사진의 EXIF 정보 출력하기 #2
기존에 적용했던 코드(https://chicpro.dev/9457)에 약간의 문제가 있어 다시 코드를 수정했다. 사소한 문제일 수 있는데 사진을 업로드하고 첨부한 최초의 포스트에서만 exif 정보가 출력되는 것이있었다. 워드프레스의 get_post 함수를 이용해 첨부 이미지의 url 정보를 얻었는데 이게 포스트 하나에서만 적용되는 문제였다. 제한을 풀면 모든 포스트에 적용이 되지만 이렇게 하면 속도가 엄청나게 늦어지는 문제가 발생해서 포스트 컨텐츠에서 정규식을 이용해 원본 이미지 경로를 구하는 방법으로 변경을 했다. 이 블로그에 적용한 lightbox 플러그인 때문에 a 태그에 원본 이미지 경로가 포함되어 있어 가능했다. 이와 다른 경우라면 다른 방법을 찾아야 할 듯..
exif.lib.php 파일만 아래의 코드로 교체하니 이상없이 작동이 되고 있다.
<?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';
preg_match_all($pattern, $content, $matches);
$count = count($matches[1]);
if ( $count > 0 ) {
for ( $i=0; $i<$count; $i++ ) {
$url = $matches[1][$i];
// 로컬 파일인지 체크
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;
}
?>
get_post를 통한 첨부 이미지 url을 얻는 쿼리를 실행하지 않아도 되기 때문에 기분상 속도도 약간 빨라진 것 같은 느낌이다. ㅎㅎ
안녕하세요. 좋은 정보 감사합니다. 질문이 있는데요, 포스팅에서 제시한대로 그대로 적용을 했는데도 불구하고 exif 정보가 출력을 하지 않네요. 더욱 중요한건 저도 bravo 테마이거든요 ㅜㅜ
css에 추가하고 exif.lib.php 만들고 function 에 삽입했는데도 안됩니다. 저의 초보적인 생각으로는 각 포스트의 이미지 하단에 함수를 호출해줘야 할거 같은데 그게 어디있는지를 잘 모르겠네요. 아니면 자동으로 exif를 띄워주는건지요?
답변 주시면 정말 감사하겠습니다.
print_exif_info 함수에서 $photos = get_post_photos($content); 코드 아래에
print_r($photos); 코드를 추가해서 이미지 url 정보 등이 제대로 배열로 출력
되는지 먼저 확인해 보시기 바랍니다. 이미지 정보 등이 없다면 정규식의 패턴을
변경하셔야 합니다. 이 블로그는 lightbox 플러그인이 적용되어 있기 때문에
위에 제시된 것과 같은 패턴을 사용했습니다. 이미지 url 정보를 얻기 위한 패턴을
변경하시면 exif 정보가 출력될 것으로 생각이 됩니다.