Hermit Cottage

利用 Aliyun OSS 显示图片 Exif 信息

首先要感谢 @fooleap 发给我的极为给力的 jQuery 实现显示图片 Exif 代码,解决了我十年来  :cry:  的一个夙愿:显示博客图片 Exif(什么是 Exif?)信息——以后再也不需要在图片的 title 属性里人肉输入用了什么设备了!

虽然从来没学过 jQuery,但好歹有十多年前可怜的一点 js 基础,加上百度,一晚上摸索着居然也搞出来了。

1、将根据自己需求修订后的 jQuery 代码 yourjscode.js 上传至主题下 js 文件夹:

/* -------------------------------------------------
 * Description: New exif.js file. Just make it neat.
 * Edition:     v1.4
 * Time:        2018/11/18 23:46
 * Author:      https://synyan.net
 * ------------------------------------------------*/
window.$ = jQuery;
$(document).ready(function(){
$('.post-content img[src*="synyan.cn"]').each(function(){
    var _ = this; 
    var $el = $(this); 
    var displayinfo;
    if( _.src.toLowerCase().lastIndexOf('.jpg') )
        var index = _.src.toLowerCase().lastIndexOf('.jpg');
        else if( _.src.toLowerCase().lastIndexOf('.jpeg') )
        var index = _.src.toLowerCase().lastIndexOf('.jpeg');
    else
        return;
    var titleString = _.title;
    var titleCamera = false;
    if (titleString.indexOf("Camera") >= 0) titleCamera = true;
    if( index > -1 ){
        var exifUrl = _.src.slice(0, index)+'.jpg?x-oss-process=image/info';
        $.ajax({
            url: exifUrl,
            success: function (res) {
               var exif = res;
               var parse = function(attr, label){
               return !attr ? '' : ( label ? label + ' ' : '') + attr.value + ' ';
     }
     /* 情况1 */
     if (!!parse(exif.Make) && !!parse(exif.Model) && !!parse(exif.DateTimeOriginal)){
        /* 情况1.1 */
        var imgCameraOne = parse(exif.Model).replace("Canon","");
        var focalLengthInNumber = Math.round((eval(parse(exif.FocalLength,'')))*100)/100;
        var focalLengthIn35mmFilmOutput;
        var focalLengthIn35mmFilmNumber = eval(parse(exif.FocalLengthIn35mmFilm,''));
        var focalLenghtOutput;
     if (!focalLengthInNumber) {
        focalLenghtOutput = "";
        if (!focalLengthIn35mmFilmNumber)
           focalLengthIn35mmFilmOutput = "";
        else
           focalLengthIn35mmFilmOutput = " eqv " + focalLengthIn35mmFilmNumber + "mm";
      }
      else {
           focalLenghtOutput = "·" + " f=" + focalLengthInNumber + "mm";
           if (focalLengthIn35mmFilmNumber)
              focalLengthIn35mmFilmOutput = " eqv " + focalLengthIn35mmFilmNumber + "mm";
           else {
              focalLengthIn35mmFilmOutput = "";
           }
           if (focalLengthInNumber == focalLengthIn35mmFilmNumber) {
              focalLenghtOutput = "";
              focalLengthIn35mmFilmOutput = "·" + " f=" + focalLengthInNumber + "mm";
           }
           else;
       }
       var content = '<div class="exif-caption" exif-data="'
                   + parse(exif.Make, '')
                   + imgCameraOne
                   + parse(exif.LensModel,'·')
                   + parse(exif.DateTimeOriginal, '·')
                   + focalLenghtOutput
                   + focalLengthIn35mmFilmOutput
                   + '"></div>';
        }
       /* 情况2 */
        else if (!parse(exif.Make) || !parse(exif.Model) || !parse(exif.DateTimeOriginal)) {
             if (titleString && titleCamera) {
                var imgTitle = titleString;
                imgTitle = imgTitle.replace(/(Camera:/i, '');
                imgTitle = imgTitle.replace(/)/i, '');
                if (imgTitle.indexOf("+") >= 0) {
                    var imgTitleString = imgTitle.split("+");
                    var imgCamera = imgTitleString[0];
                    var imgLens = imgTitleString[1];
                    var imgFilm = imgTitleString[2];
                    var imgScanner = imgTitleString[3];
                if (!imgLens){
                    imgTitle = "" + imgCamera;
                }
                else if (!imgFilm) {
                    imgTitle = "" + imgCamera +"·" + imgLens;
                }
                else if (!imgScanner) {
                    imgTitle = "" + imgCamera +"·" + imgLens + "·" + imgFilm;
                }
                else {
                    imgTitle = "" + imgCamera +"·" + imgLens + "·" + imgFilm + "·" + imgScanner;
                }
          }
          else if(imgTitle.indexOf("+") < 0 && titleString.indexOf("Camera:") >=0){
               imgTitle = "" + imgTitle;
          }
          if (exif.DateTimeOriginal) {
               var content = '<div class="exif-caption" exif-data="'
                           + imgTitle
                           + parse(exif.DateTimeOriginal, '·')
                           + '"></div>';
          }
          /* 情况2.1 */
            if (!(exif.DateTimeOriginal)) {
                 /* 情况2.1.1 */
                 if ((exif.DateTime && !exif.DateTimeDigitized)) {
                     var content = '<div class="exif-caption" exif-data="'
                                 + imgTitle 
                                 + parse(exif.DateTime, '·')
                                 + '"></div>';
             }
             else if ((exif.DateTimeDigitized)) {
                 var content = '<div class="exif-caption" exif-data="'
                             + imgTitle
                             + parse(exif.DateTimeDigitized, '·')
                             + '"></div>';
             }
             else {
                 var content = '<div class="exif-caption" exif-data="'
                             + imgTitle
                             + '"></div>';
             }
           }
        }
        /* 情况3 */
        else {
             var content = '<div class="exif-caption" exif-data="'
                         + ' 无Exif信息 '
                         + '"></div>';
        }
      }
      else;
      $(".post-content img").attr({title:""});
      $el.after(content);
      }
      })
     }
   })
})

2、在 Single.php 头部插入:
<script src="<?phpecho get_stylesheet_directory_uri() ?>/js/yourjscode.js"></script>

3、添加 css 代码(从 @fooleap 的博客扒下来的,同样也是修订了一番,最终符合 WordPress 的贴图规范,再次感谢 @fooleap):
/* exif css */
.post-content .wp-caption .exif-caption:before{
    max-width: 100%;
    text-align: center;
    margin: 0 auto;
    content: attr(exif-data);
    display: block;
    position: absolute !important;
    top: 20px;
    left: 25px;
    right: 25px;
    background-color: black;
    color: white;
    font-size: 12px;
    line-height: 25px;
    height: 25px;
    overflow: hidden;
    opacity: 0;
    transition: opacity .5s;
    -webkit-transition: opacity .5s;
}
.wp-caption:hover .exif-caption[exif-data]:before {
    opacity: .7;
}

4、Aliyun 开通 “跨域访问 ”。

大功告成! ;)

鼠标移到图片上显示Exif信息
鼠标移到图片上显示 Exif 信息

[2018/11/3]

昨晚做得匆忙,开会抽空之余继续优化了一下代码:

  • 删掉了无用的几行代码。
  • 以前人肉输入的 title 属性也没浪费,加入判断语句,如果 Exif 为空或不全,则取出 title 标签中的部分文字,嵌入显示完整信息。
无Exif的胶片引入title信息
无 Exif 的胶片引入 title 信息

[2018/11/4]

发现存量图片显示 Exif 存在各种 bug,原代码越改越多越糊涂,改到后来已经不知道到底在写什么了。

于是静下心来列了一张代码结构表:

情况 1:
正常 Exif(标准是 Make/Model/DateTimeOriginal/FNumber 同时存在)。
	情况 1.1:
	若 Make 为 Canon,Model 中去除一个重复的 Canon 字样。

情况 2:
有 Exif 但 Exif 不全(标准是 Make/Model/DateTimeOriginal/FNumber 有一个不存在),或无 Exif,以人工输入的 title="(Camera:Make & Model + [LensModel] + [Film] + [Scanner])"通过分割+号代替 Make/Model/LensModel 并添上其它属性。
	情况 2.1:
	若 DateTimeOriginal 不存在,则以 DateTime 显示修改时间。
		情况 2.1.1:
		若 DateTime 不存在,则不显示修改时间。
		情况 2.1.2:
		若 DateTimeDigitalized 存在,则以 DateTimeDigitalized 显示图片时间。
情况 3:
无 Exif,无 title,提示无 Exif 信息。

按照代码结构表重写一遍,清爽整洁多了。精简后的代码已更新至代码 1。

20 条评论

发表评论 →

取得数据的第一个判断写错了,我本意是想判断没有 exif 信息,不是 !!exif.Mark 而是 !exif.Make。

Google Chrome 70 Google Chrome 70 Mac OS X 10.14 Mac OS X 10.14

我其实也很疑惑,因为我后来也试了一下发现!!exif.Mark 无效,不过太晚了再加上能用就不管了……

Wordpress App 11 Wordpress App 11 iPhone iOS 12.1 iPhone iOS 12.1

看起来好折腾,不过习惯很好啊,想当年每张相片都插相机信息累坏了。

Google Chrome 70 Google Chrome 70 Mac OS X 10.14 Mac OS X 10.14

是啊,不过也没浪费,我改了代码了,以前留的信息都用上了,特别是胶片。其实当年如果不偷懒在修图时直接手工把 Exif 全都嵌进去就更完美了。现在是不高兴弄了……

Google Chrome 70 Google Chrome 70 Mac OS X 10.14 Mac OS X 10.14

阿里云的 oss 没搞懂,我也是借 @fooleap 之力用七牛云实现这一功能。

Google Chrome 70 Google Chrome 70 Windows 10 Windows 10

七牛云现在不能用测试域名了,所以我只能放弃。OSS 跟七牛云大差不差。@fooleap 是中国好博友,给戴大红花。

Google Chrome 70 Google Chrome 70 Mac OS X 10.14 Mac OS X 10.14

是的,不过胶片和扫描仪是从前人肉输的 title 属性,如今用函数方式取出来罢了。

Google Chrome 70 Google Chrome 70 Mac OS X 10.14 Mac OS X 10.14

代码主干部分是 fooleap 友情赞助的,并不清楚为何用 ajax。看来回头是要自学一下了。

Wordpress App 11 Wordpress App 11 iPhone iOS 12.1 iPhone iOS 12.1

我看了一下,你应该也是用的比如七牛什么的 api 吧?图片都加了-1200×900.jpg 后缀。
我一般是自己线下处理好了尺寸再上传的,减少开销。
既然能加尺寸,exif 应该也能取得,CORS 在云存储的设置里应该有。

Google Chrome 70 Google Chrome 70 Mac OS X 10.14 Mac OS X 10.14

发表评论