[WP] 워드프레스 포스트에 사진의 EXIF 정보 출력하기 #3
워드프레스 4.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]);
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;
}
?>
위의 코드는 exif.lib.php 파일의 코드이며 이 파일을 사용 중인 테마 디렉토리에 파일을 새로 생성하고 테마의 functions.php 파일 하단에 아래의 코드를 추가해주면 사진 이미지 아래에 EXIF 정보가 출력된다.
// Photo EXIF Display
require ( 'exif.lib.php' );
만약 EXIF 정보가 출력되지 않는다면 포스트 내용 중에서 이미지 소스를 추출하기 위한 get_post_photos 함수 중 정규식 패턴을 지정한 $pattern 값을 변경하면서 테스트를 해야 한다.