[WP] 워드프레스 포스트에 사진의 EXIF 정보 출력하기
이전에 작성했던 [WP] 워드프레스 포스트에 사진의 EXIF 정보 출력 포스트 내용을 조금 더 수정했다. 이전 포스트대로 적용해도 EXIF 출력은 되지만 근본적인 문제가 있는데 포스트 사이즈에 첨부할 때 full 사이즈로 등록해주지 않으면 EXIF 정보가 출력되지 않는 것이다. 그리고 이전 포스트에서도 언급했지만 경로 문제가 있어 이 부분들을 수정해서 조금 더 범용적으로 사용할 수 있도록 코드를 수정했다. 플러그인을 제작하면 좋겠지만 아직 그런 실력은 안되기 때문에.. ^^;
이번에는 WordPress 내장 함수들을 사용해서 처리하도록 코드의 많은 부분을 수정했다. 포스트에 포함된 이미지의 원본 URL을 구하고 이것을 바탕으로 EXIF 정보를 구하고 그런 후 포스트내의 이미지출력 부분을 문자치환하는 방법으로 처리하도록 했다. 아침 밥 먹고 시작한 일이 점심 먹고 나서 끝났으니 꽤 오래도록 작업을 한 셈이다. 실력이 좀 더 출중하면 금방 끝날 수도 있는 작업이어겠지만 아직 실랙이 너무나도 미천하여 효율성이 떨어진다. ㅋㅋ
우선 아래는 CSS 코드이다. 워드프레스 테마의 style.css 등에 추가한다. 스타일은 적당히 수정하면 된다.
/* EXIF Info */
.post-exif-info {
display: block;
margin: 5px 0 20px;
text-align: center;
color: #999;
font-size: 11px;
line-height: 11px;
}
.post-exif-info .sep {
padding: 0 8px;
}
그리고 아래가 exif.lib.php 파일의 코드이다.
<?php
add_filter ('the_content', 'print_exif_info');
// EXIF 정보 출력
function print_exif_info($content)
{
if(is_single()) {
if(!$content)
return $content;
$photos = get_post_photos();
if(empty($photos))
return $content;
foreach($photos as $value) {
$finfo = pathinfo($value['src']);
$ext = $finfo['extension'];
$src = preg_replace('/.'.$ext.'$/', '', $value['src']);
$pattern = '/<img[^>]*src=['"]?'.str_replace('/', '/', $src).'[^>'"]+['"]?[^>]*>/';
preg_match_all($pattern, $content, $matchs);
for($i=0; $i<count($matchs[0]); $i++) {
$content = str_replace($matchs[0][$i].'', $matchs[0][$i].''.$value['exif'], $content);
}
}
}
return $content;
}
// 포스트내 사진 src 및 exif 정보 얻음
function get_post_photos()
{
$post = get_post( get_the_ID() );
$photos = array();
$args = array(
'post_type' => 'attachment',
'numberposts' => -1,
'post_mime_type' => 'image',
'post_status' => null,
'post_parent' => $post->ID
);
$upload_info = wp_upload_dir();
$upload_dir = $upload_info['basedir'];
$upload_url = $upload_info['baseurl'];
$attachments = get_posts( $args );
if ( $attachments ) {
foreach ( $attachments as $attachment ) {
$url = wp_get_attachment_url( $attachment->ID );
// 로컬 파일인지 체크
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( 'src' => $url, 'exif' => $exif );
}
}
}
return $photos;
}
// EXIF 정보 변환
function conv_exif_info($exif)
{
if(!$exif)
return '';
$sep = false;
$sp = '<span class="sep"></span>';
$str = '<span 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['Flash'])) {
if($sep)
$str .= $sp;
$str .= $exif['Flash'];
$sep = true;
}
$str .= '</span>';
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($t1 >= $t2) {
$exp = $t1 / $t2;
} else {
$exp = $t1 / $t1 .'/'. floor($t2 / $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 파일에 아래의 코드를 추가한다.
// Photo EXIF Display
include ( 'exif.lib.php' );
이 방법을 적용하게 되면 사진 첨부때 full 사이즈가 아닌 large, medium 등의 사이즈를 선택해서 등록할 수가 있다. full 사이즈로 등록하게 되면 사진이 많은 경우 로딩 시간에 오래 걸리게 되는데 이 문제를 어느정도는 해결할 수 있다.
아래는 작업을하면서 참고한 자료이다.
http://codex.wordpress.org/Function_Reference/get_the_ID
http://codex.wordpress.org/Function_Reference/get_post
http://codex.wordpress.org/Function_Reference/wp_get_attachment_url