首先,我用到了一款插件,是纯JS压缩上传插件,第一次用CSDN,不太会用,我把插件所有代码拷贝在文章末尾。
加载JS插件<script src="__JS__/dist/lrz.mobile.min.js">script>
页面上传图片:
<div class="fileupload-buttonbar"> <a type="button" class="am-btn am-btn-sm am-fl " style=" line-height: 0.2;"><img src="__IMG__/image.png">a> <div class="fileinput-button" style="width: 100%"> <input type="file" name="files" class="btn" id="choose" style="left: 35px;position:absolute;z-index: 1;width: 35px;height:40px;opacity: 0;cursor: pointer;" data-url="{:U('Core/File/uploadPictureBase64')}" multiple/>div> <style> .img-list li { float: left; position: relative; display: inline-block; width: 100px; height: 100px; margin: 5px 5px 20px 5px; border: 1px solid rgb(100, 149, 198); background: #fff no-repeat center; background-size: cover; border-radius: 5px; } style> div> <p class="submitweibo" url="{:U('Mob/Weibo/doSend')}"> <button style="float: right" type="submit" class="am-btn am-btn-primary am-btn-block">发布button> p> div> <ul class="img-list am-fl" style="padding-left:0px;"> ul>
图片id存放,隐藏input,放在页面的form表单内即可。
<input type="hidden" id="img_ids" name="attach_ids" value="">
js代码
//新上传图片 function add_img() { var filechooser = document.getElementById("choose"); $("#upload").on("click", function () { filechooser.click(); }) filechooser.onchange = function () { if (!this.files.length) return; var files = Array.prototype.slice.call(this.files); if (files.length > 9) { alert("最多同时只可上传9张图片"); return; } files.forEach(function (files, i) { if (!/\/(?:jpeg|png|gif)/i.test(files.type)){ toast.error('上传图片格式不符!'); } var div = ' \ \ '; $('.img-list').append(div); lrz(files, { width: 1200, height: 900, before: function () { console.log('压缩开始'); }, fail: function (err) { console.error(err); }, always: function () { console.log('压缩结束'); }, done: function (results) { // 你需要的数据都在这里,可以以字符串的形式传送base64给服务端转存为图片。 var data=results.base64; upload(data); } }); }) } } function removeLi(li,file_id) { console.log(li) upAttachVal('remove', file_id, $('#img_ids')) $(li).parent('.waitbox').remove(); } //图片上传,返回id ,地址 function upload(data) { console.log(data); var dataUrl = U('Core/File/uploadPictureBase64'); $.post(dataUrl, {data: data}, function (msg) { if (msg.status == 1) { var ids = $('#img_ids').val(); upAttachVal('add', msg.id, $('#img_ids')); //上传成功显示图片 var div = ' \ removeLi(this, '+msg.id+')" style="position:absolute;right: 5px;top: -5px;color: red">\ \ '; $('.loadingBox').hide(); $('.img-list').append(div); } else { toast.error(msg.info); } }, 'json') } function upAttachVal(type, attachId, obj) { var $attach_ids = obj; var attachVal = $attach_ids.val(); var attachArr = attachVal.split(','); var newArr = []; for (var i in attachArr) { if (attachArr[i] !== '' && attachArr[i] !== attachId.toString()) { newArr.push(attachArr[i]); } } type === 'add' && newArr.push(attachId); if (newArr.length <= 9) { $attach_ids.val(newArr.join(',')); return newArr; } else { return false; } }
后台php代码:
public function uploadPictureBase64() { $aData = $_POST['data']; if ($aData == '' || $aData == 'undefined') { $this->ajaxReturn(array('status'=>0,'info'=>'参数错误')); } if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $aData, $result)) { $base64_body = substr(strstr($aData, ','), 1); empty($aExt) && $aExt = $result[2]; } else { $base64_body = $aData; } empty($aExt) && $aExt = 'jpg'; $pictureModel = D('Picture'); $md5 = md5($base64_body); $sha1 = sha1($base64_body); $check = $pictureModel->where(array('md5' => $md5, 'sha1' => $sha1))->find(); if ($check) { //已存在则直接返回信息 $return['id'] = $check['id']; $return['path'] = render_picture_path($check['path']); $this->ajaxReturn(array('status'=>1,'id'=>$return['id'],'path'=> $return['path'])); } else { //不存在则上传并返回信息 $driver = modC('PICTURE_UPLOAD_DRIVER','local','config'); $driver = check_driver_is_exist($driver); $date = date('Y-m-d'); $saveName = uniqid(); $savePath = '/Uploads/Picture/' . $date . '/'; $path = $savePath . $saveName . '.' . $aExt; if($driver == 'local'){ //本地上传 mkdir('.' . $savePath, 0777, true); $data = base64_decode($base64_body); $rs = file_put_contents('.' . $path, $data); } else{ $rs = false; //使用云存储 $name = get_addon_class($driver); if (class_exists($name)) { $class = new $name(); if (method_exists($class, 'uploadBase64')) { $path = $class->uploadBase64($base64_body,$path); $rs = true; } } } if ($rs) { $pic['type'] = $driver; $pic['path'] = $path; $pic['md5'] = $md5; $pic['sha1'] = $sha1; $pic['status'] = 1; $pic['create_time'] = time(); $id = $pictureModel->add($pic); $this->ajaxReturn (array('status'=>1,'id' => $id, 'path' => render_picture_path($path))); } else { $this->ajaxReturn(array('status'=>0,'图片上传失败。')); } } }
function render_picture_path($path) { $path = get_pic_src($path); return is_bool(strpos($path, 'http://')) ? 'http://' . str_replace('//', '/', $_SERVER['HTTP_HOST'] . '/' . $path) : $path; }
function get_pic_src($path) { //不存在http:// $not_http_remote = (strpos($path, 'http://') === false); //不存在https:// $not_https_remote = (strpos($path, 'https://') === false); if ($not_http_remote && $not_https_remote) { //本地url return str_replace('//', '/', getRootUrl() . $path); //防止双斜杠的出现 } else { //远端url return $path; } }
插件代码:
!function (e) { Array.prototype.map || (Array.prototype.map = function (e, r) { var a, t, n; if (null == this)throw new TypeError(" this is null or not defined"); var o = Object(this), i = o.length >>> 0; if ("function" != typeof e)throw new TypeError(e + " is not a function"); for (r && (a = r), t = Array(i), n = 0; i > n;) { var l, d; n in o && (l = o[n], d = e.call(a, l, n, o), t[n] = d), n++ } return t }); var r = e.detect = function () { var e = function () { }, r = { browser_parsers: [{ regex: "^(Opera)/(\\d+)\\.(\\d+) \\(Nintendo Wii", family_replacement: "Wii", manufacturer: "Nintendo" }, { regex: "(SeaMonkey|Camino)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)", family_replacement: "Camino", other: !0 }, { regex: "(Pale[Mm]oon)/(\\d+)\\.(\\d+)\\.?(\\d+)?", family_replacement: "Pale Moon (Firefox Variant)", other: !0 }, { regex: "(Fennec)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)", family_replacement: "Firefox Mobile" }, { regex: "(Fennec)/(\\d+)\\.(\\d+)(pre)", family_replacment: "Firefox Mobile" }, { regex: "(Fennec)/(\\d+)\\.(\\d+)", family_replacement: "Firefox Mobile" }, { regex: "Mobile.*(Firefox)/(\\d+)\\.(\\d+)", family_replacement: "Firefox Mobile" }, { regex: "(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?)", family_replacement: "Firefox ($1)" }, { regex: "(Firefox)/(\\d+)\\.(\\d+)(a\\d+[a-z]*)", family_replacement: "Firefox Alpha" }, { regex: "(Firefox)/(\\d+)\\.(\\d+)(b\\d+[a-z]*)", family_replacement: "Firefox Beta" }, { regex: "(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(a\\d+[a-z]*)", family_replacement: "Firefox Alpha" }, { regex: "(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(b\\d+[a-z]*)", family_replacement: "Firefox Beta" }, { regex: "(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?", family_replacement: "Firefox ($1)" }, { regex: "(Firefox).*Tablet browser (\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "MicroB", tablet: !0 }, {regex: "(MozillaDeveloperPreview)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?"}, { regex: "(Flock)/(\\d+)\\.(\\d+)(b\\d+?)", family_replacement: "Flock", other: !0 }, { regex: "(RockMelt)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Rockmelt", other: !0 }, { regex: "(Navigator)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Netscape" }, { regex: "(Navigator)/(\\d+)\\.(\\d+)([ab]\\d+)", family_replacement: "Netscape" }, { regex: "(Netscape6)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Netscape" }, { regex: "(MyIBrow)/(\\d+)\\.(\\d+)", family_replacement: "My Internet Browser", other: !0 }, { regex: "(Opera Tablet).*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?", family_replacement: "Opera Tablet", tablet: !0 }, { regex: "(Opera)/.+Opera Mobi.+Version/(\\d+)\\.(\\d+)", family_replacement: "Opera Mobile" }, {regex: "Opera Mobi", family_replacement: "Opera Mobile"}, { regex: "(Opera Mini)/(\\d+)\\.(\\d+)", family_replacement: "Opera Mini" }, { regex: "(Opera Mini)/att/(\\d+)\\.(\\d+)", family_replacement: "Opera Mini" }, { regex: "(Opera)/9.80.*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?", family_replacement: "Opera" }, {regex: "(webOSBrowser)/(\\d+)\\.(\\d+)", family_replacement: "webOS"}, { regex: "(webOS)/(\\d+)\\.(\\d+)", family_replacement: "webOS" }, {regex: "(wOSBrowser).+TouchPad/(\\d+)\\.(\\d+)", family_replacement: "webOS TouchPad"}, { regex: "(luakit)", family_replacement: "LuaKit", other: !0 }, { regex: "(Lightning)/(\\d+)\\.(\\d+)([ab]?\\d+[a-z]*)", family_replacement: "Lightning", other: !0 }, { regex: "(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?) \\(Swiftfox\\)", family_replacement: "Swiftfox", other: !0 }, { regex: "(Firefox)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)? \\(Swiftfox\\)", family_replacement: "Swiftfox", other: !0 }, { regex: "rekonq", family_replacement: "Rekonq", other: !0 }, { regex: "(conkeror|Conkeror)/(\\d+)\\.(\\d+)\\.?(\\d+)?", family_replacement: "Conkeror", other: !0 }, { regex: "(konqueror)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Konqueror", other: !0 }, { regex: "(WeTab)-Browser", family_replacement: "WeTab", other: !0 }, { regex: "(Comodo_Dragon)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Comodo Dragon", other: !0 }, { regex: "(YottaaMonitor)", family_replacement: "Yottaa Monitor", other: !0 }, {regex: "(Kindle)/(\\d+)\\.(\\d+)", family_replacement: "Kindle"}, { regex: "(Symphony) (\\d+).(\\d+)", family_replacement: "Symphony", other: !0 }, { regex: "Minimo", family_replacement: "Minimo", other: !0 }, { regex: "(CrMo)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Chrome Mobile" }, { regex: "(CriOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Chrome Mobile iOS" }, { regex: "(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) Mobile", family_replacement: "Chrome Mobile" }, { regex: "(chromeframe)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Chrome Frame" }, { regex: "(UC Browser)(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "UC Browser", other: !0 }, { regex: "(SLP Browser)/(\\d+)\\.(\\d+)", family_replacement: "Tizen Browser", other: !0 }, { regex: "(Epiphany)/(\\d+)\\.(\\d+).(\\d+)", family_replacement: "Epiphany", other: !0 }, { regex: "(SE 2\\.X) MetaSr (\\d+)\\.(\\d+)", family_replacement: "Sogou Explorer", other: !0 }, { regex: "(Pingdom.com_bot_version_)(\\d+)\\.(\\d+)", family_replacement: "PingdomBot", other: !0 }, { regex: "(facebookexternalhit)/(\\d+)\\.(\\d+)", family_replacement: "FacebookBot" }, { regex: "(Twitterbot)/(\\d+)\\.(\\d+)", family_replacement: "TwitterBot" }, {regex: "(AdobeAIR|Chromium|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Shiira|Sunrise|Chrome|Flock|Netscape|Lunascape|WebPilot|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iron|Iris|UP\\.Browser|Bunjaloo|Google Earth|Raven for Mac)/(\\d+)\\.(\\d+)\\.(\\d+)"}, {regex: "(Bolt|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|NetNewsWire|Iron|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris)/(\\d+)\\.(\\d+)"}, {regex: "(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\\d+)\\.(\\d+)\\.(\\d+)"}, {regex: "(iCab|Lunascape|Opera|Android|Jasmine|Polaris|BREW) (\\d+)\\.(\\d+)\\.?(\\d+)?"}, { regex: "(Android) Donut", v2_replacement: "2", v1_replacement: "1" }, {regex: "(Android) Eclair", v2_replacement: "1", v1_replacement: "2"}, { regex: "(Android) Froyo", v2_replacement: "2", v1_replacement: "2" }, {regex: "(Android) Gingerbread", v2_replacement: "3", v1_replacement: "2"}, { regex: "(Android) Honeycomb", v1_replacement: "3" }, { regex: "(IEMobile)[ /](\\d+)\\.(\\d+)", family_replacement: "IE Mobile" }, { regex: "(MSIE) (\\d+)\\.(\\d+).*XBLWP7", family_replacement: "IE Large Screen" }, {regex: "(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+)"}, {regex: "(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*)?"}, { regex: "(Obigo)InternetBrowser", other: !0 }, {regex: "(Obigo)\\-Browser", other: !0}, { regex: "(Obigo|OBIGO)[^\\d]*(\\d+)(?:.(\\d+))?", other: !0 }, { regex: "(MAXTHON|Maxthon) (\\d+)\\.(\\d+)", family_replacement: "Maxthon", other: !0 }, {regex: "(Maxthon|MyIE2|Uzbl|Shiira)", v1_replacement: "0", other: !0}, { regex: "(PLAYSTATION) (\\d+)", family_replacement: "PlayStation", manufacturer: "Sony" }, { regex: "(PlayStation Portable)[^\\d]+(\\d+).(\\d+)", manufacturer: "Sony" }, {regex: "(BrowseX) \\((\\d+)\\.(\\d+)\\.(\\d+)", other: !0}, { regex: "(POLARIS)/(\\d+)\\.(\\d+)", family_replacement: "Polaris", other: !0 }, { regex: "(Embider)/(\\d+)\\.(\\d+)", family_replacement: "Polaris", other: !0 }, { regex: "(BonEcho)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Bon Echo", other: !0 }, { regex: "(iPod).+Version/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPod).*Version/(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPod)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPhone).*Version/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPhone).*Version/(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPhone)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPad).*Version/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", tablet: !0, manufacturer: "Apple" }, { regex: "(iPad).*Version/(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", tablet: !0, manufacturer: "Apple" }, { regex: "(iPad)", family_replacement: "Mobile Safari", tablet: !0, manufacturer: "Apple" }, {regex: "(AvantGo) (\\d+).(\\d+)", other: !0}, { regex: "(Avant)", v1_replacement: "1", other: !0 }, { regex: "^(Nokia)", family_replacement: "Nokia Services (WAP) Browser", manufacturer: "Nokia" }, { regex: "(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)\\.(\\d+)", manufacturer: "Nokia" }, { regex: "(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)", manufacturer: "Nokia" }, { regex: "(NokiaBrowser)/(\\d+)\\.(\\d+)", manufacturer: "Nokia" }, { regex: "(BrowserNG)/(\\d+)\\.(\\d+).(\\d+)", family_replacement: "NokiaBrowser", manufacturer: "Nokia" }, { regex: "(Series60)/5\\.0", v2_replacement: "0", v1_replacement: "7", family_replacement: "NokiaBrowser", manufacturer: "Nokia" }, { regex: "(Series60)/(\\d+)\\.(\\d+)", family_replacement: "Nokia OSS Browser", manufacturer: "Nokia" }, { regex: "(S40OviBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Nokia Series 40 Ovi Browser", manufacturer: "Nokia" }, { regex: "(Nokia)[EN]?(\\d+)", manufacturer: "Nokia" }, { regex: "(PlayBook).+RIM Tablet OS (\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Blackberry WebKit", tablet: !0, manufacturer: "Nokia" }, { regex: "(Black[bB]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Blackberry WebKit", manufacturer: "RIM" }, { regex: "(Black[bB]erry)\\s?(\\d+)", family_replacement: "Blackberry", manufacturer: "RIM" }, {regex: "(OmniWeb)/v(\\d+)\\.(\\d+)", other: !0}, { regex: "(Blazer)/(\\d+)\\.(\\d+)", family_replacement: "Palm Blazer", manufacturer: "Palm" }, { regex: "(Pre)/(\\d+)\\.(\\d+)", family_replacement: "Palm Pre", manufacturer: "Palm" }, {regex: "(Links) \\((\\d+)\\.(\\d+)", other: !0}, { regex: "(QtWeb) Internet Browser/(\\d+)\\.(\\d+)", other: !0 }, { regex: "(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?", other: !0, tablet: !0 }, { regex: "(AppleWebKit)/(\\d+)\\.?(\\d+)?\\+ .* Version/\\d+\\.\\d+.\\d+ Safari/", family_replacement: "WebKit Nightly" }, { regex: "(Version)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?.*Safari/", family_replacement: "Safari" }, {regex: "(Safari)/\\d+"}, { regex: "(OLPC)/Update(\\d+)\\.(\\d+)", other: !0 }, { regex: "(OLPC)/Update()\\.(\\d+)", v1_replacement: "0", other: !0 }, {regex: "(SEMC\\-Browser)/(\\d+)\\.(\\d+)", other: !0}, { regex: "(Teleca)", family_replacement: "Teleca Browser", other: !0 }, {regex: "Trident(.*)rv.(\\d+)\\.(\\d+)", family_replacement: "IE"}, { regex: "(MSIE) (\\d+)\\.(\\d+)", family_replacement: "IE" }], os_parsers: [{regex: "(Android) (\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?"}, {regex: "(Android)\\-(\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?"}, { regex: "(Android) Donut", os_v2_replacement: "2", os_v1_replacement: "1" }, {regex: "(Android) Eclair", os_v2_replacement: "1", os_v1_replacement: "2"}, { regex: "(Android) Froyo", os_v2_replacement: "2", os_v1_replacement: "2" }, { regex: "(Android) Gingerbread", os_v2_replacement: "3", os_v1_replacement: "2" }, {regex: "(Android) Honeycomb", os_v1_replacement: "3"}, { regex: "(Silk-Accelerated=[a-z]{4,5})", os_replacement: "Android" }, {regex: "(Windows Phone 6\\.5)"}, { regex: "(Windows (?:NT 5\\.2|NT 5\\.1))", os_replacement: "Windows XP" }, {regex: "(XBLWP7)", os_replacement: "Windows Phone OS"}, { regex: "(Windows NT 6\\.1)", os_replacement: "Windows 7" }, { regex: "(Windows NT 6\\.0)", os_replacement: "Windows Vista" }, {regex: "(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\\.0|Windows Vista|Windows 2000)"}, { regex: "(Windows NT 6\\.2)", os_replacement: "Windows 8" }, {regex: "(Windows Phone 8)", os_replacement: "Windows Phone 8"}, { regex: "(Windows NT 5\\.0)", os_replacement: "Windows 2000" }, {regex: "(Windows Phone OS) (\\d+)\\.(\\d+)"}, { regex: "(Windows ?Mobile)", os_replacement: "Windows Mobile" }, {regex: "(WinNT4.0)", os_replacement: "Windows NT 4.0"}, { regex: "(Win98)", os_replacement: "Windows 98" }, {regex: "(Tizen)/(\\d+)\\.(\\d+)", other: !0}, { regex: "(Mac OS X) (\\d+)[_.](\\d+)(?:[_.](\\d+))?", manufacturer: "Apple" }, { regex: "(?:PPC|Intel) (Mac OS X)", manufacturer: "Apple" }, { regex: "(CPU OS|iPhone OS) (\\d+)_(\\d+)(?:_(\\d+))?", os_replacement: "iOS", manufacturer: "Apple" }, { regex: "(iPhone|iPad|iPod); Opera", os_replacement: "iOS", manufacturer: "Apple" }, { regex: "(iPad); Opera", tablet: !0, manufacturer: "Apple" }, { regex: "(iPhone|iPad|iPod).*Mac OS X.*Version/(\\d+)\\.(\\d+)", os_replacement: "iOS", manufacturer: "Apple" }, { regex: "(CrOS) [a-z0-9_]+ (\\d+)\\.(\\d+)(?:\\.(\\d+))?", os_replacement: "Chrome OS" }, { regex: "(Debian)-(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?", other: !0 }, { regex: "(Linux Mint)(?:/(\\d+))?", other: !0 }, { regex: "(Mandriva)(?: Linux)?/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?", other: !0 }, { regex: "(Symbian[Oo][Ss])/(\\d+)\\.(\\d+)", os_replacement: "Symbian OS" }, { regex: "(Symbian/3).+NokiaBrowser/7\\.3", os_replacement: "Symbian^3 Anna" }, {regex: "(Symbian/3).+NokiaBrowser/7\\.4", os_replacement: "Symbian^3 Belle"}, { regex: "(Symbian/3)", os_replacement: "Symbian^3" }, {regex: "(Series 60|SymbOS|S60)", os_replacement: "Symbian OS"}, { regex: "(MeeGo)", other: !0 }, { regex: "Symbian [Oo][Ss]", os_replacement: "Symbian OS" }, { regex: "(Black[Bb]erry)[0-9a-z]+/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?", os_replacement: "BlackBerry OS", manufacturer: "RIM" }, { regex: "(Black[Bb]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?", os_replacement: "BlackBerry OS", manufacturer: "RIM" }, { regex: "(RIM Tablet OS) (\\d+)\\.(\\d+)\\.(\\d+)", os_replacement: "BlackBerry Tablet OS", tablet: !0, manufacturer: "RIM" }, { regex: "(Play[Bb]ook)", os_replacement: "BlackBerry Tablet OS", tablet: !0, manufacturer: "RIM" }, { regex: "(Black[Bb]erry)", os_replacement: "Blackberry OS", manufacturer: "RIM" }, { regex: "(webOS|hpwOS)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?", os_replacement: "webOS" }, { regex: "(SUSE|Fedora|Red Hat|PCLinuxOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)", other: !0 }, { regex: "(SUSE|Fedora|Red Hat|Puppy|PCLinuxOS|CentOS)/(\\d+)\\.(\\d+)\\.(\\d+)", other: !0 }, {regex: "(Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Red Hat|Slackware)/(\\d+)\\.(\\d+)"}, {regex: "(Windows|OpenBSD|FreeBSD|NetBSD|Ubuntu|Kubuntu|Android|Arch Linux|CentOS|WeTab|Slackware)"}, { regex: "(Linux|BSD)", other: !0 }], mobile_os_families: ["Windows Phone 6.5", "Windows CE", "Symbian OS"], device_parsers: [{ regex: "HTC ([A-Z][a-z0-9]+) Build", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "HTC ([A-Z][a-z0-9 ]+) \\d+\\.\\d+\\.\\d+\\.\\d+", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "HTC_Touch_([A-Za-z0-9]+)", device_replacement: "HTC Touch ($1)", manufacturer: "HTC" }, { regex: "USCCHTC(\\d+)", device_replacement: "HTC $1 (US Cellular)", manufacturer: "HTC" }, { regex: "Sprint APA(9292)", device_replacement: "HTC $1 (Sprint)", manufacturer: "HTC" }, { regex: "HTC ([A-Za-z0-9]+ [A-Z])", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "HTC-([A-Za-z0-9]+)", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "HTC_([A-Za-z0-9]+)", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "HTC ([A-Za-z0-9]+)", device_replacement: "HTC $1", manufacturer: "HTC" }, {regex: "(ADR[A-Za-z0-9]+)", device_replacement: "HTC $1", manufacturer: "HTC"}, { regex: "(HTC)", manufacturer: "HTC" }, { regex: "SonyEricsson([A-Za-z0-9]+)/", device_replacement: "Ericsson $1", other: !0, manufacturer: "Sony" }, {regex: "Android[\\- ][\\d]+\\.[\\d]+\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; WOWMobile (.+) Build"}, {regex: "Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"}, {regex: "Android[\\- ][\\d]+\\.[\\d]+\\-update1\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"}, {regex: "Android[\\- ][\\d]+\\.[\\d]+\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build"}, {regex: "Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; (.+) Build"}, { regex: "NokiaN([0-9]+)", device_replacement: "Nokia N$1", manufacturer: "Nokia" }, { regex: "Nokia([A-Za-z0-9\\v-]+)", device_replacement: "Nokia $1", manufacturer: "Nokia" }, { regex: "NOKIA ([A-Za-z0-9\\-]+)", device_replacement: "Nokia $1", manufacturer: "Nokia" }, { regex: "Nokia ([A-Za-z0-9\\-]+)", device_replacement: "Nokia $1", manufacturer: "Nokia" }, { regex: "Lumia ([A-Za-z0-9\\-]+)", device_replacement: "Lumia $1", manufacturer: "Nokia" }, { regex: "Symbian", device_replacement: "Nokia", manufacturer: "Nokia" }, { regex: "(PlayBook).+RIM Tablet OS", device_replacement: "Blackberry Playbook", tablet: !0, manufacturer: "RIM" }, {regex: "(Black[Bb]erry [0-9]+);", manufacturer: "RIM"}, { regex: "Black[Bb]erry([0-9]+)", device_replacement: "BlackBerry $1", manufacturer: "RIM" }, { regex: "(Pre)/(\\d+)\\.(\\d+)", device_replacement: "Palm Pre", manufacturer: "Palm" }, { regex: "(Pixi)/(\\d+)\\.(\\d+)", device_replacement: "Palm Pixi", manufacturer: "Palm" }, { regex: "(Touchpad)/(\\d+)\\.(\\d+)", device_replacement: "HP Touchpad", manufacturer: "HP" }, { regex: "HPiPAQ([A-Za-z0-9]+)/(\\d+).(\\d+)", device_replacement: "HP iPAQ $1", manufacturer: "HP" }, { regex: "Palm([A-Za-z0-9]+)", device_replacement: "Palm $1", manufacturer: "Palm" }, { regex: "Treo([A-Za-z0-9]+)", device_replacement: "Palm Treo $1", manufacturer: "Palm" }, { regex: "webOS.*(P160UNA)/(\\d+).(\\d+)", device_replacement: "HP Veer", manufacturer: "HP" }, {regex: "(Kindle Fire)", manufacturer: "Amazon"}, { regex: "(Kindle)", manufacturer: "Amazon" }, { regex: "(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?", device_replacement: "Kindle Fire", tablet: !0, manufacturer: "Amazon" }, {regex: "(iPad) Simulator;", manufacturer: "Apple"}, { regex: "(iPad);", manufacturer: "Apple" }, {regex: "(iPod);", manufacturer: "Apple"}, { regex: "(iPhone) Simulator;", manufacturer: "Apple" }, {regex: "(iPhone);", manufacturer: "Apple"}, { regex: "Nexus\\ ([A-Za-z0-9\\-]+)", device_replacement: "Nexus $1" }, { regex: "acer_([A-Za-z0-9]+)_", device_replacement: "Acer $1", manufacturer: "Acer" }, { regex: "acer_([A-Za-z0-9]+)_", device_replacement: "Acer $1", manufacturer: "Acer" }, { regex: "Amoi\\-([A-Za-z0-9]+)", device_replacement: "Amoi $1", other: !0, manufacturer: "Amoi" }, { regex: "AMOI\\-([A-Za-z0-9]+)", device_replacement: "Amoi $1", other: !0, manufacturer: "Amoi" }, { regex: "Asus\\-([A-Za-z0-9]+)", device_replacement: "Asus $1", manufacturer: "Asus" }, { regex: "ASUS\\-([A-Za-z0-9]+)", device_replacement: "Asus $1", manufacturer: "Asus" }, { regex: "BIRD\\-([A-Za-z0-9]+)", device_replacement: "Bird $1", other: !0 }, { regex: "BIRD\\.([A-Za-z0-9]+)", device_replacement: "Bird $1", other: !0 }, {regex: "BIRD ([A-Za-z0-9]+)", device_replacement: "Bird $1", other: !0}, { regex: "Dell ([A-Za-z0-9]+)", device_replacement: "Dell $1", manufacturer: "Dell" }, { regex: "DoCoMo/2\\.0 ([A-Za-z0-9]+)", device_replacement: "DoCoMo $1", other: !0 }, { regex: "([A-Za-z0-9]+)\\_W\\;FOMA", device_replacement: "DoCoMo $1", other: !0 }, { regex: "([A-Za-z0-9]+)\\;FOMA", device_replacement: "DoCoMo $1", other: !0 }, { regex: "vodafone([A-Za-z0-9]+)", device_replacement: "Huawei Vodafone $1", other: !0 }, { regex: "i\\-mate ([A-Za-z0-9]+)", device_replacement: "i-mate $1", other: !0 }, { regex: "Kyocera\\-([A-Za-z0-9]+)", device_replacement: "Kyocera $1", other: !0 }, { regex: "KWC\\-([A-Za-z0-9]+)", device_replacement: "Kyocera $1", other: !0 }, { regex: "Lenovo\\-([A-Za-z0-9]+)", device_replacement: "Lenovo $1", manufacturer: "Lenovo" }, { regex: "Lenovo\\_([A-Za-z0-9]+)", device_replacement: "Lenovo $1", manufacturer: "Levovo" }, { regex: "LG/([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LG-LG([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LGE-LG([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LGE VX([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LG ([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LGE LG\\-AX([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LG\\-([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LGE\\-([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LG([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "(KIN)\\.One (\\d+)\\.(\\d+)", device_replacement: "Microsoft $1" }, { regex: "(KIN)\\.Two (\\d+)\\.(\\d+)", device_replacement: "Microsoft $1" }, {regex: "(Motorola)\\-([A-Za-z0-9]+)", manufacturer: "Motorola"}, { regex: "MOTO\\-([A-Za-z0-9]+)", device_replacement: "Motorola $1", manufacturer: "Motorola" }, { regex: "MOT\\-([A-Za-z0-9]+)", device_replacement: "Motorola $1", manufacturer: "Motorola" }, { regex: "Philips([A-Za-z0-9]+)", device_replacement: "Philips $1", manufacturer: "Philips" }, { regex: "Philips ([A-Za-z0-9]+)", device_replacement: "Philips $1", manufacturer: "Philips" }, { regex: "SAMSUNG-([A-Za-z0-9\\-]+)", device_replacement: "Samsung $1", manufacturer: "Samsung" }, { regex: "SAMSUNG\\; ([A-Za-z0-9\\-]+)", device_replacement: "Samsung $1", manufacturer: "Samsung" }, { regex: "Softbank/1\\.0/([A-Za-z0-9]+)", device_replacement: "Softbank $1", other: !0 }, { regex: "Softbank/2\\.0/([A-Za-z0-9]+)", device_replacement: "Softbank $1", other: !0 }, { regex: "(hiptop|avantgo|plucker|xiino|blazer|elaine|up.browser|up.link|mmp|smartphone|midp|wap|vodafone|o2|pocket|mobile|pda)", device_replacement: "Generic Smartphone" }, { regex: "^(1207|3gso|4thp|501i|502i|503i|504i|505i|506i|6310|6590|770s|802s|a wa|acer|acs\\-|airn|alav|asus|attw|au\\-m|aur |aus |abac|acoo|aiko|alco|alca|amoi|anex|anny|anyw|aptu|arch|argo|bell|bird|bw\\-n|bw\\-u|beck|benq|bilb|blac|c55/|cdm\\-|chtm|capi|comp|cond|craw|dall|dbte|dc\\-s|dica|ds\\-d|ds12|dait|devi|dmob|doco|dopo|el49|erk0|esl8|ez40|ez60|ez70|ezos|ezze|elai|emul|eric|ezwa|fake|fly\\-|fly\\_|g\\-mo|g1 u|g560|gf\\-5|grun|gene|go.w|good|grad|hcit|hd\\-m|hd\\-p|hd\\-t|hei\\-|hp i|hpip|hs\\-c|htc |htc\\-|htca|htcg)", device_replacement: "Generic Feature Phone" }, { regex: "^(htcp|htcs|htct|htc\\_|haie|hita|huaw|hutc|i\\-20|i\\-go|i\\-ma|i230|iac|iac\\-|iac/|ig01|im1k|inno|iris|jata|java|kddi|kgt|kgt/|kpt |kwc\\-|klon|lexi|lg g|lg\\-a|lg\\-b|lg\\-c|lg\\-d|lg\\-f|lg\\-g|lg\\-k|lg\\-l|lg\\-m|lg\\-o|lg\\-p|lg\\-s|lg\\-t|lg\\-u|lg\\-w|lg/k|lg/l|lg/u|lg50|lg54|lge\\-|lge/|lynx|leno|m1\\-w|m3ga|m50/|maui|mc01|mc21|mcca|medi|meri|mio8|mioa|mo01|mo02|mode|modo|mot |mot\\-|mt50|mtp1|mtv |mate|maxo|merc|mits|mobi|motv|mozz|n100|n101|n102|n202|n203|n300|n302|n500|n502|n505|n700|n701|n710|nec\\-|nem\\-|newg|neon)", device_replacement: "Generic Feature Phone" }, { regex: "^(netf|noki|nzph|o2 x|o2\\-x|opwv|owg1|opti|oran|ot\\-s|p800|pand|pg\\-1|pg\\-2|pg\\-3|pg\\-6|pg\\-8|pg\\-c|pg13|phil|pn\\-2|pt\\-g|palm|pana|pire|pock|pose|psio|qa\\-a|qc\\-2|qc\\-3|qc\\-5|qc\\-7|qc07|qc12|qc21|qc32|qc60|qci\\-|qwap|qtek|r380|r600|raks|rim9|rove|s55/|sage|sams|sc01|sch\\-|scp\\-|sdk/|se47|sec\\-|sec0|sec1|semc|sgh\\-|shar|sie\\-|sk\\-0|sl45|slid|smb3|smt5|sp01|sph\\-|spv |spv\\-|sy01|samm|sany|sava|scoo|send|siem|smar|smit|soft|sony|t\\-mo|t218|t250|t600|t610|t618|tcl\\-|tdg\\-|telm|tim\\-|ts70|tsm\\-|tsm3|tsm5|tx\\-9|tagt)", device_replacement: "Generic Feature Phone" }, { regex: "^(talk|teli|topl|tosh|up.b|upg1|utst|v400|v750|veri|vk\\-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vite|voda|vulc|w3c |w3c\\-|wapj|wapp|wapu|wapm|wig |wapi|wapr|wapv|wapy|wapa|waps|wapt|winc|winw|wonu|x700|xda2|xdag|yas\\-|your|zte\\-|zeto|aste|audi|avan|blaz|brew|brvw|bumb|ccwa|cell|cldc|cmd\\-|dang|eml2|fetc|hipt|http|ibro|idea|ikom|ipaq|jbro|jemu|jigs|keji|kyoc|kyok|libw|m\\-cr|midp|mmef|moto|mwbp|mywa|newt|nok6|o2im|pant|pdxg|play|pluc|port|prox|rozo|sama|seri|smal|symb|treo|upsi|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|wap\\-|webc|whit|wmlb|xda\\-|xda\\_)", device_replacement: "Generic Feature Phone" }, { regex: "(bot|borg|google(^tv)|yahoo|slurp|msnbot|msrbot|openbot|archiver|netresearch|lycos|scooter|altavista|teoma|gigabot|baiduspider|blitzbot|oegp|charlotte|furlbot|http%20client|polybot|htdig|ichiro|mogimogi|larbin|pompos|scrubby|searchsight|seekbot|semanticdiscovery|silk|snappy|speedy|spider|voila|vortex|voyager|zao|zeal|fast\\-webcrawler|converacrawler|dataparksearch|findlinks)", device_replacement: "Spider" }], mobile_browser_families: ["Firefox Mobile", "Opera Mobile", "Opera Mini", "Mobile Safari", "webOS", "IE Mobile", "Playstation Portable", "Nokia", "Blackberry", "Palm", "Silk", "Android", "Maemo", "Obigo", "Netfront", "AvantGo", "Teleca", "SEMC-Browser", "Bolt", "Iris", "UP.Browser", "Symphony", "Minimo", "Bunjaloo", "Jasmine", "Dolfin", "Polaris", "BREW", "Chrome Mobile", "Chrome Mobile iOS", "UC Browser", "Tizen Browser"] }; e.parsers = ["device_parsers", "browser_parsers", "os_parsers", "mobile_os_families", "mobile_browser_families"], e.types = ["browser", "os", "device"], e.regexes = r || function () { var r = {}; return e.parsers.map(function (e) { r[e] = [] }), r }(), e.families = function () { var r = {}; return e.types.map(function (e) { r[e] = [] }), r }(); var a = Array.prototype, t = (Object.prototype, Function.prototype, a.forEach); a.indexOf; var n = function (e, r) { for (var a = {}, t = 0; r.length > t && !(a = r[t](e)); t++); return a }, o = function (e, r) { i(e, function (e) { i(r, function (r) { delete e[r] }) }) }, i = forEach = function (e, r, a) { if (null != e)if (t && e.forEach === t)e.forEach(r, a); else if (e.length === +e.length)for (var n = 0, o = e.length; o > n; n++)r.call(a, e[n], n, e); else for (var i in e)_.has(e, i) && r.call(a, e[i], i, e) }, l = function (e) { return !(!e || void 0 === e || null == e) }, d = function (e) { var r = ""; return e = e || {}, l(e) && l(e.major) && (r += e.major, l(e.minor) && (r += "." + e.minor, l(e.patch) && (r += "." + e.patch))), r }, c = function (e) { e = e || {}; var r = d(e); return r && (r = " " + r), e && l(e.family) ? e.family + r : "" }; return e.parse = function (r) { var a = function (r) { return e.regexes[r + "_parsers"].map(function (e) { function a(r) { var a = r.match(t); if (!a)return null; var i = {}; return i.family = (n ? n.replace("$1", a[1]) : a[1]) || "other", i.major = parseInt(o ? o : a[2]) || null, i.minor = a[3] ? parseInt(a[3]) : null, i.patch = a[4] ? parseInt(a[4]) : null, i.tablet = e.tablet, i.man = e.manufacturer || null, i } var t = RegExp(e.regex), n = e[("browser" === r ? "family" : r) + "_replacement"], o = e.major_version_replacement; return a }) }, t = function () { }, i = a("browser"), m = a("os"), s = a("device"), p = new t; p.source = r, p.browser = n(r, i), l(p.browser) ? (p.browser.name = c(p.browser), p.browser.version = d(p.browser)) : p.browser = {}, p.os = n(r, m), l(p.os) ? (p.os.name = c(p.os), p.os.version = d(p.os)) : p.os = {}, p.device = n(r, s), l(p.device) ? (p.device.name = c(p.device), p.device.version = d(p.device)) : p.device = { tablet: !1, family: "Other" }; var u = {}; return e.regexes.mobile_browser_families.map(function (e) { u[e] = !0 }), e.regexes.mobile_os_families.map(function (e) { u[e] = !0 }), p.device.type = "Spider" === p.browser.family ? "Spider" : p.browser.tablet || p.os.tablet || p.device.tablet ? "Tablet" : u.hasOwnProperty(p.browser.family) ? "Mobile" : "Desktop", p.device.manufacturer = p.browser.man || p.os.man || p.device.man || null, o([p.browser, p.os, p.device], ["tablet", "man"]), p }, e }(); "undefined" != typeof exports ? ("undefined" != typeof module && module.exports && (exports = module.exports = r), exports.detect = r) : e.detect = r, "function" == typeof define && define.amd && define(function () { return r }) }(window), function () { function e(e) { return !!e.exifdata } function r(e, r) { r = r || e.match(/^data\:([^\;]+)\;base64,/im)[1] || "", e = e.replace(/^data\:([^\;]+)\;base64,/gim, ""); for (var a = atob(e), t = a.length, n = new ArrayBuffer(t), o = new Uint8Array(n), i = 0; t > i; i++)o[i] = a.charCodeAt(i); return n } function a(e, r) { var a = new XMLHttpRequest; a.open("GET", e, !0), a.responseType = "blob", a.onload = function (e) { (200 == this.status || 0 === this.status) && r(this.response) }, a.send() } function t(e, t) { function n(r) { var a = o(r), n = i(r); e.exifdata = a || {}, e.iptcdata = n || {}, t && t.call(e) } if (e.src)if (/^data\:/i.test(e.src)) { var l = r(e.src); n(l) } else if (/^blob\:/i.test(e.src)) { var d = new FileReader; d.onload = function (e) { n(e.target.result) }, a(e.src, function (e) { d.readAsArrayBuffer(e) }) } else { var c = new XMLHttpRequest; c.onload = function () { if (200 != this.status && 0 !== this.status)throw"Could not load image"; n(c.response), c = null }, c.open("GET", e.src, !0), c.responseType = "arraybuffer", c.send(null) } else if (window.FileReader && (e instanceof window.Blob || e instanceof window.File)) { var d = new FileReader; d.onload = function (e) { p && console.log("Got file of length " + e.target.result.byteLength), n(e.target.result) }, d.readAsArrayBuffer(e) } } function o(e) { var r = new DataView(e); if (p && console.log("Got file of length " + e.byteLength), 255 != r.getUint8(0) || 216 != r.getUint8(1))return p && console.log("Not a valid JPEG"), !1; for (var a, t = 2, n = e.byteLength; n > t;) { if (255 != r.getUint8(t))return p && console.log("Not a valid marker at offset " + t + ", found: " + r.getUint8(t)), !1; if (a = r.getUint8(t + 1), p && console.log(a), 225 == a)return p && console.log("Found 0xFFE1 marker"), s(r, t + 4, r.getUint16(t + 2) - 2); t += 2 + r.getUint16(t + 2) } } function i(e) { var r = new DataView(e); if (p && console.log("Got file of length " + e.byteLength), 255 != r.getUint8(0) || 216 != r.getUint8(1))return p && console.log("Not a valid JPEG"), !1; for (var a = 2, t = e.byteLength, n = function (e, r) { return 56 === e.getUint8(r) && 66 === e.getUint8(r + 1) && 73 === e.getUint8(r + 2) && 77 === e.getUint8(r + 3) && 4 === e.getUint8(r + 4) && 4 === e.getUint8(r + 5) }; t > a;) { if (n(r, a)) { var o = r.getUint8(a + 7); o % 2 !== 0 && (o += 1), 0 === o && (o = 4); var i = a + 8 + o, d = r.getUint16(a + 6 + o); return l(e, i, d) } a++ } } function l(e, r, a) { for (var t, n, o, i, l, d = new DataView(e), c = {}, s = r; r + a > s;)28 === d.getUint8(s) && 2 === d.getUint8(s + 1) && (i = d.getUint8(s + 2), i in y && (o = d.getInt16(s + 3), l = o + 5, n = y[i], t = m(d, s + 5, o), c.hasOwnProperty(n) ? c[n]instanceof Array ? c[n].push(t) : c[n] = [c[n], t] : c[n] = t)), s++; return c } function d(e, r, a, t, n) { var o, i, l, d = e.getUint16(a, !n), m = {}; for (l = 0; d > l; l++)o = a + 12 * l + 2, i = t[e.getUint16(o, !n)], !i && p && console.log("Unknown tag: " + e.getUint16(o, !n)), m[i] = c(e, o, r, a, n); return m } function c(e, r, a, t, n) { var o, i, l, d, c, s, p = e.getUint16(r + 2, !n), u = e.getUint32(r + 4, !n), g = e.getUint32(r + 8, !n) + a; switch (p) { case 1: case 7: if (1 == u)return e.getUint8(r + 8, !n); for (o = u > 4 ? g : r + 8, i = [], d = 0; u > d; d++)i[d] = e.getUint8(o + d); return i; case 2: return o = u > 4 ? g : r + 8, m(e, o, u - 1); case 3: if (1 == u)return e.getUint16(r + 8, !n); for (o = u > 2 ? g : r + 8, i = [], d = 0; u > d; d++)i[d] = e.getUint16(o + 2 * d, !n); return i; case 4: if (1 == u)return e.getUint32(r + 8, !n); for (i = [], d = 0; u > d; d++)i[d] = e.getUint32(g + 4 * d, !n); return i; case 5: if (1 == u)return c = e.getUint32(g, !n), s = e.getUint32(g + 4, !n), l = new Number(c / s), l.numerator = c, l.denominator = s, l; for (i = [], d = 0; u > d; d++)c = e.getUint32(g + 8 * d, !n), s = e.getUint32(g + 4 + 8 * d, !n), i[d] = new Number(c / s), i[d].numerator = c, i[d].denominator = s; return i; case 9: if (1 == u)return e.getInt32(r + 8, !n); for (i = [], d = 0; u > d; d++)i[d] = e.getInt32(g + 4 * d, !n); return i; case 10: if (1 == u)return e.getInt32(g, !n) / e.getInt32(g + 4, !n); for (i = [], d = 0; u > d; d++)i[d] = e.getInt32(g + 8 * d, !n) / e.getInt32(g + 4 + 8 * d, !n); return i } } function m(e, r, a) { var t = ""; for (n = r; n < r + a; n++)t += String.fromCharCode(e.getUint8(n)); return t } function s(e, r) { if ("Exif" != m(e, r, 4))return p && console.log("Not valid EXIF data! " + m(e, r, 4)), !1; var a, t, n, o, i, l = r + 6; if (18761 == e.getUint16(l))a = !1; else { if (19789 != e.getUint16(l))return p && console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"), !1; a = !0 } if (42 != e.getUint16(l + 2, !a))return p && console.log("Not valid TIFF data! (no 0x002A)"), !1; var c = e.getUint32(l + 4, !a); if (8 > c)return p && console.log("Not valid TIFF data! (First offset less than 8)", e.getUint32(l + 4, !a)), !1; if (t = d(e, l, l + c, x, a), t.ExifIFDPointer) { o = d(e, l, l + t.ExifIFDPointer, f, a); for (n in o) { switch (n) { case"LightSource": case"Flash": case"MeteringMode": case"ExposureProgram": case"SensingMethod": case"SceneCaptureType": case"SceneType": case"CustomRendered": case"WhiteBalance": case"GainControl": case"Contrast": case"Saturation": case"Sharpness": case"SubjectDistanceRange": case"FileSource": o[n] = b[n][o[n]]; break; case"ExifVersion": case"FlashpixVersion": o[n] = String.fromCharCode(o[n][0], o[n][1], o[n][2], o[n][3]); break; case"ComponentsConfiguration": o[n] = b.Components[o[n][0]] + b.Components[o[n][1]] + b.Components[o[n][2]] + b.Components[o[n][3]] } t[n] = o[n] } } if (t.GPSInfoIFDPointer) { i = d(e, l, l + t.GPSInfoIFDPointer, h, a); for (n in i) { switch (n) { case"GPSVersionID": i[n] = i[n][0] + "." + i[n][1] + "." + i[n][2] + "." + i[n][3] } t[n] = i[n] } } return t } var p = !1, u = this, g = function (e) { return e instanceof g ? e : this instanceof g ? void(this.EXIFwrapped = e) : new g(e) }; "undefined" != typeof exports ? ("undefined" != typeof module && module.exports && (exports = module.exports = g), exports.EXIF = g) : u.EXIF = g; var f = g.Tags = { 36864: "ExifVersion", 40960: "FlashpixVersion", 40961: "ColorSpace", 40962: "PixelXDimension", 40963: "PixelYDimension", 37121: "ComponentsConfiguration", 37122: "CompressedBitsPerPixel", 37500: "MakerNote", 37510: "UserComment", 40964: "RelatedSoundFile", 36867: "DateTimeOriginal", 36868: "DateTimeDigitized", 37520: "SubsecTime", 37521: "SubsecTimeOriginal", 37522: "SubsecTimeDigitized", 33434: "ExposureTime", 33437: "FNumber", 34850: "ExposureProgram", 34852: "SpectralSensitivity", 34855: "ISOSpeedRatings", 34856: "OECF", 37377: "ShutterSpeedValue", 37378: "ApertureValue", 37379: "BrightnessValue", 37380: "ExposureBias", 37381: "MaxApertureValue", 37382: "SubjectDistance", 37383: "MeteringMode", 37384: "LightSource", 37385: "Flash", 37396: "SubjectArea", 37386: "FocalLength", 41483: "FlashEnergy", 41484: "SpatialFrequencyResponse", 41486: "FocalPlaneXResolution", 41487: "FocalPlaneYResolution", 41488: "FocalPlaneResolutionUnit", 41492: "SubjectLocation", 41493: "ExposureIndex", 41495: "SensingMethod", 41728: "FileSource", 41729: "SceneType", 41730: "CFAPattern", 41985: "CustomRendered", 41986: "ExposureMode", 41987: "WhiteBalance", 41988: "DigitalZoomRation", 41989: "FocalLengthIn35mmFilm", 41990: "SceneCaptureType", 41991: "GainControl", 41992: "Contrast", 41993: "Saturation", 41994: "Sharpness", 41995: "DeviceSettingDescription", 41996: "SubjectDistanceRange", 40965: "InteroperabilityIFDPointer", 42016: "ImageUniqueID" }, x = g.TiffTags = { 256: "ImageWidth", 257: "ImageHeight", 34665: "ExifIFDPointer", 34853: "GPSInfoIFDPointer", 40965: "InteroperabilityIFDPointer", 258: "BitsPerSample", 259: "Compression", 262: "PhotometricInterpretation", 274: "Orientation", 277: "SamplesPerPixel", 284: "PlanarConfiguration", 530: "YCbCrSubSampling", 531: "YCbCrPositioning", 282: "XResolution", 283: "YResolution", 296: "ResolutionUnit", 273: "StripOffsets", 278: "RowsPerStrip", 279: "StripByteCounts", 513: "JPEGInterchangeFormat", 514: "JPEGInterchangeFormatLength", 301: "TransferFunction", 318: "WhitePoint", 319: "PrimaryChromaticities", 529: "YCbCrCoefficients", 532: "ReferenceBlackWhite", 306: "DateTime", 270: "ImageDescription", 271: "Make", 272: "Model", 305: "Software", 315: "Artist", 33432: "Copyright" }, h = g.GPSTags = { 0: "GPSVersionID", 1: "GPSLatitudeRef", 2: "GPSLatitude", 3: "GPSLongitudeRef", 4: "GPSLongitude", 5: "GPSAltitudeRef", 6: "GPSAltitude", 7: "GPSTimeStamp", 8: "GPSSatellites", 9: "GPSStatus", 10: "GPSMeasureMode", 11: "GPSDOP", 12: "GPSSpeedRef", 13: "GPSSpeed", 14: "GPSTrackRef", 15: "GPSTrack", 16: "GPSImgDirectionRef", 17: "GPSImgDirection", 18: "GPSMapDatum", 19: "GPSDestLatitudeRef", 20: "GPSDestLatitude", 21: "GPSDestLongitudeRef", 22: "GPSDestLongitude", 23: "GPSDestBearingRef", 24: "GPSDestBearing", 25: "GPSDestDistanceRef", 26: "GPSDestDistance", 27: "GPSProcessingMethod", 28: "GPSAreaInformation", 29: "GPSDateStamp", 30: "GPSDifferential" }, b = g.StringValues = { ExposureProgram: { 0: "Not defined", 1: "Manual", 2: "Normal program", 3: "Aperture priority", 4: "Shutter priority", 5: "Creative program", 6: "Action program", 7: "Portrait mode", 8: "Landscape mode" }, MeteringMode: { 0: "Unknown", 1: "Average", 2: "CenterWeightedAverage", 3: "Spot", 4: "MultiSpot", 5: "Pattern", 6: "Partial", 255: "Other" }, LightSource: { 0: "Unknown", 1: "Daylight", 2: "Fluorescent", 3: "Tungsten (incandescent light)", 4: "Flash", 9: "Fine weather", 10: "Cloudy weather", 11: "Shade", 12: "Daylight fluorescent (D 5700 - 7100K)", 13: "Day white fluorescent (N 4600 - 5400K)", 14: "Cool white fluorescent (W 3900 - 4500K)", 15: "White fluorescent (WW 3200 - 3700K)", 17: "Standard light A", 18: "Standard light B", 19: "Standard light C", 20: "D55", 21: "D65", 22: "D75", 23: "D50", 24: "ISO studio tungsten", 255: "Other" }, Flash: { 0: "Flash did not fire", 1: "Flash fired", 5: "Strobe return light not detected", 7: "Strobe return light detected", 9: "Flash fired, compulsory flash mode", 13: "Flash fired, compulsory flash mode, return light not detected", 15: "Flash fired, compulsory flash mode, return light detected", 16: "Flash did not fire, compulsory flash mode", 24: "Flash did not fire, auto mode", 25: "Flash fired, auto mode", 29: "Flash fired, auto mode, return light not detected", 31: "Flash fired, auto mode, return light detected", 32: "No flash function", 65: "Flash fired, red-eye reduction mode", 69: "Flash fired, red-eye reduction mode, return light not detected", 71: "Flash fired, red-eye reduction mode, return light detected", 73: "Flash fired, compulsory flash mode, red-eye reduction mode", 77: "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected", 79: "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected", 89: "Flash fired, auto mode, red-eye reduction mode", 93: "Flash fired, auto mode, return light not detected, red-eye reduction mode", 95: "Flash fired, auto mode, return light detected, red-eye reduction mode" }, SensingMethod: { 1: "Not defined", 2: "One-chip color area sensor", 3: "Two-chip color area sensor", 4: "Three-chip color area sensor", 5: "Color sequential area sensor", 7: "Trilinear sensor", 8: "Color sequential linear sensor" }, SceneCaptureType: {0: "Standard", 1: "Landscape", 2: "Portrait", 3: "Night scene"}, SceneType: {1: "Directly photographed"}, CustomRendered: {0: "Normal process", 1: "Custom process"}, WhiteBalance: {0: "Auto white balance", 1: "Manual white balance"}, GainControl: {0: "None", 1: "Low gain up", 2: "High gain up", 3: "Low gain down", 4: "High gain down"}, Contrast: {0: "Normal", 1: "Soft", 2: "Hard"}, Saturation: {0: "Normal", 1: "Low saturation", 2: "High saturation"}, Sharpness: {0: "Normal", 1: "Soft", 2: "Hard"}, SubjectDistanceRange: {0: "Unknown", 1: "Macro", 2: "Close view", 3: "Distant view"}, FileSource: {3: "DSC"}, Components: {0: "", 1: "Y", 2: "Cb", 3: "Cr", 4: "R", 5: "G", 6: "B"} }, y = { 120: "caption", 110: "credit", 25: "keywords", 55: "dateCreated", 80: "byline", 85: "bylineTitle", 122: "captionWriter", 105: "headline", 116: "copyright", 15: "category" }; g.getData = function (r, a) { return (r instanceof Image || r instanceof HTMLImageElement) && !r.complete ? !1 : (e(r) ? a && a.call(r) : t(r, a), !0) }, g.getTag = function (r, a) { return e(r) ? r.exifdata[a] : void 0 }, g.getAllTags = function (r) { if (!e(r))return {}; var a, t = r.exifdata, n = {}; for (a in t)t.hasOwnProperty(a) && (n[a] = t[a]); return n }, g.pretty = function (r) { if (!e(r))return ""; var a, t = r.exifdata, n = ""; for (a in t)t.hasOwnProperty(a) && (n += "object" == typeof t[a] ? t[a]instanceof Number ? a + " : " + t[a] + " [" + t[a].numerator + "/" + t[a].denominator + "]\r\n" : a + " : [" + t[a].length + " values]\r\n" : a + " : " + t[a] + "\r\n"); return n }, g.readFromBinaryFile = function (e) { return o(e) }, "function" == typeof define && define.amd && define("exif-js", [], function () { return g }) }.call(this); function JPEGEncoder(r) { function a(r) { for (var a = [16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99], e = 0; 64 > e; e++) { var t = U((a[e] * r + 50) / 100); 1 > t ? t = 1 : t > 255 && (t = 255), k[q[e]] = t } for (var n = [17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99], o = 0; 64 > o; o++) { var i = U((n[o] * r + 50) / 100); 1 > i ? i = 1 : i > 255 && (i = 255), p[q[o]] = i } for (var c = [1, 1.387039845, 1.306562965, 1.175875602, 1, .785694958, .5411961, .275899379], f = 0, s = 0; 8 > s; s++)for (var v = 0; 8 > v; v++)M[f] = 1 / (k[q[f]] * c[s] * c[v] * 8), j[f] = 1 / (p[q[f]] * c[s] * c[v] * 8), f++ } function e(r, a) { for (var e = 0, t = 0, n = new Array, o = 1; 16 >= o; o++) { for (var i = 1; i <= r[o]; i++)n[a[t]] = [], n[a[t]][0] = e, n[a[t]][1] = o, t++, e++; e *= 2 } return n } function t() { y = e(z, G), L = e(S, F), I = e(J, Q), A = e(K, V) } function n() { for (var r = 1, a = 2, e = 1; 15 >= e; e++) { for (var t = r; a > t; t++)C[32767 + t] = e, E[32767 + t] = [], E[32767 + t][1] = e, E[32767 + t][0] = t; for (var n = -(a - 1); -r >= n; n++)C[32767 + n] = e, E[32767 + n] = [], E[32767 + n][1] = e, E[32767 + n][0] = a - 1 + n; r <<= 1, a <<= 1 } } function o() { for (var r = 0; 256 > r; r++)_[r] = 19595 * r, _[r + 256 >> 0] = 38470 * r, _[r + 512 >> 0] = 7471 * r + 32768, _[r + 768 >> 0] = -11059 * r, _[r + 1024 >> 0] = -21709 * r, _[r + 1280 >> 0] = 32768 * r + 8421375, _[r + 1536 >> 0] = -27439 * r, _[r + 1792 >> 0] = -5329 * r } function i(r) { for (var a = r[0], e = r[1] - 1; e >= 0;)a & 1 << e && (H |= 1 << O), e--, O--, 0 > O && (255 == H ? (c(255), c(0)) : c(H), O = 7, H = 0) } function c(r) { P.push(B[r]) } function f(r) { c(r >> 8 & 255), c(255 & r) } function s(r, a) { var e, t, n, o, i, c, f, s, v, h = 0; const u = 8, d = 64; for (v = 0; u > v; ++v) { e = r[h], t = r[h + 1], n = r[h + 2], o = r[h + 3], i = r[h + 4], c = r[h + 5], f = r[h + 6], s = r[h + 7]; var g = e + s, l = e - s, w = t + f, m = t - f, b = n + c, y = n - c, L = o + i, I = o - i, A = g + L, R = g - L, U = w + b, k = w - b; r[h] = A + U, r[h + 4] = A - U; var p = .707106781 * (k + R); r[h + 2] = R + p, r[h + 6] = R - p, A = I + y, U = y + m, k = m + l; var M = .382683433 * (A - k), j = .5411961 * A + M, E = 1.306562965 * k + M, C = .707106781 * U, x = l + C, P = l - C; r[h + 5] = P + j, r[h + 3] = P - j, r[h + 1] = x + E, r[h + 7] = x - E, h += 8 } for (h = 0, v = 0; u > v; ++v) { e = r[h], t = r[h + 8], n = r[h + 16], o = r[h + 24], i = r[h + 32], c = r[h + 40], f = r[h + 48], s = r[h + 56]; var H = e + s, O = e - s, T = t + f, W = t - f, N = n + c, B = n - c, _ = o + i, q = o - i, z = H + _, G = H - _, J = T + N, Q = T - N; r[h] = z + J, r[h + 32] = z - J; var S = .707106781 * (Q + G); r[h + 16] = G + S, r[h + 48] = G - S, z = q + B, J = B + W, Q = W + O; var F = .382683433 * (z - Q), K = .5411961 * z + F, V = 1.306562965 * Q + F, X = .707106781 * J, Y = O + X, Z = O - X; r[h + 40] = Z + K, r[h + 24] = Z - K, r[h + 8] = Y + V, r[h + 56] = Y - V, h++ } var $; for (v = 0; d > v; ++v)$ = r[v] * a[v], D[v] = $ > 0 ? $ + .5 | 0 : $ - .5 | 0; return D } function v() { f(65504), f(16), c(74), c(70), c(73), c(70), c(0), c(1), c(1), c(0), f(1), f(1), c(0), c(0) } function h(r, a) { f(65472), f(17), c(8), f(a), f(r), c(3), c(1), c(17), c(0), c(2), c(17), c(1), c(3), c(17), c(1) } function u() { f(65499), f(132), c(0); for (var r = 0; 64 > r; r++)c(k[r]); c(1); for (var a = 0; 64 > a; a++)c(p[a]) } function d() { f(65476), f(418), c(0); for (var r = 0; 16 > r; r++)c(z[r + 1]); for (var a = 0; 11 >= a; a++)c(G[a]); c(16); for (var e = 0; 16 > e; e++)c(J[e + 1]); for (var t = 0; 161 >= t; t++)c(Q[t]); c(1); for (var n = 0; 16 > n; n++)c(S[n + 1]); for (var o = 0; 11 >= o; o++)c(F[o]); c(17); for (var i = 0; 16 > i; i++)c(K[i + 1]); for (var s = 0; 161 >= s; s++)c(V[s]) } function g() { f(65498), f(12), c(3), c(1), c(0), c(2), c(17), c(3), c(17), c(0), c(63), c(0) } function l(r, a, e, t, n) { var o, c = n[0], f = n[240]; const v = 16, h = 63, u = 64; for (var d = s(r, a), g = 0; u > g; ++g)x[q[g]] = d[g]; var l = x[0] - e; e = x[0], 0 == l ? i(t[0]) : (o = 32767 + l, i(t[C[o]]), i(E[o])); for (var w = 63; w > 0 && 0 == x[w]; w--); if (0 == w)return i(c), e; for (var m, b = 1; w >= b;) { for (var y = b; 0 == x[b] && w >= b; ++b); var L = b - y; if (L >= v) { m = L >> 4; for (var I = 1; m >= I; ++I)i(f); L = 15 & L } o = 32767 + x[b], i(n[(L << 4) + C[o]]), i(E[o]), b++ } return w != h && i(c), e } function w() { for (var r = String.fromCharCode, a = 0; 256 > a; a++)B[a] = r(a) } function m(r) { if (0 >= r && (r = 1), r > 100 && (r = 100), R != r) { var e = 0; e = Math.floor(50 > r ? 5e3 / r : 200 - 2 * r), a(e), R = r, console.log("Quality set to: " + r + "%") } } function b() { var a = (new Date).getTime(); r || (r = 50), w(), t(), n(), o(), m(r); var e = (new Date).getTime() - a; console.log("Initialization " + e + "ms") } var y, L, I, A, R, U = (Math.round, Math.floor), k = new Array(64), p = new Array(64), M = new Array(64), j = new Array(64), E = new Array(65535), C = new Array(65535), D = new Array(64), x = new Array(64), P = [], H = 0, O = 7, T = new Array(64), W = new Array(64), N = new Array(64), B = new Array(256), _ = new Array(2048), q = [0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63], z = [0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], G = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], J = [0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125], Q = [1, 2, 3, 0, 4, 17, 5, 18, 33, 49, 65, 6, 19, 81, 97, 7, 34, 113, 20, 50, 129, 145, 161, 8, 35, 66, 177, 193, 21, 82, 209, 240, 36, 51, 98, 114, 130, 9, 10, 22, 23, 24, 25, 26, 37, 38, 39, 40, 41, 42, 52, 53, 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, 131, 132, 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 179, 180, 181, 182, 183, 184, 185, 186, 194, 195, 196, 197, 198, 199, 200, 201, 202, 210, 211, 212, 213, 214, 215, 216, 217, 218, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250], S = [0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], F = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], K = [0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119], V = [0, 1, 2, 3, 17, 4, 5, 33, 49, 6, 18, 65, 81, 7, 97, 113, 19, 34, 50, 129, 8, 20, 66, 145, 161, 177, 193, 9, 35, 51, 82, 240, 21, 98, 114, 209, 10, 22, 36, 52, 225, 37, 241, 23, 24, 25, 26, 38, 39, 40, 41, 42, 53, 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, 130, 131, 132, 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 179, 180, 181, 182, 183, 184, 185, 186, 194, 195, 196, 197, 198, 199, 200, 201, 202, 210, 211, 212, 213, 214, 215, 216, 217, 218, 226, 227, 228, 229, 230, 231, 232, 233, 234, 242, 243, 244, 245, 246, 247, 248, 249, 250]; this.encode = function (r, a, e) { var t = (new Date).getTime(); a && m(a), P = new Array, H = 0, O = 7, f(65496), v(), u(), h(r.width, r.height), d(), g(); var n = 0, o = 0, c = 0; H = 0, O = 7, this.encode.displayName = "_encode_"; for (var s, w, b, R, U, k, p, E, C, D = r.data, x = r.width, B = r.height, q = 4 * x, z = 0; B > z;) { for (s = 0; q > s;) { for (U = q * z + s, k = U, p = -1, E = 0, C = 0; 64 > C; C++)E = C >> 3, p = 4 * (7 & C), k = U + E * q + p, z + E >= B && (k -= q * (z + 1 + E - B)), s + p >= q && (k -= s + p - q + 4), w = D[k++], b = D[k++], R = D[k++], T[C] = (_[w] + _[b + 256 >> 0] + _[R + 512 >> 0] >> 16) - 128, W[C] = (_[w + 768 >> 0] + _[b + 1024 >> 0] + _[R + 1280 >> 0] >> 16) - 128, N[C] = (_[w + 1280 >> 0] + _[b + 1536 >> 0] + _[R + 1792 >> 0] >> 16) - 128; n = l(T, M, n, y, I), o = l(W, j, o, L, A), c = l(N, j, c, L, A), s += 32 } z += 8 } if (O >= 0) { var G = []; G[1] = O + 1, G[0] = (1 << O + 1) - 1, i(G) } if (f(65497), e) { for (var J = P.length, Q = new Uint8Array(J), S = 0; J > S; S++)Q[S] = P[S].charCodeAt(); P = []; var F = (new Date).getTime() - t; return console.log("Encoding time: " + F + "ms"), Q } var K = "data:image/jpeg;base64," + btoa(P.join("")); P = []; var F = (new Date).getTime() - t; return console.log("Encoding time: " + F + "ms"), K }, b() } !function () { function r(r) { var a = r.naturalWidth, e = r.naturalHeight; if (a * e > 1048576) { var t = document.createElement("canvas"); t.width = t.height = 1; var n = t.getContext("2d"); return n.drawImage(r, -a + 1, 0), 0 === n.getImageData(0, 0, 1, 1).data[3] } return !1 } function a(r, a, e) { var t = document.createElement("canvas"); t.width = 1, t.height = e; var n = t.getContext("2d"); n.drawImage(r, 0, 0); for (var o = n.getImageData(0, 0, 1, e).data, i = 0, c = e, f = e; f > i;) { var s = o[4 * (f - 1) + 3]; 0 === s ? c = f : i = f, f = c + i >> 1 } var v = f / e; return 0 === v ? 1 : v } function e(r, a, e) { var n = document.createElement("canvas"); return t(r, n, a, e), n.toDataURL("image/jpeg", a.quality || .8) } function t(e, t, o, i) { var c = e.naturalWidth, f = e.naturalHeight; if (c + f) { var s = o.width, v = o.height, h = t.getContext("2d"); h.save(), n(t, h, s, v, o.orientation); var u = r(e); u && (c /= 2, f /= 2); var d = 1024, g = document.createElement("canvas"); g.width = g.height = d; for (var l = g.getContext("2d"), w = i ? a(e, c, f) : 1, m = Math.ceil(d * s / c), b = Math.ceil(d * v / f / w), y = 0, L = 0; f > y;) { for (var I = 0, A = 0; c > I;)l.clearRect(0, 0, d, d), l.drawImage(e, -I, -y), h.drawImage(g, 0, 0, d, d, A, L, m, b), I += d, A += m; y += d, L += b } h.restore(), g = l = null } } function n(r, a, e, t, n) { switch (n) { case 5: case 6: case 7: case 8: r.width = t, r.height = e; break; default: r.width = e, r.height = t } switch (n) { case 2: a.translate(e, 0), a.scale(-1, 1); break; case 3: a.translate(e, t), a.rotate(Math.PI); break; case 4: a.translate(0, t), a.scale(1, -1); break; case 5: a.rotate(.5 * Math.PI), a.scale(1, -1); break; case 6: a.rotate(.5 * Math.PI), a.translate(0, -t); break; case 7: a.rotate(.5 * Math.PI), a.translate(e, -t), a.scale(-1, 1); break; case 8: a.rotate(-.5 * Math.PI), a.translate(-e, 0) } } function o(r) { if (window.Blob && r instanceof Blob) { if (!i)throw Error("No createObjectURL function found to create blob url"); var a = new Image; a.src = i.createObjectURL(r), this.blob = r, r = a } if (!r.naturalWidth && !r.naturalHeight) { var e = this; r.onload = r.onerror = function () { var r = e.imageLoadListeners; if (r) { e.imageLoadListeners = null; for (var a = 0, t = r.length; t > a; a++)r[a]() } }, this.imageLoadListeners = [] } this.srcImage = r } var i = window.URL && window.URL.createObjectURL ? window.URL : window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null; o.prototype.render = function (r, a, n) { if (this.imageLoadListeners) { var o = this; return void this.imageLoadListeners.push(function () { o.render(r, a, n) }) } a = a || {}; var c = this.srcImage.naturalWidth, f = this.srcImage.naturalHeight, s = a.width, v = a.height, h = a.maxWidth, u = a.maxHeight, d = !this.blob || "image/jpeg" === this.blob.type; s && !v ? v = f * s / c << 0 : v && !s ? s = c * v / f << 0 : (s = c, v = f), h && s > h && (s = h, v = f * s / c << 0), u && v > u && (v = u, s = c * v / f << 0); var g = {width: s, height: v}; for (var l in a)g[l] = a[l]; var w = r.tagName.toLowerCase(); "img" === w ? r.src = e(this.srcImage, g, d) : "canvas" === w && t(this.srcImage, r, g, d), "function" == typeof this.onrender && this.onrender(r), n && n(), this.blob && (this.blob = null, i.revokeObjectURL(this.srcImage.src)) }, "function" == typeof define && define.amd ? define([], function () { return o }) : this.MegaPixImage = o }(); !function () { function e(e, t) { this.file = e, this.defaults = {quality: .7, done: null, fail: null, before: null, always: null}; for (var a in t)this.defaults[a] = t[a]; this.defaults.quality > 1 && (this.defaults.quality = 1), this.results = { origin: null, base64: null, base64Len: null }, this.init() } window.URL = window.URL || window.webkitURL; var t = detect.parse(navigator.userAgent); e.prototype = { constructor: e, init: function () { var e = this; if ("undefined" == typeof window.URL || "function" != typeof document.createElement("canvas").getContext) { var t = new Error("不支持此设备"); return "function" == typeof e.defaults.fail && e.defaults.fail(t), void("function" == typeof e.defaults.always && e.defaults.always()) } e.create(e.file) }, create: function (e) { var a = this, i = new Image, n = a.results, s = "string" == typeof e ? e : URL.createObjectURL(e); i.crossOrigin = "*", i.onerror = function () { var e = new Error("图片加载失败"); "function" == typeof a.defaults.fail && a.defaults.fail(e), "function" == typeof a.defaults.always && a.defaults.always() }, i.onload = function () { function l(e) { canvas = null, i = null, URL.revokeObjectURL(s), e.base64Len = e.base64.length, "function" == typeof a.defaults.done && a.defaults.done(e), "function" == typeof a.defaults.always && a.defaults.always() } EXIF.getData(i, function () { var s, r = EXIF.getTag(this, "Orientation"), o = a.resize(this, r), h = document.createElement("canvas"); if (h.width = o.w, h.height = o.h, s = h.getContext("2d"), s.fillStyle = "#fff", s.fillRect(0, 0, o.w, o.h), n.origin = e, "iOS" === t.os.family && parseInt(t.os.version) < 8) { var f = new MegaPixImage(i); "5678".indexOf(r) > -1 ? f.render(h, { width: h.height, height: h.width, orientation: r }) : f.render(h, { width: h.width, height: h.height, orientation: r }), n.base64 = h.toDataURL("image/jpeg", a.defaults.quality), l(n) } else { switch (r) { case 3: s.rotate(180 * Math.PI / 180), s.drawImage(i, -o.w, -o.h, o.w, o.h); break; case 6: s.rotate(90 * Math.PI / 180), s.drawImage(i, 0, -o.w, o.h, o.w); break; case 8: s.rotate(270 * Math.PI / 180), s.drawImage(i, -o.h, 0, o.h, o.w); break; case 2: s.translate(o.w, 0), s.scale(-1, 1), s.drawImage(i, 0, 0, o.w, o.h); break; case 4: s.translate(o.w, 0), s.scale(-1, 1), s.rotate(180 * Math.PI / 180), s.drawImage(i, -o.w, -o.h, o.w, o.h); break; case 5: s.translate(o.w, 0), s.scale(-1, 1), s.rotate(90 * Math.PI / 180), s.drawImage(i, 0, -o.w, o.h, o.w); break; case 7: s.translate(o.w, 0), s.scale(-1, 1), s.rotate(270 * Math.PI / 180), s.drawImage(i, -o.h, 0, o.h, o.w); break; default: s.drawImage(i, 0, 0, o.w, o.h) } if ("Android" === t.os.family && t.os.version.slice(0, 3) < 4.5) { var w = new JPEGEncoder; n.base64 = w.encode(s.getImageData(0, 0, h.width, h.height), 100 * a.defaults.quality) } else n.base64 = h.toDataURL("image/jpeg", a.defaults.quality); l(n) } }) }, "function" == typeof this.defaults.before && this.defaults.before(), i.src = s }, resize: function (e, t) { var a = this.defaults.width, i = this.defaults.height, n = {w: e.width, h: e.height}; "5678".indexOf(t) > -1 && (n.w = e.height, n.h = e.width); var s = n.w / n.h; return a && i ? s >= a / i ? n.w > a && (n.w = a, n.h = Math.ceil(a / s)) : n.h > i && (n.h = i, n.w = Math.ceil(i * s)) : a ? (n.w = a, n.h = Math.ceil(a / s)) : i && (n.w = Math.ceil(i * s), n.h = i), (n.w >= 3264 || n.h >= 2448) && (n.w *= .8, n.h *= .8), n } }, window.lrz = function (t, a) { return new e(t, a) } }();
注:当上传的图片被分割时,手机游览器设置一下即可,换成手机版或者电脑版。
其中一些上传到某个地点,云或本地的,我使用的是OpenSNS的一些他们有的的内部函数,有不懂的,可以下个OpenSNS或者留言给我,我可以把所有代码发出来或者详解下。