当程序员遇到会写代码的产品经理......

发布时间:2022-07-05 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了当程序员遇到会写代码的产品经理......脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

1、缘起

事情是这样的,上周我接到了个需求,产品经理想在微信内嵌的H5里,静默获取图片的详细信息,比如拍照的时间、地理位置、设备指纹等。 一方面最近活儿太多影响我摸鱼,另一方面是这个需求没办法完全实现,因为有些图片信息就是没有,又懒得解释,于是我和产品经理说F1a;

这个需求做不了。

原以为事情到这里就结束了,万万没想到,我遇到了一个会写代码的产品经理…

第二天早上,我的直属技领导直接找到了我,和我说:

“xxx(产品经理)”把获取图片信息的Demo写出来了,这个需求可以做,之后就你来吧。

当时我的内心是这样的:

当程序员遇到会写代码的产品经理......

拿错了拿错了:

当程序员遇到会写代码的产品经理......

总之,最后这个需求还是落到我头上了

当程序员遇到会写代码的产品经理......

所以就有了这篇:获取图片的Exif数据

2、正文开始

像这种附带拍摄时间、GPS地理位置等信息的图片格式叫做Exif,英文全称为 Exchangeable image file format,即可交换图像文件格式 。

之前有一阵子传得沸沸扬扬的微信上传原图会泄漏隐私数据的事儿,其实就是这个Exif的锅。。。实际上这些Exif数据是由拍照设备产生的,并且用户可以自行修改和删除,换句话说,你可以随便修改Exif数据。比如这样:

当程序员遇到会写代码的产品经理......

当然,微信上传原图确实会有风险,因为一不小心你就告诉了别人你是在哪里拍的这张照片,但是这个事不能全赖微信,理论上所有上传图片的程序都有泄漏隐私的风险。你可以像上面说的那样直接改数据,也可以点左下角的删除属性和个人信息来直接删除Exif数据

当程序员遇到会写代码的产品经理......

因为Exif数据是可以伪造和删除的,所以理论上只能作为参考,而不能当作确切信息。

那么,如何获取Exif数据呢?

gIThub上有个4.1k star的开项目exif-js:https://github.COM/exif-js/exif-js

用起来很丝滑,我写了个Demo来获取图片的Exif数据:

http://jsrun.net/kwTKp/edit

随便找张手机拍的照片上传看看:

当程序员遇到会写代码的产品经理......

可以看到已经获取到了图片的Exif数据,并且通过百度地图API反查出了具体的地址。

但是对于非设备直接拍照的图片,或者图片经过了压缩处理,比如你从网上直接下载下来的图片等,可能就拿不到Exif数据。

作为一个有追求的前端,至少不能输给产品经理我们不仅要知其然,还要知其所以然。

所以,去看看exif-js的源码:

一千多行,在下告辞

呵,区区一千多行,话不多说,就是肝。


以下是源码分析

分析比较长,可以不看

直接拉到最后给我点个赞 😃


当程序员遇到会写代码的产品经理......

首先是个匿名自执行函数,这样写的好处是能拥有独立作用域,既避免污染外界代码,也避免被外界代码污染。

@H_919_126@

接着定义并导出EXIF对象,这样就可以把EXIT暴露给外部,以便外部获取并使用EXIF对象。

这里检查了当前环境的模块化规范,exportscommonjs的规范,如果当前环境支持exports,则使用exports方式导出模块,如果不支持,则将EXIF挂到全局对象下。

EXIF上定义了很多属性和方法,比如我们demo里用到的getData方法:

// exif-js
EXIF.getData = function(img, callback) {
  // ...省略部分非核心代码
  
  // 判断img对象上是否有exifdata属性值
  if (!imageHasData(img)) {
      // 本地上传一般是没有exifdata,需要调用getImageData去获取
      getImageData(img, callback);
  } else {
      // 如果有exifdata属性值直接回调
      if (callback) {
          callback.call(img);
      }
  }
})

可以看到入参是img对象和callback回调函数,如果img对象上有exifdata属性值,则直接调用callback,如果没有,则需要调一个方法去获取:getImageData

因为图片有可能是我们通过src属性定义的,也有可能是本地上传的,而src属性值有可能是base64格式,也可能是blob或http/https等格式,所以getImageData会对不同情况的图片对象进行处理,最后都处理为ArrayBuffer对象。

ArrayBuffer是一个字节数组,用来表示通用的、固定长度的原始二进制数据缓冲区。

ArrayBuffer是一个只能读不能写的对象,因此源码中使用DataView对象对ArrayBuffer进行写操作。

上述的几个对象实际上都是JS提供的处理二进制数据的对象,如果想进一步了解,推荐阅读这篇文章:《聊聊JS的二进制家族:Blob、ArrayBuffer和Buffer》:https://zhuanlan.zhihu.com/p/97768916

我们继续看源码:

拿到ArrayBuffer对象后,就可以对二进制数据进行解析了。

// 解析图片的Exif数据
function findEXIFinJPEG(file) {
        VAR dataView = new DataView(file);

        // 根据文件头的前2个字节判断是否为图片文件
        if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
            return false; // not a valid jpeg
        }

        var offset = 2,
            length = file.byteLength,
            marker;

        // 遍历查找Exif数据信息串
        while (offset < length) {
            // 这里是将0xFFE1分成两个字节判断,先判断第一个字节是否等于0xFF
            if (dataView.getUint8(offset) != 0xFF) {
                return false; // not a valid marker, something is wrong
            }

            marker = dataView.getUint8(offset + 1);
            // we could implement handling for other markers here,
            // but we're only looking for 0xFFE1 for EXIF data

            // 再判断第二个字节是否等于0xE1,也就是255
            if (marker == 225) {
                return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2);
            } else {
                offset += 2 + dataView.getUint16(offset+2);
            }

        }

    }

这里有个前置知识点:Exif信息以0xFFE1作为开头标记,所以源码中的这段while遍历就是为了找到Exif信息串的开头,然后再调用readEXIFData方法。

readEXIFData就是对Exif信息串做解析,即通过遍历二进制串,匹配出属性及对应的值,并放到一个对象tags中,解析完成后返回这个对象。

除了Exif数据,源码中还解析了IPTC数据(作者,版权,字幕,细节描述等)、XMP数据(Extensible Metadata Platform,Adobe公司提出的关于元数据的创建、处理和交换的一套标准)。

当程序员遇到会写代码的产品经理......


扩展资料

exif-js的API、属性等使用说明可以参考这篇博客:http://code.ciaoca.com/javascript/exif-js/


产品经理还有一个获取设备指纹的需求,因篇幅所限,就下次再写吧,这里给出Demo:http://jsrun.net/2wTKp/edit,用的是fingerPRintjs


3、总结

作为一个秃头程序员,身处和谐社会,我积极反思了一下自己,实际上不能直接和产品经理说“这个需求做不了”。如果真的做不了,应该给出具体的技术可行性分析,再得出做不了的结论,否则就应该说:“我去看下可行性”,然后去仔细了解下技术实现上的难点,再和产品经理沟通说明。

总而言之就是:

不能直接说“这个需求做不了”

当程序员遇到会写代码的产品经理......

以上都是废话,大家看看就好。

本文的重点其实还是中间那段获取Exif数据的分析。

闲扯两句

中秋快到啦,我的老家最近疫情又严重了,所以回不了家,只能中秋的时候一起赏月云饼了~~希望疫情能早日结束吧。

提前祝大家中秋节快乐,团团圆,幸福美满!

脚本宝典总结

以上是脚本宝典为你收集整理的当程序员遇到会写代码的产品经理......全部内容,希望文章能够帮你解决当程序员遇到会写代码的产品经理......所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。