[WP] 워드프레스 포스트에 사진의 EXIF 정보 출력
워드프레스로 블로그를 이전하고 아쉬웠던 기능 중에 하나가 사진의 EXIF 정보 출력이다. 플러그인을 찾아서 설치를 해봤지만 블로그에 접속할 수 없을 정도로 속도가 느려져서 사용하지 않고 있었는데.. 결국은 아쉬운 사람이 우물을 판다고.. PHP로 코드를 짜서 사진의 EXIF 정보가 출력되도록 해봤다. 지금 사용하고 있는 테마에 맞춰서 작업을 했기 때문에 다른 테마에서도 정상적으로 작동할 것이라고는 장담할 수 없다.
바로 위 이미지처럼 사진 아래에 간단한 EXIF 정보가 출력된다. 플러그인 방식으로 만들면 좋겠지만 아직 그런 실력은 없어서.. PHP 코드를 직접 추가하는 방법을 택했다. PHP 코드는 테만의 functions.php 파일에 추가하면 된다. 지난 번 애드센스를 추가하는 것과 같은 방식으로 처리하도록 했다.
우선 아래 코드를 테마의 functions.php 파일에 추가한다.
include ( 'exif.lib.php' );
add_filter ('the_content', 'print_exif_info');
그런 다음 아래 코드를 exif.lib.php 파일로 만들어 functions.php 파일과 같은 위치에 저장한다.
<?php
// EXIF 정보 출력
function print_exif_info($content)
{
if(is_single()) {
if(!$content)
return $content;
$images = get_post_images($content);
if(empty($images))
return $content;
for($i=0; $i<count($images[1]); $i++) {
$p = parse_url($images[1][$i]);
$srcfile = $_SERVER['DOCUMENT_ROOT'].$p['path'];
if(!is_file($srcfile) || !preg_match("/jpe?g$/i", $srcfile))
continue;
$exif = get_exif_info($srcfile);
if(!empty($exif)) {
$str = conv_exif_info($exif);
$content = str_replace($images[0][$i].'', $images[0][$i].'</a>'.$str, $content);
}
}
}
return $content;
}
// EXIF 정보 변환
function conv_exif_info($exif)
{
if(!$exif)
return '';
$sep = false;
$sp = ' ';
$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;
}
// 포스트내 이미지 src 얻음
function get_post_images($contents)
{
if(!$contents)
return '';
// $contents 중 img 태그 추출
$pattern = "/<img[^>]*src=['"]?([^>'"]+[^>'"]+)['"]?[^>]*>/";
preg_match_all($pattern, $contents, $matchs);
return $matchs;
}
// 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 정보가 나오는 영역의 CSS 정보는 아래와 같다. 아래 코드를 테마의 style.css 파일에 추가해준다.
.post-exif-info {
display: block;
margin: -5px 0 20px;
font-family: Tahoma;
font-size: 11px;
}
css 내용은 자신의 환경에 맞게 수정하면 된다.
위 코드에서 문제가 될 수 있는 부분은 사진파일의 경로를 처리하는 부분이다.
$p = parse_url($images[1][$i]);
$srcfile = $_SERVER['DOCUMENT_ROOT'].$p['path'];
사용하는 호스팅의 환경에 따라서 DOCUMENT_ROOT의 경로가 상이하기 때문에 이 부분은 직접 수정을 해야만 한다.