Last active
August 29, 2015 14:24
-
-
Save ZE3kr/8f3e68c12f694112e5c0 to your computer and use it in GitHub Desktop.
Read and formatting the EXIF data from UPYUN and generate a JavaScript code. Support GPS data and use Mapbox. (Used in https://ze3kr.tlo.xyz and can across domain)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<? | |
$mmc = memcache_init(); | |
/** | |
* 将分数转化为浮点数 | |
**/ | |
function Deci_Con($coordPart){ | |
$parts = explode('/', $coordPart);// 将 "/" 的两边数据转化为数组 | |
if (count($parts) <= 0) | |
return 0; | |
if (count($parts) == 1) | |
return $parts[0]; | |
return floatval($parts[0]) / floatval($parts[1]); | |
} | |
/** | |
* 将 EXIF 中经纬度坐标转化为浮点数 | |
* @see http://stackoverflow.com/questions/2526304/php-extract-gps-exif-data | |
**/ | |
function getGps($exifCoord, $hemi) { | |
$exifCoord = explode(",", $exifCoord); | |
$degrees = count($exifCoord) > 0 ? Deci_Con($exifCoord[0]) : 0; | |
$minutes = count($exifCoord) > 1 ? Deci_Con($exifCoord[1]) : 0; | |
$seconds = count($exifCoord) > 2 ? Deci_Con($exifCoord[2]) : 0; | |
$flip = ($hemi == 'W' or $hemi == 'S') ? -1 : 1; | |
return sprintf( "%.6f",$flip * ($degrees + $minutes / 60 + $seconds / 3600) );// 小数点后六位 | |
} | |
$localization = [ | |
"ZH" => [ | |
"Camera" => "相机", | |
"ISO" => "感光度", | |
"Aperture" => "光圈", | |
"Exposure" => "快门速度", | |
"Focal length" => "焦距", | |
"Lens" => "镜头", | |
"HDR" => "HDR 已启用", | |
"Real length" => "实际焦距:", | |
"Exposure Program" => [ | |
"1" => "手动", | |
"2" => "自动(程序曝光)", | |
"3" => "光圈优先", | |
"4" => "快门优先", | |
"5" => "自动(创意)", | |
"6" => "自动(运动)", | |
"7" => "自动(人像)", | |
"8" => "自动(风景)", | |
"9" => "手动(B 门)", | |
], | |
"Program" => "模式", | |
], | |
"EN" => [ | |
"Camera" => "Camera", | |
"ISO" => "Film speed", | |
"Aperture" => "Aperture", | |
"Exposure" => "Shutter speed", | |
"Focal length" => "Focal length", | |
"Lens" => "Camera lens", | |
"HDR" => "HDR is enabled", | |
"Real length" => "Real length:", | |
"Exposure Program" => [ | |
"1" => "Manual", | |
"2" => "Auto (Program exposure)", | |
"3" => "Aperture priority", | |
"4" => "Shutter priority", | |
"5" => "Auto (Creative)", | |
"6" => "Auto (Action)", | |
"7" => "Auto (Portrait)", | |
"8" => "Auto (Landscape)", | |
"9" => "Auto (Blub)", | |
], | |
"Program" => "Program", | |
], | |
]; | |
$in35mmFilmData = [ | |
/** | |
* ███╗ ██╗██╗██╗ ██╗ ██████╗ ███╗ ██╗ | |
* ████╗ ██║██║██║ ██╔╝██╔═══██╗████╗ ██║ | |
* ██╔██╗ ██║██║█████╔╝ ██║ ██║██╔██╗ ██║ | |
* ██║╚██╗██║██║██╔═██╗ ██║ ██║██║╚██╗██║ | |
* ██║ ╚████║██║██║ ██╗╚██████╔╝██║ ╚████║ | |
* ╚═╝ ╚═══╝╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ | |
**/ | |
/* 专业级系列 */ | |
"D1" => 1.52, | |
"D1H" => 1.52, | |
"D1X" => 1.52, | |
"D2X" => 1.52, | |
"D2H" => 1.52, | |
"D2Hs" => 1.52, | |
"D2X" => 1.52, | |
"D2Xs" => 1.52, | |
/* 高档系列 */ | |
"D100" => 1.52, | |
"D200" => 1.52, | |
"D300" => 1.52, | |
"D300S" => 1.52, "D300s" => 1.52, | |
/* 中档系列 */ | |
"D40" => 1.52, | |
"D40x" => 1.52, | |
"D50" => 1.52, | |
"D60" => 1.52, | |
"D70" => 1.52, | |
"D70S" => 1.52, "D300s" => 1.52, | |
"D80" => 1.52, | |
"D90" => 1.52, | |
"D3000" => 1.52, | |
"D3100" => 1.56, | |
"D3200" => 1.55, | |
"D3300" => 1.53, | |
"D5000" => 1.52, | |
"D5100" => 1.52, | |
"D5200" => 1.52, | |
"D5300" => 1.53, | |
"D5500" => 1.52, | |
"D7000" => 1.52, | |
"D7100" => 1.52, | |
"D7200" => 1.52, | |
"Coolpix A" => 1.53, | |
/** | |
* ██████╗ █████╗ ███╗ ██╗ ██████╗ ███╗ ██╗ | |
* ██╔════╝██╔══██╗████╗ ██║██╔═══██╗████╗ ██║ | |
* ██║ ███████║██╔██╗ ██║██║ ██║██╔██╗ ██║ | |
* ██║ ██╔══██║██║╚██╗██║██║ ██║██║╚██╗██║ | |
* ╚██████╗██║ ██║██║ ╚████║╚██████╔╝██║ ╚████║ | |
* ╚═════╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═══╝ | |
**/ | |
/* 专业级系列 */ | |
"EOS 1D" => 1.255, | |
"EOS 1D Mark II" => 1.255, | |
"EOS 1D Mark III" => 1.28, | |
"EOS 1D Mark IV" => 1.29, | |
/* 高档系列 */ | |
"EOS 7D" => 1.62, | |
"EOS 7D Mark II" => 1.62, | |
/* 中档系列 */ | |
"EOS D30" => 1.62, | |
"EOS D60" => 1.62, | |
"EOS 10D" => 1.62, | |
"EOS 20D" => 1.62, | |
"EOS 30D" => 1.62, | |
"EOS 30Da" => 1.62, | |
"EOS 40D" => 1.62, | |
"EOS 50D" => 1.62, | |
"EOS 60D" => 1.62, | |
"EOS 60Da" => 1.62, | |
"EOS 70D" => 1.62, | |
/* 入门系列 */ | |
"EOS 300D" => 1.62, "EOS Rebel" => 1.62, "EOS Kiss" => 1.62, | |
"EOS 350D" => 1.62, "EOS Rebel XT" => 1.62, "EOS Kiss N" => 1.62, | |
"EOS 400D" => 1.62, "EOS Rebel XTi" => 1.62, "EOS Kiss X" => 1.62, | |
"EOS 450D" => 1.62, "EOS Rebel XSi" => 1.62, "EOS Kiss X2" => 1.62, | |
"EOS 500D" => 1.62, "EOS Rebel T1i" => 1.62, "EOS Kiss X3" => 1.62, | |
"EOS 550D" => 1.62, "EOS Rebel T2i" => 1.62, "EOS Kiss X4" => 1.62, | |
"EOS 600D" => 1.62, "EOS Rebel T3i" => 1.62, "EOS Kiss X5" => 1.62, | |
"EOS 650D" => 1.62, "EOS Rebel T4i" => 1.62, "EOS Kiss X6i" => 1.62, | |
"EOS 700D" => 1.62, "EOS Rebel T5i" => 1.62, "EOS Kiss X7i" => 1.62, | |
"EOS 750D" => 1.62, "EOS Rebel T6i" => 1.62, "EOS Kiss X8i" => 1.62, | |
"EOS 760D" => 1.62, "EOS Rebel T6s" => 1.62, "EOS 8000D" => 1.62, | |
"EOS 1100D" => 1.62, "EOS Rebel T3" => 1.62, "EOS Kiss X50" => 1.62, | |
"EOS 1200D" => 1.62, "EOS Rebel T5" => 1.62, "EOS Kiss X70" => 1.62, | |
/* 微单系列 */ | |
"EOS M1" => 1.62, | |
"EOS M2" => 1.62, | |
"EOS M3" => 1.62, | |
]; | |
$fixLens = [ | |
/* | |
"EF70-300mm f/4-5.6L IS USM" => "EF 70-300mm f/4-5.6L IS USM", | |
"EF-S15-85mm f/3.5-5.6 IS USM" => "EF-S 15-85mm f/3.5-5.6 IS USM", | |
*/ | |
]; | |
$camerasLink = [ | |
"iPhone 6" => "asin=B00NQGP5M8&CN=B00OB5T6DM", | |
"Apple iPhone 6" => "asin=B00NQGP5M8&CN=B00OB5T6DM", | |
"HERO4 Silver" => "asin=B00NIYJF6U&CN=B00R24SK4K", | |
"GoPro HERO4 Silver" => "asin=B00NIYJF6U&CN=B00R24SK4K", | |
"Canon EOS 7D" => "asin=B002NEGTTW&CN=B002QB2H98", | |
"Canon EOS 7D Mark II" => "asin=B00NEWZDRG&CN=B00OXKZWX8", | |
]; | |
$lensLink = [ | |
"EF70-300mm f/4-5.6L IS USM" => "asin=B0040Y83X8", | |
"EF-S15-85mm f/3.5-5.6 IS USM" => "asin=B002NEGTTM&CN=B004H3W8WE", | |
]; | |
$catchurl = 'http://tlimage.b0.upaiyun.com';// UPYUN 图片位置 | |
if( substr($_SERVER["REQUEST_URI"], 0, 6) == '/'.'lang/' ) | |
{ | |
$path = substr($_SERVER["REQUEST_URI"], 8, strpos($_SERVER["REQUEST_URI"]."?", "?")); | |
$language = $localization[ substr($_SERVER["REQUEST_URI"], 6, 2) ]; | |
} | |
else | |
{ | |
$path = substr($_SERVER["REQUEST_URI"], 0, strpos($_SERVER["REQUEST_URI"]."?", "?")); | |
$language = $localization[ 'EN' ]; | |
} | |
if(substr($path,-13) == '!exif.json-js')// UPYUN EXIF 信息后缀为 "!exif.json" | |
{ | |
$path = substr($path,0,-3); | |
$get = memcache_get($mmc,$path); | |
if($get != '') | |
{ | |
if($get['status'] == 200) | |
{ | |
$pagecontent = $get['content']; | |
} | |
$info = [ 'http_code'=>$get['status'], ]; | |
$cache = "OK"; | |
} | |
else | |
{ | |
$curl = curl_init(); | |
$szUrl = $catchurl.$path; | |
curl_setopt($curl, CURLOPT_URL, $szUrl); | |
curl_setopt($curl, CURLOPT_HEADER, 1); | |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 不显示网页内容 | |
curl_setopt($curl, CURLOPT_ENCODING, ''); | |
$data=curl_exec($curl); | |
$info = curl_getinfo($curl); | |
$httpHeaderSize = $info['header_size']; | |
$pHeader = substr($data, 0, $httpHeaderSize); | |
$pagecontent = substr($data, $httpHeaderSize); | |
$regex = "/Content-Length:\s([0-9].+?)\s/"; | |
$count = preg_match($regex, $pHeader, $matches); | |
$cache = "No"; | |
} | |
} | |
if($info['http_code'] == 200) | |
{ | |
$value = [ 'status' => '200', 'content' => $pagecontent ]; | |
memcache_set($mmc,$path,$value);// 缓存 EXIF 内容 | |
header('HTTP/1.1 200 OK'); | |
header('Content-Type: text/javascript'); | |
header('Cache-Control: public, max-age=86400'); | |
echo <<<JS | |
/* The original code is at here: https://gist.github.com/ZE3kr/8f3e68c12f694112e5c0 */ | |
JS; | |
$pagecontent = json_decode($pagecontent,true); | |
$exif = $pagecontent['EXIF'];// 抓取 EXIF | |
$FocalLengthIn35mmFilm = sprintf("%.0f", Deci_Con($exif['FocalLength']));// 格式化焦距 | |
/** | |
* 计算部分非全画幅相机的等效焦距 | |
* @see https://en.wikipedia.org/wiki/APS-C#Multiplier_factors | |
**/ | |
$model = $exif['Model']; | |
$model = str_replace( 'Nikon ', '', $model); | |
$model = str_replace( ' Digital', '', $model); | |
$model = str_replace( ' DIGITAL', '', $model); | |
$model = str_replace( 'Canon ', '', $model); | |
$model = str_replace( $exif['Make'].' ', '', $model); | |
if( isset($in35mmFilmData[ $model ]) ) { | |
$FocalLengthIn35mmFilm = sprintf("%.0f", $in35mmFilmData[ $model ] * Deci_Con($exif['FocalLength'])); | |
} | |
if( isset($exif['FocalLengthIn35mmFilm']) ) { | |
$FocalLengthIn35mmFilm = sprintf("%.0f", Deci_Con($exif['FocalLengthIn35mmFilm']));// 格式化等效焦距 | |
} | |
$ApertureValue = sprintf("%.1f", pow(1.41,Deci_Con($exif['ApertureValue'])));// 计算光圈 | |
$ExposureTime = Deci_Con($exif['ExposureTime']);// 格式化快门时间 | |
/** | |
* 格式化快门时间 | |
**/ | |
if( $ExposureTime <= 0.1 ) | |
{ | |
$ExposureTime = '1/'.sprintf("%.0f", 1/$ExposureTime).' s';// 快门时间小于等于 0.1s 时, 显示 1/$x + s 的形式 | |
} | |
elseif( $ExposureTime <= 1 ) | |
{ | |
$ExposureTime = sprintf("%.2f", $ExposureTime).'"';// 快门时间小于等于 1s 又大于 0.1s 时, 显示保留小数点后 2 位的定点数 | |
} | |
elseif( $ExposureTime <= 10 ) | |
{ | |
$ExposureTime = sprintf("%.1f", $ExposureTime).'"';// 快门时间大于 1s 又小于等于 10s 时, 显示保留小数点后 1 位的定点数 | |
} | |
elseif( $ExposureTime <= 60 ) | |
{ | |
$ExposureTime = sprintf("%.0f", $ExposureTime).'"';// 快门时间大于 10s 又小于等于 60s 时, 显示整数 | |
} | |
else | |
{ | |
$ExposureTime = sprintf("%.1f", $ExposureTime/60).'min';// 快门时间大于 60s 显示保留小数点后 1 位的定点数 (表示分钟) | |
} | |
/** | |
* 赞助商链接 | |
**/ | |
if( isset( $camerasLink[ $exif['Model'] ] ) ) | |
{ | |
$link = 'https://cdn-tlo.b0.upaiyun.com/html/redirecting2.html#' . $camerasLink[ $exif['Model'] ]; | |
$cameraText = "<li><b>{$language['Camera']}:</b> <i><a href='{$link}' target='_black'>{$exif['Make']} {$model}</a></i></li>"; | |
} | |
else | |
{ | |
$cameraText = "<li><b>{$language['Camera']}:</b> <i>{$exif['Make']} {$model}</i></li>"; | |
} | |
if( isset( $language['Exposure Program'][ $exif['ExposureProgram'] ] ) ) // 显示模式 | |
{ | |
$programText = "<li><b>{$language['Program']}:</b> <i>{$language['Exposure Program'][ $exif['ExposureProgram'] ]}</i></li>"; | |
} | |
/** | |
* 基本信息 | |
**/ | |
$html = <<<HTML | |
<li><b><i class='exif-li-i'>{$FocalLengthIn35mmFilm}mm</i><i class='exif-li-i'>f/{$ApertureValue}</i><i class='exif-li-i'>{$ExposureTime}</i><i class='exif-li-i'>ISO {$exif['ISOSpeedRatings']}</i></b></li>{$programText}{$cameraText} | |
HTML; | |
/** | |
* 额外信息 | |
**/ | |
if( isset( $exif['0xA434'] ) ) // 显示相机镜头 | |
{ | |
$lens = $exif['0xA434']; | |
if( isset( $fixLens[ $lens ] ) ) | |
{ | |
$lens = $fixLens[ $lens ]; | |
} | |
if( isset( $lensLink[ $exif['0xA434'] ] ) ) | |
{ | |
$link = 'https://cdn-tlo.b0.upaiyun.com/html/redirecting2.html#' . $lensLink[ $exif['0xA434'] ]; | |
$html = $html."<li><b>{$language['Lens']}:</b> <i><a href='{$link}' target='_black'>{$lens}</a></i></li>"; | |
} | |
else | |
{ | |
$html = $html."<li><b>{$language['Lens']}:</b> <i>{$lens}</i></li>"; | |
} | |
} | |
if( isset( $exif['CustomRendered'] ) && $exif['CustomRendered'] !== '0' ) // 显示 HDR | |
{ | |
$html = $html."<li><b>{$language['HDR']}</b></li>"; | |
} | |
if( isset($exif["GPSLongitude"]) && isset($exif["GPSLatitude"]) ) //显示地图 | |
{ | |
$html = $html . <<<HTML | |
<style>.tlo-map{display:block!important;}</style> | |
HTML; | |
$echo = '$(document).ready(function(){$("#exif").html("'.$html.'");});'; | |
$lon = getGps($exif["GPSLongitude"], $exif['GPSLongitudeRef']); | |
$lat = getGps($exif["GPSLatitude"], $exif['GPSLatitudeRef']); | |
$gps = <<<JS | |
var lat = {$lat}; | |
var lon = {$lon}; | |
var gps = 'isset'; | |
JS; | |
$echo = $gps.$echo; | |
} | |
else | |
{ | |
$echo = '$(document).ready(function(){$("#exif").html("'.$html.'");});'; | |
} | |
echo $echo;// 输出 JavaSript | |
} | |
else | |
{ | |
header('Cache-Control: no-cache'); | |
header('Content-Type: text/javascript'); | |
echo <<<JS | |
/* The original code is at here: https://gist.github.com/ZE3kr/8f3e68c12f694112e5c0 */ | |
/* 404 Page Not Find */ | |
JS; | |
} | |
if($info['http_code'] == 404)// 针对 404 页面缓存 1 小时 | |
{ | |
$value = [ 'status' => '404' ]; | |
memcache_set($mmc,$path,$value, 0, 3600); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment