├── .gitignore ├── README.md ├── dist ├── css │ └── cropper.css └── js │ ├── lib │ └── require.js │ └── main.js ├── index.js ├── lib ├── app │ ├── compress.js │ └── watermark.js ├── base64_blob.js ├── exif.js ├── get_length.js ├── is_array.js └── rotate_draw.js ├── package.json └── src ├── build.js ├── css ├── cropper.css └── reset.css ├── html ├── compress.html ├── cropper.html ├── gifmaker.html └── watermark.html ├── image ├── wjz │ ├── 10.jpg │ ├── 11.jpg │ ├── 12.jpg │ ├── 13.jpg │ ├── 14.jpg │ ├── 15.jpg │ ├── 16.jpg │ ├── 17.jpg │ ├── 18.jpg │ ├── 19.jpg │ ├── 20.jpg │ ├── 21.jpg │ ├── 22.jpg │ ├── 23.jpg │ ├── 24.jpg │ ├── 25.jpg │ ├── 26.jpg │ ├── 27.jpg │ ├── 28.jpg │ ├── 29.jpg │ ├── 30.jpg │ ├── 31.jpg │ ├── 32.jpg │ ├── 33.jpg │ ├── 34.jpg │ ├── 35.jpg │ ├── 36.jpg │ ├── 37.jpg │ ├── 38.jpg │ ├── 39.jpg │ ├── 40.jpg │ ├── 41.jpg │ ├── 42.jpg │ ├── 43.jpg │ ├── 44.jpg │ ├── 45.jpg │ ├── 46.jpg │ ├── 47.jpg │ ├── 48.jpg │ ├── 49.jpg │ ├── 50.jpg │ ├── 51.jpg │ ├── 52.jpg │ ├── 53.jpg │ ├── 54.jpg │ ├── 55.jpg │ ├── 56.jpg │ ├── 57.jpg │ ├── 58.jpg │ ├── 59.jpg │ ├── 60.jpg │ ├── 61.jpg │ ├── 62.jpg │ ├── 63.jpg │ ├── 64.jpg │ ├── 65.jpg │ ├── 66.jpg │ ├── 67.jpg │ ├── 68.jpg │ ├── 69.jpg │ ├── 70.jpg │ ├── 71.jpg │ ├── 72.jpg │ ├── 73.jpg │ ├── 74.jpg │ ├── 75.jpg │ ├── 76.jpg │ ├── 77.jpg │ ├── 78.jpg │ ├── 79.jpg │ ├── 80.jpg │ ├── 81.jpg │ ├── 82.jpg │ ├── 83.jpg │ ├── 84.jpg │ ├── 85.jpg │ └── 9.jpg └── wjz_min │ ├── 10.jpg │ ├── 11.jpg │ ├── 12.jpg │ ├── 13.jpg │ ├── 14.jpg │ ├── 15.jpg │ ├── 16.jpg │ ├── 17.jpg │ ├── 18.jpg │ ├── 19.jpg │ ├── 20.jpg │ ├── 21.jpg │ ├── 22.jpg │ ├── 23.jpg │ ├── 24.jpg │ ├── 25.jpg │ ├── 26.jpg │ ├── 27.jpg │ ├── 28.jpg │ ├── 29.jpg │ ├── 30.jpg │ ├── 31.jpg │ ├── 32.jpg │ ├── 33.jpg │ ├── 34.jpg │ ├── 35.jpg │ ├── 36.jpg │ ├── 37.jpg │ ├── 38.jpg │ ├── 39.jpg │ ├── 40.jpg │ ├── 41.jpg │ ├── 42.jpg │ ├── 43.jpg │ ├── 44.jpg │ ├── 45.jpg │ ├── 46.jpg │ ├── 47.jpg │ ├── 48.jpg │ ├── 49.jpg │ ├── 50.jpg │ ├── 51.jpg │ ├── 52.jpg │ ├── 53.jpg │ ├── 54.jpg │ ├── 55.jpg │ ├── 56.jpg │ ├── 57.jpg │ ├── 58.jpg │ ├── 59.jpg │ ├── 60.jpg │ ├── 61.jpg │ ├── 62.jpg │ ├── 63.jpg │ ├── 64.jpg │ ├── 65.jpg │ ├── 66.jpg │ ├── 67.jpg │ ├── 68.jpg │ ├── 69.jpg │ ├── 70.jpg │ ├── 71.jpg │ ├── 72.jpg │ ├── 73.jpg │ ├── 74.jpg │ ├── 75.jpg │ ├── 76.jpg │ ├── 77.jpg │ ├── 78.jpg │ ├── 79.jpg │ ├── 80.jpg │ ├── 81.jpg │ ├── 82.jpg │ ├── 83.jpg │ ├── 84.jpg │ ├── 85.jpg │ └── 9.jpg ├── index.html └── js ├── app ├── base64_blob.js ├── compress.js ├── cropper.js ├── get_length.js ├── is_array.js ├── rotate_draw.js └── watermark.js ├── lib ├── cropper.js ├── exif.js ├── gif.js ├── gif.worker.js ├── gif.worker.js.map └── require.js └── main.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #### Demo预览 2 | 3 | [http://palxp.com/ccimg/](http://www.palxp.com/ccimg/) 4 | 5 | #### 安装说明 6 | 7 | 下载本项目,将`dist`文件下的 js 引入页面 8 | 9 | `` 10 | 11 | 使用到图片裁剪工具时需引入 css 12 | 13 | `` 14 | 15 | #### npm引入方式 16 | npm install ccimg 17 | web项目中使用,目前只支持压缩和水印功能: 18 | 19 | var ccimg = require('ccimg') 20 | ccimg.compress // 使用等于下面的 $compress 21 | ccimg.watermark // 使用等于下面的 $watermark 22 | 23 | #### 使用说明 24 | 25 | ## 1. 图片裁剪 26 | 27 | 传入参数: 28 | > src: 图片地址 29 | > 30 | > aspectRatio: 裁剪框比例,不传为自由变换 eg: 16/9 4/3 2/3 1/1 31 | 32 | 示例: 33 | 34 | $cropper(src).open({ 35 | aspectRatio: 1, 36 | ok: function (base64) { 37 | // 确认回调函数,返回裁剪后图片。 38 | }, 39 | toBlob: function (blob) { 40 | // 确认回调函数,返回裁剪后图片,转换成用于传输到后台的格式,使用formData接收。 41 | // var formData = new FormData(); 42 | // formData.append('croppedImage', blob); 43 | } 44 | }) 45 | 46 | ## 2. 图片压缩 47 | 48 | 传入参数: 49 | > src:(string/array) 单个图片地址,或者多个图片地址的数组 50 | > 51 | > width / height:(number) 自定义压缩后宽高,可不传 52 | > 53 | > quality:(1~99) 压缩质量 数值越大质量越高 54 | > 55 | > original: (boolean) 传true压缩后分辨率接近或与原始分辨率一致 56 | 57 | $compress({ 58 | src: document.getElementById('xxx').src, 59 | width: 100, 60 | height: 100, 61 | quality: 40, 62 | ok: function (base64) { 63 | // 返回的压缩图片,如果传递数组则返回数组: 64 | // base64.forEach(function (item) {}) 65 | }, 66 | toBlob: function (blob) { 67 | // 返回转换为blob的格式 68 | } 69 | }) 70 | 71 | ## 3. 图片底部加水印 72 | 73 | 传入参数: 74 | > src: 图片地址 75 | > 76 | > text: 水印文字 77 | > 78 | > fontSize: 字体大小,不传或者为0则自适应 79 | 80 | var src = document.getElementById('xxx').src 81 | $watermark(src).add({ 82 | text: '文字', 83 | fontSize: 18, 84 | ok: function (base64) { 85 | // 完成后回调函数 86 | } 87 | }) 88 | -------------------------------------------------------------------------------- /dist/css/cropper.css: -------------------------------------------------------------------------------- 1 | /*! * Cropper.js v1.3.5 * https://github.com/fengyuanchen/cropperjs * * Copyright (c) 2015-2018 Chen Fengyuan * Released under the MIT license * * Date:2018-04-15T06:19:56.029Z */ .cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.cropper-container img{display:block;height:100%;image-orientation:0deg;max-height:none !important;max-width:none !important;min-height:0 !important;min-width:0 !important;width:100%;}.cropper-wrap-box,.cropper-canvas,.cropper-drag-box,.cropper-crop-box,.cropper-modal{bottom:0;left:0;position:absolute;right:0;top:0;}.cropper-wrap-box,.cropper-canvas{overflow:hidden;}.cropper-drag-box{background-color:#fff;opacity:0;}.cropper-modal{background-color:#000;opacity:.5;}.cropper-view-box{display:block;height:100%;outline-color:rgba(51,153,255,0.75);outline:1px solid #39f;overflow:hidden;width:100%;}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute;}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%;}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%;}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0;}.cropper-center:before,.cropper-center:after{background-color:#eee;content:' ';display:block;position:absolute;}.cropper-center:before{height:1px;left:-3px;top:0;width:7px;}.cropper-center:after{height:7px;left:0;top:-3px;width:1px;}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%;}.cropper-face{background-color:#fff;left:0;top:0;}.cropper-line{background-color:#39f;}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px;}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px;}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px;}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0;}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px;}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%;}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px;}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%;}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px;}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px;}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px;}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px;}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px;}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px;}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px;}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px;}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:' ';display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%;}.cropper-invisible{opacity:0;}.cropper-bg{background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');}.cropper-hide{display:block;height:0;position:absolute;width:0;}.cropper-hidden{display:none !important;}.cropper-move{cursor:move;}.cropper-crop{cursor:crosshair;}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed;}#ccw_cropprt_out{color:beige;display:table;width:100%;text-align:center;background:black;display:none;}.ccw_cropper_container{width:100%;display:table-cell;vertical-align:middle;text-align:center;}.ccw_cropper_image{width:100%;}.ccw_cropper_confirm,.ccw_cropper_cancel{color:aliceblue;position:fixed;border:1px solid white;border-radius:5px;bottom:3%;padding:6px 10px;}.ccw_cropper_confirm{left:5%;}.ccw_cropper_cancel{right:5%;}.cc_disScroll{position:fixed;width:100%;} -------------------------------------------------------------------------------- /dist/js/lib/require.js: -------------------------------------------------------------------------------- 1 | /** vim: et:ts=4:sw=4:sts=4 2 | * @license RequireJS 2.3.5 Copyright jQuery Foundation and other contributors. 3 | * Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE 4 | */ 5 | 6 | var requirejs,require,define;!function(global,setTimeout){function commentReplace(e,t){return t||""}function isFunction(e){return"[object Function]"===ostring.call(e)}function isArray(e){return"[object Array]"===ostring.call(e)}function each(e,t){if(e){var i;for(i=0;i-1&&(!e[i]||!t(e[i],i,e));i-=1);}}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,r){return t&&eachProp(t,function(t,n){!i&&hasProp(e,n)||(!r||"object"!=typeof t||!t||isArray(t)||isFunction(t)||t instanceof RegExp?e[n]=t:(e[n]||(e[n]={}),mixin(e[n],t,i,r)))}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,i,r){var n=new Error(t+"\nhttp://requirejs.org/docs/errors.html#"+e);return n.requireType=e,n.requireModules=r,i&&(n.originalError=i),n}function newContext(e){function t(e){var t,i;for(t=0;t0&&(e.splice(t-1,2),t-=2)}}function i(e,i,r){var n,o,a,s,u,c,d,p,f,l,h,m=i&&i.split("/"),g=y.map,v=g&&g["*"];if(e&&(e=e.split("/"),c=e.length-1,y.nodeIdCompat&&jsSuffixRegExp.test(e[c])&&(e[c]=e[c].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&m&&(h=m.slice(0,m.length-1),e=h.concat(e)),t(e),e=e.join("/")),r&&g&&(m||v)){o=e.split("/");e:for(a=o.length;a>0;a-=1){if(u=o.slice(0,a).join("/"),m)for(s=m.length;s>0;s-=1)if((n=getOwn(g,m.slice(0,s).join("/")))&&(n=getOwn(n,u))){d=n,p=a;break e}!f&&v&&getOwn(v,u)&&(f=getOwn(v,u),l=a)}!d&&f&&(d=f,p=l),d&&(o.splice(0,p,d),e=o.join("/"))}return getOwn(y.pkgs,e)||e}function r(e){isBrowser&&each(scripts(),function(t){if(t.getAttribute("data-requiremodule")===e&&t.getAttribute("data-requirecontext")===q.contextName)return t.parentNode.removeChild(t),!0})}function n(e){var t=getOwn(y.paths,e);if(t&&isArray(t)&&t.length>1)return t.shift(),q.require.undef(e),q.makeRequire(null,{skipMap:!0})([e]),!0}function o(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function a(e,t,r,n){var a,s,u,c,d=null,p=t?t.name:null,f=e,l=!0,h="";return e||(l=!1,e="_@r"+(T+=1)),c=o(e),d=c[0],e=c[1],d&&(d=i(d,p,n),s=getOwn(j,d)),e&&(d?h=r?e:s&&s.normalize?s.normalize(e,function(e){return i(e,p,n)}):-1===e.indexOf("!")?i(e,p,n):e:(h=i(e,p,n),c=o(h),d=c[0],h=c[1],r=!0,a=q.nameToUrl(h))),u=!d||s||r?"":"_unnormalized"+(A+=1),{prefix:d,name:h,parentMap:t,unnormalized:!!u,url:a,originalName:f,isDefine:l,id:(d?d+"!"+h:h)+u}}function s(e){var t=e.id,i=getOwn(S,t);return i||(i=S[t]=new q.Module(e)),i}function u(e,t,i){var r=e.id,n=getOwn(S,r);!hasProp(j,r)||n&&!n.defineEmitComplete?(n=s(e),n.error&&"error"===t?i(n.error):n.on(t,i)):"defined"===t&&i(j[r])}function c(e,t){var i=e.requireModules,r=!1;t?t(e):(each(i,function(t){var i=getOwn(S,t);i&&(i.error=e,i.events.error&&(r=!0,i.emit("error",e)))}),r||req.onError(e))}function d(){globalDefQueue.length&&(each(globalDefQueue,function(e){var t=e[0];"string"==typeof t&&(q.defQueueMap[t]=!0),O.push(e)}),globalDefQueue=[])}function p(e){delete S[e],delete k[e]}function f(e,t,i){var r=e.map.id;e.error?e.emit("error",e.error):(t[r]=!0,each(e.depMaps,function(r,n){var o=r.id,a=getOwn(S,o);!a||e.depMatched[n]||i[o]||(getOwn(t,o)?(e.defineDep(n,j[o]),e.check()):f(a,t,i))}),i[r]=!0)}function l(){var e,t,i=1e3*y.waitSeconds,o=i&&q.startTime+i<(new Date).getTime(),a=[],s=[],u=!1,d=!0;if(!x){if(x=!0,eachProp(k,function(e){var i=e.map,c=i.id;if(e.enabled&&(i.isDefine||s.push(e),!e.error))if(!e.inited&&o)n(c)?(t=!0,u=!0):(a.push(c),r(c));else if(!e.inited&&e.fetched&&i.isDefine&&(u=!0,!i.prefix))return d=!1}),o&&a.length)return e=makeError("timeout","Load timeout for modules: "+a,null,a),e.contextName=q.contextName,c(e);d&&each(s,function(e){f(e,{},{})}),o&&!t||!u||!isBrowser&&!isWebWorker||w||(w=setTimeout(function(){w=0,l()},50)),x=!1}}function h(e){hasProp(j,e[0])||s(a(e[0],null,!0)).init(e[1],e[2])}function m(e,t,i,r){e.detachEvent&&!isOpera?r&&e.detachEvent(r,t):e.removeEventListener(i,t,!1)}function g(e){var t=e.currentTarget||e.srcElement;return m(t,q.onScriptLoad,"load","onreadystatechange"),m(t,q.onScriptError,"error"),{node:t,id:t&&t.getAttribute("data-requiremodule")}}function v(){var e;for(d();O.length;){if(e=O.shift(),null===e[0])return c(makeError("mismatch","Mismatched anonymous define() module: "+e[e.length-1]));h(e)}q.defQueueMap={}}var x,b,q,E,w,y={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},S={},k={},M={},O=[],j={},P={},R={},T=1,A=1;return E={require:function(e){return e.require?e.require:e.require=q.makeRequire(e.map)},exports:function(e){if(e.usingExports=!0,e.map.isDefine)return e.exports?j[e.map.id]=e.exports:e.exports=j[e.map.id]={}},module:function(e){return e.module?e.module:e.module={id:e.map.id,uri:e.map.url,config:function(){return getOwn(y.config,e.map.id)||{}},exports:e.exports||(e.exports={})}}},b=function(e){this.events=getOwn(M,e.id)||{},this.map=e,this.shim=getOwn(y.shim,e.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0},b.prototype={init:function(e,t,i,r){r=r||{},this.inited||(this.factory=t,i?this.on("error",i):this.events.error&&(i=bind(this,function(e){this.emit("error",e)})),this.depMaps=e&&e.slice(0),this.errback=i,this.inited=!0,this.ignore=r.ignore,r.enabled||this.enabled?this.enable():this.check())},defineDep:function(e,t){this.depMatched[e]||(this.depMatched[e]=!0,this.depCount-=1,this.depExports[e]=t)},fetch:function(){if(!this.fetched){this.fetched=!0,q.startTime=(new Date).getTime();var e=this.map;if(!this.shim)return e.prefix?this.callPlugin():this.load();q.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return e.prefix?this.callPlugin():this.load()}))}},load:function(){var e=this.map.url;P[e]||(P[e]=!0,q.load(this.map.id,e))},check:function(){if(this.enabled&&!this.enabling){var e,t,i=this.map.id,r=this.depExports,n=this.exports,o=this.factory;if(this.inited){if(this.error)this.emit("error",this.error);else if(!this.defining){if(this.defining=!0,this.depCount<1&&!this.defined){if(isFunction(o)){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)try{n=q.execCb(i,o,r,n)}catch(t){e=t}else n=q.execCb(i,o,r,n);if(this.map.isDefine&&void 0===n&&(t=this.module,t?n=t.exports:this.usingExports&&(n=this.exports)),e)return e.requireMap=this.map,e.requireModules=this.map.isDefine?[this.map.id]:null,e.requireType=this.map.isDefine?"define":"require",c(this.error=e)}else n=o;if(this.exports=n,this.map.isDefine&&!this.ignore&&(j[i]=n,req.onResourceLoad)){var a=[];each(this.depMaps,function(e){a.push(e.normalizedMap||e)}),req.onResourceLoad(q,this.map,a)}p(i),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else hasProp(q.defQueueMap,i)||this.fetch()}},callPlugin:function(){var e=this.map,t=e.id,r=a(e.prefix);this.depMaps.push(r),u(r,"defined",bind(this,function(r){var n,o,d,f=getOwn(R,this.map.id),l=this.map.name,h=this.map.parentMap?this.map.parentMap.name:null,m=q.makeRequire(e.parentMap,{enableBuildCallback:!0});return this.map.unnormalized?(r.normalize&&(l=r.normalize(l,function(e){return i(e,h,!0)})||""),o=a(e.prefix+"!"+l,this.map.parentMap,!0),u(o,"defined",bind(this,function(e){this.map.normalizedMap=o,this.init([],function(){return e},null,{enabled:!0,ignore:!0})})),void((d=getOwn(S,o.id))&&(this.depMaps.push(o),this.events.error&&d.on("error",bind(this,function(e){this.emit("error",e)})),d.enable()))):f?(this.map.url=q.nameToUrl(f),void this.load()):(n=bind(this,function(e){this.init([],function(){return e},null,{enabled:!0})}),n.error=bind(this,function(e){this.inited=!0,this.error=e,e.requireModules=[t],eachProp(S,function(e){0===e.map.id.indexOf(t+"_unnormalized")&&p(e.map.id)}),c(e)}),n.fromText=bind(this,function(i,r){var o=e.name,u=a(o),d=useInteractive;r&&(i=r),d&&(useInteractive=!1),s(u),hasProp(y.config,t)&&(y.config[o]=y.config[t]);try{req.exec(i)}catch(e){return c(makeError("fromtexteval","fromText eval for "+t+" failed: "+e,e,[t]))}d&&(useInteractive=!0),this.depMaps.push(u),q.completeLoad(o),m([o],n)}),void r.load(e.name,m,n,y))})),q.enable(r,this),this.pluginMaps[r.id]=r},enable:function(){k[this.map.id]=this,this.enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(e,t){var i,r,n;if("string"==typeof e){if(e=a(e,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[t]=e,n=getOwn(E,e.id))return void(this.depExports[t]=n(this));this.depCount+=1,u(e,"defined",bind(this,function(e){this.undefed||(this.defineDep(t,e),this.check())})),this.errback?u(e,"error",bind(this,this.errback)):this.events.error&&u(e,"error",bind(this,function(e){this.emit("error",e)}))}i=e.id,r=S[i],hasProp(E,i)||!r||r.enabled||q.enable(e,this)})),eachProp(this.pluginMaps,bind(this,function(e){var t=getOwn(S,e.id);t&&!t.enabled&&q.enable(e,this)})),this.enabling=!1,this.check()},on:function(e,t){var i=this.events[e];i||(i=this.events[e]=[]),i.push(t)},emit:function(e,t){each(this.events[e],function(e){e(t)}),"error"===e&&delete this.events[e]}},q={config:y,contextName:e,registry:S,defined:j,urlFetched:P,defQueue:O,defQueueMap:{},Module:b,makeModuleMap:a,nextTick:req.nextTick,onError:c,configure:function(e){if(e.baseUrl&&"/"!==e.baseUrl.charAt(e.baseUrl.length-1)&&(e.baseUrl+="/"),"string"==typeof e.urlArgs){var t=e.urlArgs;e.urlArgs=function(e,i){return(-1===i.indexOf("?")?"?":"&")+t}}var i=y.shim,r={paths:!0,bundles:!0,config:!0,map:!0};eachProp(e,function(e,t){r[t]?(y[t]||(y[t]={}),mixin(y[t],e,!0,!0)):y[t]=e}),e.bundles&&eachProp(e.bundles,function(e,t){each(e,function(e){e!==t&&(R[e]=t)})}),e.shim&&(eachProp(e.shim,function(e,t){isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=q.makeShimExports(e)),i[t]=e}),y.shim=i),e.packages&&each(e.packages,function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(y.paths[i]=e.location),y.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),eachProp(S,function(e,t){e.inited||e.map.unnormalized||(e.map=a(t,null,!0))}),(e.deps||e.callback)&&q.require(e.deps||[],e.callback)},makeShimExports:function(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t},makeRequire:function(t,n){function o(i,r,u){var d,p,f;return n.enableBuildCallback&&r&&isFunction(r)&&(r.__requireJsBuild=!0),"string"==typeof i?isFunction(r)?c(makeError("requireargs","Invalid require call"),u):t&&hasProp(E,i)?E[i](S[t.id]):req.get?req.get(q,i,t,o):(p=a(i,t,!1,!0),d=p.id,hasProp(j,d)?j[d]:c(makeError("notloaded",'Module name "'+d+'" has not been loaded yet for context: '+e+(t?"":". Use require([])")))):(v(),q.nextTick(function(){v(),f=s(a(null,t)),f.skipMap=n.skipMap,f.init(i,r,u,{enabled:!0}),l()}),o)}return n=n||{},mixin(o,{isBrowser:isBrowser,toUrl:function(e){var r,n=e.lastIndexOf("."),o=e.split("/")[0],a="."===o||".."===o;return-1!==n&&(!a||n>1)&&(r=e.substring(n,e.length),e=e.substring(0,n)),q.nameToUrl(i(e,t&&t.id,!0),r,!0)},defined:function(e){return hasProp(j,a(e,t,!1,!0).id)},specified:function(e){return e=a(e,t,!1,!0).id,hasProp(j,e)||hasProp(S,e)}}),t||(o.undef=function(e){d();var i=a(e,t,!0),n=getOwn(S,e);n.undefed=!0,r(e),delete j[e],delete P[i.url],delete M[e],eachReverse(O,function(t,i){t[0]===e&&O.splice(i,1)}),delete q.defQueueMap[e],n&&(n.events.defined&&(M[e]=n.events),p(e))}),o},enable:function(e){getOwn(S,e.id)&&s(e).enable()},completeLoad:function(e){var t,i,r,o=getOwn(y.shim,e)||{},a=o.exports;for(d();O.length;){if(i=O.shift(),null===i[0]){if(i[0]=e,t)break;t=!0}else i[0]===e&&(t=!0);h(i)}if(q.defQueueMap={},r=getOwn(S,e),!t&&!hasProp(j,e)&&r&&!r.inited){if(!(!y.enforceDefine||a&&getGlobal(a)))return n(e)?void 0:c(makeError("nodefine","No define call for "+e,null,[e]));h([e,o.deps||[],o.exportsFn])}l()},nameToUrl:function(e,t,i){var r,n,o,a,s,u,c,d=getOwn(y.pkgs,e);if(d&&(e=d),c=getOwn(R,e))return q.nameToUrl(c,t,i);if(req.jsExtRegExp.test(e))s=e+(t||"");else{for(r=y.paths,n=e.split("/"),o=n.length;o>0;o-=1)if(a=n.slice(0,o).join("/"),u=getOwn(r,a)){isArray(u)&&(u=u[0]),n.splice(0,o,u);break}s=n.join("/"),s+=t||(/^data\:|^blob\:|\?/.test(s)||i?"":".js"),s=("/"===s.charAt(0)||s.match(/^[\w\+\.\-]+:/)?"":y.baseUrl)+s}return y.urlArgs&&!/^blob\:/.test(s)?s+y.urlArgs(e,s):s},load:function(e,t){req.load(q,e,t)},execCb:function(e,t,i,r){return t.apply(r,i)},onScriptLoad:function(e){if("load"===e.type||readyRegExp.test((e.currentTarget||e.srcElement).readyState)){interactiveScript=null;var t=g(e);q.completeLoad(t.id)}},onScriptError:function(e){var t=g(e);if(!n(t.id)){var i=[];return eachProp(S,function(e,r){0!==r.indexOf("_@r")&&each(e.depMaps,function(e){if(e.id===t.id)return i.push(r),!0})}),c(makeError("scripterror",'Script error for "'+t.id+(i.length?'", needed by: '+i.join(", "):'"'),e,[t.id]))}}},q.require=q.makeRequire(),q}function getInteractiveScript(){return interactiveScript&&"interactive"===interactiveScript.readyState?interactiveScript:(eachReverse(scripts(),function(e){if("interactive"===e.readyState)return interactiveScript=e}),interactiveScript)}var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.3.5",commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;if(void 0===define){if(void 0!==requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}void 0===require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,i,r){var n,o,a=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=i,i=r):e=[]),o&&o.context&&(a=o.context),n=getOwn(contexts,a),n||(n=contexts[a]=req.s.newContext(a)),o&&n.configure(o),n.require(e,t,i)},req.config=function(e){return req(e)},req.nextTick=void 0!==setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],(baseElement=document.getElementsByTagName("base")[0])&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,i){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(e,t,i){var r,n=e&&e.config||{};if(isBrowser)return r=req.createNode(n,t,i),r.setAttribute("data-requirecontext",e.contextName),r.setAttribute("data-requiremodule",t),!r.attachEvent||r.attachEvent.toString&&r.attachEvent.toString().indexOf("[native code")<0||isOpera?(r.addEventListener("load",e.onScriptLoad,!1),r.addEventListener("error",e.onScriptError,!1)):(useInteractive=!0,r.attachEvent("onreadystatechange",e.onScriptLoad)),r.src=i,n.onNodeCreated&&n.onNodeCreated(r,n,t,i),currentlyAddingScript=r,baseElement?head.insertBefore(r,baseElement):head.appendChild(r),currentlyAddingScript=null,r;if(isWebWorker)try{setTimeout(function(){},0),importScripts(i),e.completeLoad(t)}catch(r){e.onError(makeError("importscripts","importScripts failed for "+t+" at "+i,r,[t]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){if(head||(head=e.parentNode),dataMain=e.getAttribute("data-main"))return mainScript=dataMain,cfg.baseUrl||-1!==mainScript.indexOf("!")||(src=mainScript.split("/"),mainScript=src.pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,t,i){var r,n;"string"!=typeof e&&(i=t,t=e,e=null),isArray(t)||(i=t,t=null),!t&&isFunction(i)&&(t=[],i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript())&&(e||(e=r.getAttribute("data-requiremodule")),n=contexts[r.getAttribute("data-requirecontext")]),n?(n.defQueue.push([e,t,i]),n.defQueueMap[e]=!0):globalDefQueue.push([e,t,i])},define.amd={jQuery:!0},req.exec=function(text){return eval(text)},req(cfg)}}(this,"undefined"==typeof setTimeout?void 0:setTimeout); -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var compress = require('./lib/app/compress') 2 | var watermark = require('./lib/app/watermark') 3 | 4 | module.exports = { 5 | compress, 6 | watermark 7 | } -------------------------------------------------------------------------------- /lib/app/compress.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var isArray = require('../is_array') 3 | var base64toBlob = require('../base64_blob') 4 | var imgRotate = require('../rotate_draw') 5 | var params 6 | var Compress = function (obj) { 7 | return new Compress.prototype.init(obj) 8 | } 9 | Compress.prototype = { 10 | init: function (obj) { 11 | params = obj 12 | switch (isArray(params.src)) { 13 | case true: 14 | var dispose = this.dispose 15 | var a = 0 16 | var result = [] 17 | var blob_result = [] 18 | thumb() 19 | 20 | function thumb() { 21 | if (params.src[a]) { 22 | dispose(params.src[a], function (base64) { 23 | a++ 24 | result.push(base64) 25 | thumb() 26 | }, function (blob) { 27 | blob_result.push(blob) 28 | }) 29 | } else { 30 | if (params.ok) params.ok(result) 31 | setTimeout(function () { 32 | if (params.toBlob) params.toBlob(blob_result) 33 | }, 300); 34 | } 35 | } 36 | break; 37 | case false: 38 | this.dispose(params.src, function (base64) { 39 | if (params.ok) params.ok(base64) 40 | }, function (blob) { 41 | if (params.toBlob) params.toBlob(blob) 42 | }) 43 | break; 44 | } 45 | }, 46 | dispose: function (path, result, toBlob) { 47 | var img = new Image(); 48 | img.addEventListener("load", function () { 49 | var that = this; 50 | var w = that.width, 51 | h = that.height, 52 | scale = w / h; 53 | w = params.width || w; 54 | h = params.height || (w / scale); 55 | var scaleCount = Math.round(0.0014 * w); 56 | if (scaleCount >= 1 && !params.original) { 57 | if (scaleCount <= 2) { 58 | w = parseInt(w / 1.5); 59 | h = parseInt(h / 1.5); 60 | } else if (scaleCount == 3) { 61 | w = parseInt(w / 2); 62 | h = parseInt(h / 2); 63 | } else { 64 | w = parseInt(w / (scaleCount - 1.5)); 65 | h = parseInt(h / (scaleCount - 1.5)); 66 | } 67 | } 68 | var quality = 0.5; // 默认图片质量 69 | var canvas = document.createElement('canvas'); 70 | var ctx = canvas.getContext('2d'); 71 | var anw = document.createAttribute("width"); 72 | anw.nodeValue = w; 73 | var anh = document.createAttribute("height"); 74 | anh.nodeValue = h; 75 | canvas.setAttributeNode(anw); 76 | canvas.setAttributeNode(anh); 77 | imgRotate(that, canvas, { 78 | width: w, 79 | height: h 80 | }) 81 | if (params.quality && params.quality <= 99 && params.quality > 0) { 82 | quality = params.quality; 83 | } 84 | 85 | var base64 = canvas.toDataURL('image/jpeg', quality * 0.01); 86 | if (result) result(base64) 87 | if (toBlob) { 88 | try { 89 | canvas.toBlob(function (blob) { 90 | toBlob(blob); 91 | }) 92 | } catch (error) { 93 | toBlob(base64toBlob(base64)) 94 | } 95 | } 96 | }, false); 97 | img.crossOrigin = 'Anonymous'; 98 | img.src = path; 99 | } 100 | } 101 | Compress.prototype.init.prototype = Compress.prototype 102 | 103 | module.exports = Compress -------------------------------------------------------------------------------- /lib/app/watermark.js: -------------------------------------------------------------------------------- 1 | var getLength = require('../get_length') 2 | var imgRotate = require('../rotate_draw') 3 | var Watermark = function (obj) { 4 | return new Watermark.prototype.init(obj) 5 | } 6 | Watermark.prototype = { 7 | init: function (obj) { 8 | if (!obj) return 9 | if (typeof obj == 'object') { 10 | this.add(obj) 11 | } else { 12 | this.src = obj 13 | } 14 | }, 15 | add: function (obj) { 16 | var img = new Image(); 17 | img.addEventListener("load", function () { 18 | var canvas = document.createElement("canvas"); 19 | canvas.width = this.width; 20 | canvas.height = this.height; 21 | var ctx = canvas.getContext("2d"); 22 | var txt = obj.text || obj; 23 | 24 | imgRotate(img, canvas); 25 | 26 | var fontSize = obj.fontSize >= 1 ? obj.fontSize : parseInt(canvas.height / 14) 27 | ctx.font = fontSize + "px sans-serif"; 28 | ctx.fillStyle = "#FFFFFF"; 29 | ctx.fillText(txt, canvas.width - ((getLength(txt) + 0.5) * fontSize), canvas.height - fontSize / 2); 30 | var base64 = canvas.toDataURL('image/jpeg'); 31 | if (obj.ok) obj.ok(base64) 32 | }, false); 33 | img.crossOrigin = 'Anonymous'; 34 | obj.src ? img.src = obj.src : img.src = this.src 35 | } 36 | } 37 | Watermark.prototype.init.prototype = Watermark.prototype 38 | 39 | module.exports = Watermark -------------------------------------------------------------------------------- /lib/base64_blob.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var base642blob = function (dataurl) { 3 | var arr = dataurl.split(','), 4 | mime = arr[0].match(/:(.*?);/)[1], 5 | bstr = atob(arr[1]), 6 | n = bstr.length, 7 | u8arr = new Uint8Array(n); 8 | while (n--) { 9 | u8arr[n] = bstr.charCodeAt(n); 10 | } 11 | return new Blob([u8arr], { 12 | type: mime 13 | }); 14 | } 15 | module.exports = base642blob -------------------------------------------------------------------------------- /lib/exif.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var debug = false; 4 | 5 | var root = this; 6 | 7 | var EXIF = function(obj) { 8 | if (obj instanceof EXIF) return obj; 9 | if (!(this instanceof EXIF)) return new EXIF(obj); 10 | this.EXIFwrapped = obj; 11 | }; 12 | 13 | if (typeof exports !== 'undefined') { 14 | if (typeof module !== 'undefined' && module.exports) { 15 | exports = module.exports = EXIF; 16 | } 17 | exports.EXIF = EXIF; 18 | } else { 19 | root.EXIF = EXIF; 20 | } 21 | 22 | var ExifTags = EXIF.Tags = { 23 | 24 | // version tags 25 | 0x9000 : "ExifVersion", // EXIF version 26 | 0xA000 : "FlashpixVersion", // Flashpix format version 27 | 28 | // colorspace tags 29 | 0xA001 : "ColorSpace", // Color space information tag 30 | 31 | // image configuration 32 | 0xA002 : "PixelXDimension", // Valid width of meaningful image 33 | 0xA003 : "PixelYDimension", // Valid height of meaningful image 34 | 0x9101 : "ComponentsConfiguration", // Information about channels 35 | 0x9102 : "CompressedBitsPerPixel", // Compressed bits per pixel 36 | 37 | // user information 38 | 0x927C : "MakerNote", // Any desired information written by the manufacturer 39 | 0x9286 : "UserComment", // Comments by user 40 | 41 | // related file 42 | 0xA004 : "RelatedSoundFile", // Name of related sound file 43 | 44 | // date and time 45 | 0x9003 : "DateTimeOriginal", // Date and time when the original image was generated 46 | 0x9004 : "DateTimeDigitized", // Date and time when the image was stored digitally 47 | 0x9290 : "SubsecTime", // Fractions of seconds for DateTime 48 | 0x9291 : "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal 49 | 0x9292 : "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized 50 | 51 | // picture-taking conditions 52 | 0x829A : "ExposureTime", // Exposure time (in seconds) 53 | 0x829D : "FNumber", // F number 54 | 0x8822 : "ExposureProgram", // Exposure program 55 | 0x8824 : "SpectralSensitivity", // Spectral sensitivity 56 | 0x8827 : "ISOSpeedRatings", // ISO speed rating 57 | 0x8828 : "OECF", // Optoelectric conversion factor 58 | 0x9201 : "ShutterSpeedValue", // Shutter speed 59 | 0x9202 : "ApertureValue", // Lens aperture 60 | 0x9203 : "BrightnessValue", // Value of brightness 61 | 0x9204 : "ExposureBias", // Exposure bias 62 | 0x9205 : "MaxApertureValue", // Smallest F number of lens 63 | 0x9206 : "SubjectDistance", // Distance to subject in meters 64 | 0x9207 : "MeteringMode", // Metering mode 65 | 0x9208 : "LightSource", // Kind of light source 66 | 0x9209 : "Flash", // Flash status 67 | 0x9214 : "SubjectArea", // Location and area of main subject 68 | 0x920A : "FocalLength", // Focal length of the lens in mm 69 | 0xA20B : "FlashEnergy", // Strobe energy in BCPS 70 | 0xA20C : "SpatialFrequencyResponse", // 71 | 0xA20E : "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit 72 | 0xA20F : "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit 73 | 0xA210 : "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution 74 | 0xA214 : "SubjectLocation", // Location of subject in image 75 | 0xA215 : "ExposureIndex", // Exposure index selected on camera 76 | 0xA217 : "SensingMethod", // Image sensor type 77 | 0xA300 : "FileSource", // Image source (3 == DSC) 78 | 0xA301 : "SceneType", // Scene type (1 == directly photographed) 79 | 0xA302 : "CFAPattern", // Color filter array geometric pattern 80 | 0xA401 : "CustomRendered", // Special processing 81 | 0xA402 : "ExposureMode", // Exposure mode 82 | 0xA403 : "WhiteBalance", // 1 = auto white balance, 2 = manual 83 | 0xA404 : "DigitalZoomRation", // Digital zoom ratio 84 | 0xA405 : "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm) 85 | 0xA406 : "SceneCaptureType", // Type of scene 86 | 0xA407 : "GainControl", // Degree of overall image gain adjustment 87 | 0xA408 : "Contrast", // Direction of contrast processing applied by camera 88 | 0xA409 : "Saturation", // Direction of saturation processing applied by camera 89 | 0xA40A : "Sharpness", // Direction of sharpness processing applied by camera 90 | 0xA40B : "DeviceSettingDescription", // 91 | 0xA40C : "SubjectDistanceRange", // Distance to subject 92 | 93 | // other tags 94 | 0xA005 : "InteroperabilityIFDPointer", 95 | 0xA420 : "ImageUniqueID" // Identifier assigned uniquely to each image 96 | }; 97 | 98 | var TiffTags = EXIF.TiffTags = { 99 | 0x0100 : "ImageWidth", 100 | 0x0101 : "ImageHeight", 101 | 0x8769 : "ExifIFDPointer", 102 | 0x8825 : "GPSInfoIFDPointer", 103 | 0xA005 : "InteroperabilityIFDPointer", 104 | 0x0102 : "BitsPerSample", 105 | 0x0103 : "Compression", 106 | 0x0106 : "PhotometricInterpretation", 107 | 0x0112 : "Orientation", 108 | 0x0115 : "SamplesPerPixel", 109 | 0x011C : "PlanarConfiguration", 110 | 0x0212 : "YCbCrSubSampling", 111 | 0x0213 : "YCbCrPositioning", 112 | 0x011A : "XResolution", 113 | 0x011B : "YResolution", 114 | 0x0128 : "ResolutionUnit", 115 | 0x0111 : "StripOffsets", 116 | 0x0116 : "RowsPerStrip", 117 | 0x0117 : "StripByteCounts", 118 | 0x0201 : "JPEGInterchangeFormat", 119 | 0x0202 : "JPEGInterchangeFormatLength", 120 | 0x012D : "TransferFunction", 121 | 0x013E : "WhitePoint", 122 | 0x013F : "PrimaryChromaticities", 123 | 0x0211 : "YCbCrCoefficients", 124 | 0x0214 : "ReferenceBlackWhite", 125 | 0x0132 : "DateTime", 126 | 0x010E : "ImageDescription", 127 | 0x010F : "Make", 128 | 0x0110 : "Model", 129 | 0x0131 : "Software", 130 | 0x013B : "Artist", 131 | 0x8298 : "Copyright" 132 | }; 133 | 134 | var GPSTags = EXIF.GPSTags = { 135 | 0x0000 : "GPSVersionID", 136 | 0x0001 : "GPSLatitudeRef", 137 | 0x0002 : "GPSLatitude", 138 | 0x0003 : "GPSLongitudeRef", 139 | 0x0004 : "GPSLongitude", 140 | 0x0005 : "GPSAltitudeRef", 141 | 0x0006 : "GPSAltitude", 142 | 0x0007 : "GPSTimeStamp", 143 | 0x0008 : "GPSSatellites", 144 | 0x0009 : "GPSStatus", 145 | 0x000A : "GPSMeasureMode", 146 | 0x000B : "GPSDOP", 147 | 0x000C : "GPSSpeedRef", 148 | 0x000D : "GPSSpeed", 149 | 0x000E : "GPSTrackRef", 150 | 0x000F : "GPSTrack", 151 | 0x0010 : "GPSImgDirectionRef", 152 | 0x0011 : "GPSImgDirection", 153 | 0x0012 : "GPSMapDatum", 154 | 0x0013 : "GPSDestLatitudeRef", 155 | 0x0014 : "GPSDestLatitude", 156 | 0x0015 : "GPSDestLongitudeRef", 157 | 0x0016 : "GPSDestLongitude", 158 | 0x0017 : "GPSDestBearingRef", 159 | 0x0018 : "GPSDestBearing", 160 | 0x0019 : "GPSDestDistanceRef", 161 | 0x001A : "GPSDestDistance", 162 | 0x001B : "GPSProcessingMethod", 163 | 0x001C : "GPSAreaInformation", 164 | 0x001D : "GPSDateStamp", 165 | 0x001E : "GPSDifferential" 166 | }; 167 | 168 | var StringValues = EXIF.StringValues = { 169 | ExposureProgram : { 170 | 0 : "Not defined", 171 | 1 : "Manual", 172 | 2 : "Normal program", 173 | 3 : "Aperture priority", 174 | 4 : "Shutter priority", 175 | 5 : "Creative program", 176 | 6 : "Action program", 177 | 7 : "Portrait mode", 178 | 8 : "Landscape mode" 179 | }, 180 | MeteringMode : { 181 | 0 : "Unknown", 182 | 1 : "Average", 183 | 2 : "CenterWeightedAverage", 184 | 3 : "Spot", 185 | 4 : "MultiSpot", 186 | 5 : "Pattern", 187 | 6 : "Partial", 188 | 255 : "Other" 189 | }, 190 | LightSource : { 191 | 0 : "Unknown", 192 | 1 : "Daylight", 193 | 2 : "Fluorescent", 194 | 3 : "Tungsten (incandescent light)", 195 | 4 : "Flash", 196 | 9 : "Fine weather", 197 | 10 : "Cloudy weather", 198 | 11 : "Shade", 199 | 12 : "Daylight fluorescent (D 5700 - 7100K)", 200 | 13 : "Day white fluorescent (N 4600 - 5400K)", 201 | 14 : "Cool white fluorescent (W 3900 - 4500K)", 202 | 15 : "White fluorescent (WW 3200 - 3700K)", 203 | 17 : "Standard light A", 204 | 18 : "Standard light B", 205 | 19 : "Standard light C", 206 | 20 : "D55", 207 | 21 : "D65", 208 | 22 : "D75", 209 | 23 : "D50", 210 | 24 : "ISO studio tungsten", 211 | 255 : "Other" 212 | }, 213 | Flash : { 214 | 0x0000 : "Flash did not fire", 215 | 0x0001 : "Flash fired", 216 | 0x0005 : "Strobe return light not detected", 217 | 0x0007 : "Strobe return light detected", 218 | 0x0009 : "Flash fired, compulsory flash mode", 219 | 0x000D : "Flash fired, compulsory flash mode, return light not detected", 220 | 0x000F : "Flash fired, compulsory flash mode, return light detected", 221 | 0x0010 : "Flash did not fire, compulsory flash mode", 222 | 0x0018 : "Flash did not fire, auto mode", 223 | 0x0019 : "Flash fired, auto mode", 224 | 0x001D : "Flash fired, auto mode, return light not detected", 225 | 0x001F : "Flash fired, auto mode, return light detected", 226 | 0x0020 : "No flash function", 227 | 0x0041 : "Flash fired, red-eye reduction mode", 228 | 0x0045 : "Flash fired, red-eye reduction mode, return light not detected", 229 | 0x0047 : "Flash fired, red-eye reduction mode, return light detected", 230 | 0x0049 : "Flash fired, compulsory flash mode, red-eye reduction mode", 231 | 0x004D : "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected", 232 | 0x004F : "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected", 233 | 0x0059 : "Flash fired, auto mode, red-eye reduction mode", 234 | 0x005D : "Flash fired, auto mode, return light not detected, red-eye reduction mode", 235 | 0x005F : "Flash fired, auto mode, return light detected, red-eye reduction mode" 236 | }, 237 | SensingMethod : { 238 | 1 : "Not defined", 239 | 2 : "One-chip color area sensor", 240 | 3 : "Two-chip color area sensor", 241 | 4 : "Three-chip color area sensor", 242 | 5 : "Color sequential area sensor", 243 | 7 : "Trilinear sensor", 244 | 8 : "Color sequential linear sensor" 245 | }, 246 | SceneCaptureType : { 247 | 0 : "Standard", 248 | 1 : "Landscape", 249 | 2 : "Portrait", 250 | 3 : "Night scene" 251 | }, 252 | SceneType : { 253 | 1 : "Directly photographed" 254 | }, 255 | CustomRendered : { 256 | 0 : "Normal process", 257 | 1 : "Custom process" 258 | }, 259 | WhiteBalance : { 260 | 0 : "Auto white balance", 261 | 1 : "Manual white balance" 262 | }, 263 | GainControl : { 264 | 0 : "None", 265 | 1 : "Low gain up", 266 | 2 : "High gain up", 267 | 3 : "Low gain down", 268 | 4 : "High gain down" 269 | }, 270 | Contrast : { 271 | 0 : "Normal", 272 | 1 : "Soft", 273 | 2 : "Hard" 274 | }, 275 | Saturation : { 276 | 0 : "Normal", 277 | 1 : "Low saturation", 278 | 2 : "High saturation" 279 | }, 280 | Sharpness : { 281 | 0 : "Normal", 282 | 1 : "Soft", 283 | 2 : "Hard" 284 | }, 285 | SubjectDistanceRange : { 286 | 0 : "Unknown", 287 | 1 : "Macro", 288 | 2 : "Close view", 289 | 3 : "Distant view" 290 | }, 291 | FileSource : { 292 | 3 : "DSC" 293 | }, 294 | 295 | Components : { 296 | 0 : "", 297 | 1 : "Y", 298 | 2 : "Cb", 299 | 3 : "Cr", 300 | 4 : "R", 301 | 5 : "G", 302 | 6 : "B" 303 | } 304 | }; 305 | 306 | function addEvent(element, event, handler) { 307 | if (element.addEventListener) { 308 | element.addEventListener(event, handler, false); 309 | } else if (element.attachEvent) { 310 | element.attachEvent("on" + event, handler); 311 | } 312 | } 313 | 314 | function imageHasData(img) { 315 | return !!(img.exifdata); 316 | } 317 | 318 | 319 | function base64ToArrayBuffer(base64, contentType) { 320 | contentType = contentType || base64.match(/^data\:([^\;]+)\;base64,/mi)[1] || ''; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg' 321 | base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, ''); 322 | var binary = atob(base64); 323 | var len = binary.length; 324 | var buffer = new ArrayBuffer(len); 325 | var view = new Uint8Array(buffer); 326 | for (var i = 0; i < len; i++) { 327 | view[i] = binary.charCodeAt(i); 328 | } 329 | return buffer; 330 | } 331 | 332 | function objectURLToBlob(url, callback) { 333 | var http = new XMLHttpRequest(); 334 | http.open("GET", url, true); 335 | http.responseType = "blob"; 336 | http.onload = function(e) { 337 | if (this.status == 200 || this.status === 0) { 338 | callback(this.response); 339 | } 340 | }; 341 | http.send(); 342 | } 343 | 344 | function getImageData(img, callback) { 345 | function handleBinaryFile(binFile) { 346 | var data = findEXIFinJPEG(binFile); 347 | var iptcdata = findIPTCinJPEG(binFile); 348 | img.exifdata = data || {}; 349 | img.iptcdata = iptcdata || {}; 350 | if (callback) { 351 | callback.call(img); 352 | } 353 | } 354 | 355 | if (img.src) { 356 | if (/^data\:/i.test(img.src)) { // Data URI 357 | var arrayBuffer = base64ToArrayBuffer(img.src); 358 | handleBinaryFile(arrayBuffer); 359 | 360 | } else if (/^blob\:/i.test(img.src)) { // Object URL 361 | var fileReader = new FileReader(); 362 | fileReader.onload = function(e) { 363 | handleBinaryFile(e.target.result); 364 | }; 365 | objectURLToBlob(img.src, function (blob) { 366 | fileReader.readAsArrayBuffer(blob); 367 | }); 368 | } else { 369 | var http = new XMLHttpRequest(); 370 | http.onload = function() { 371 | if (this.status == 200 || this.status === 0) { 372 | handleBinaryFile(http.response); 373 | } else { 374 | throw "Could not load image"; 375 | } 376 | http = null; 377 | }; 378 | http.open("GET", img.src, true); 379 | http.responseType = "arraybuffer"; 380 | http.send(null); 381 | } 382 | } else if (window.FileReader && (img instanceof window.Blob || img instanceof window.File)) { 383 | var fileReader = new FileReader(); 384 | fileReader.onload = function(e) { 385 | if (debug) console.log("Got file of length " + e.target.result.byteLength); 386 | handleBinaryFile(e.target.result); 387 | }; 388 | 389 | fileReader.readAsArrayBuffer(img); 390 | } 391 | } 392 | 393 | function findEXIFinJPEG(file) { 394 | var dataView = new DataView(file); 395 | 396 | if (debug) console.log("Got file of length " + file.byteLength); 397 | if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { 398 | if (debug) console.log("Not a valid JPEG"); 399 | return false; // not a valid jpeg 400 | } 401 | 402 | var offset = 2, 403 | length = file.byteLength, 404 | marker; 405 | 406 | while (offset < length) { 407 | if (dataView.getUint8(offset) != 0xFF) { 408 | if (debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(offset)); 409 | return false; // not a valid marker, something is wrong 410 | } 411 | 412 | marker = dataView.getUint8(offset + 1); 413 | if (debug) console.log(marker); 414 | 415 | // we could implement handling for other markers here, 416 | // but we're only looking for 0xFFE1 for EXIF data 417 | 418 | if (marker == 225) { 419 | if (debug) console.log("Found 0xFFE1 marker"); 420 | 421 | return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2); 422 | 423 | // offset += 2 + file.getShortAt(offset+2, true); 424 | 425 | } else { 426 | offset += 2 + dataView.getUint16(offset+2); 427 | } 428 | 429 | } 430 | 431 | } 432 | 433 | function findIPTCinJPEG(file) { 434 | var dataView = new DataView(file); 435 | 436 | if (debug) console.log("Got file of length " + file.byteLength); 437 | if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { 438 | if (debug) console.log("Not a valid JPEG"); 439 | return false; // not a valid jpeg 440 | } 441 | 442 | var offset = 2, 443 | length = file.byteLength; 444 | 445 | 446 | var isFieldSegmentStart = function(dataView, offset){ 447 | return ( 448 | dataView.getUint8(offset) === 0x38 && 449 | dataView.getUint8(offset+1) === 0x42 && 450 | dataView.getUint8(offset+2) === 0x49 && 451 | dataView.getUint8(offset+3) === 0x4D && 452 | dataView.getUint8(offset+4) === 0x04 && 453 | dataView.getUint8(offset+5) === 0x04 454 | ); 455 | }; 456 | 457 | while (offset < length) { 458 | 459 | if ( isFieldSegmentStart(dataView, offset )){ 460 | 461 | // Get the length of the name header (which is padded to an even number of bytes) 462 | var nameHeaderLength = dataView.getUint8(offset+7); 463 | if(nameHeaderLength % 2 !== 0) nameHeaderLength += 1; 464 | // Check for pre photoshop 6 format 465 | if(nameHeaderLength === 0) { 466 | // Always 4 467 | nameHeaderLength = 4; 468 | } 469 | 470 | var startOffset = offset + 8 + nameHeaderLength; 471 | var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength); 472 | 473 | return readIPTCData(file, startOffset, sectionLength); 474 | 475 | break; 476 | 477 | } 478 | 479 | 480 | // Not the marker, continue searching 481 | offset++; 482 | 483 | } 484 | 485 | } 486 | var IptcFieldMap = { 487 | 0x78 : 'caption', 488 | 0x6E : 'credit', 489 | 0x19 : 'keywords', 490 | 0x37 : 'dateCreated', 491 | 0x50 : 'byline', 492 | 0x55 : 'bylineTitle', 493 | 0x7A : 'captionWriter', 494 | 0x69 : 'headline', 495 | 0x74 : 'copyright', 496 | 0x0F : 'category' 497 | }; 498 | function readIPTCData(file, startOffset, sectionLength){ 499 | var dataView = new DataView(file); 500 | var data = {}; 501 | var fieldValue, fieldName, dataSize, segmentType, segmentSize; 502 | var segmentStartPos = startOffset; 503 | while(segmentStartPos < startOffset+sectionLength) { 504 | if(dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos+1) === 0x02){ 505 | segmentType = dataView.getUint8(segmentStartPos+2); 506 | if(segmentType in IptcFieldMap) { 507 | dataSize = dataView.getInt16(segmentStartPos+3); 508 | segmentSize = dataSize + 5; 509 | fieldName = IptcFieldMap[segmentType]; 510 | fieldValue = getStringFromDB(dataView, segmentStartPos+5, dataSize); 511 | // Check if we already stored a value with this name 512 | if(data.hasOwnProperty(fieldName)) { 513 | // Value already stored with this name, create multivalue field 514 | if(data[fieldName] instanceof Array) { 515 | data[fieldName].push(fieldValue); 516 | } 517 | else { 518 | data[fieldName] = [data[fieldName], fieldValue]; 519 | } 520 | } 521 | else { 522 | data[fieldName] = fieldValue; 523 | } 524 | } 525 | 526 | } 527 | segmentStartPos++; 528 | } 529 | return data; 530 | } 531 | 532 | 533 | 534 | function readTags(file, tiffStart, dirStart, strings, bigEnd) { 535 | var entries = file.getUint16(dirStart, !bigEnd), 536 | tags = {}, 537 | entryOffset, tag, 538 | i; 539 | 540 | for (i=0;i 4 ? valueOffset : (entryOffset + 8); 565 | vals = []; 566 | for (n=0;n 4 ? valueOffset : (entryOffset + 8); 574 | return getStringFromDB(file, offset, numValues-1); 575 | 576 | case 3: // short, 16 bit int 577 | if (numValues == 1) { 578 | return file.getUint16(entryOffset + 8, !bigEnd); 579 | } else { 580 | offset = numValues > 2 ? valueOffset : (entryOffset + 8); 581 | vals = []; 582 | for (n=0;n= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) { 8 | bytesCount += 1; 9 | } else { 10 | bytesCount += 2; 11 | } 12 | } 13 | return parseInt((bytesCount / 2).toFixed(0)); 14 | } 15 | 16 | module.exports = getLength -------------------------------------------------------------------------------- /lib/is_array.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var isArray = function (value) { 3 | if (typeof Array.isArray === "function") { 4 | return Array.isArray(value) 5 | } else { 6 | return Object.prototype.toString.call(value) === "[object Array]" 7 | } 8 | } 9 | module.exports = isArray -------------------------------------------------------------------------------- /lib/rotate_draw.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var EXIF = require('./exif') 3 | var rotateImg = function (img, canvas, custom, untiles) { 4 | var Orientation; 5 | EXIF.getData(img, function () { 6 | EXIF.getAllTags(this); 7 | Orientation = EXIF.getTag(this, 'Orientation'); 8 | }); 9 | var ctx = canvas.getContext("2d"); 10 | 11 | if (custom) { 12 | img.width = custom.width 13 | img.height = custom.height 14 | } 15 | switch (Orientation) { 16 | case 6: 17 | canvas.width = img.height 18 | canvas.height = img.width 19 | ctx.save() 20 | ctx.rotate(Math.PI / 2); 21 | if (!untiles) { 22 | tiles(canvas, ctx, img, function (istiles) { 23 | if (!istiles) { 24 | ctx.drawImage(img, 0, -img.height, canvas.height, canvas.width) 25 | } 26 | ctx.restore() 27 | }) 28 | } else { 29 | ctx.drawImage(img, 0, -img.height, canvas.height, canvas.width) 30 | ctx.restore() 31 | } 32 | break; 33 | case 3: 34 | ctx.save() 35 | ctx.rotate(Math.PI); 36 | if (!untiles) { 37 | tiles(canvas, ctx, img, function (istiles) { 38 | if (!istiles) { 39 | ctx.drawImage(img, 0, 0, -img.width, -img.height); 40 | } 41 | ctx.restore() 42 | }) 43 | } else { 44 | ctx.drawImage(img, 0, 0, -img.width, -img.height); 45 | ctx.restore() 46 | } 47 | // ctx.drawImage(img, 0, 0, -img.width, -img.height); 48 | // ctx.restore() 49 | break; 50 | case 8: 51 | canvas.width = img.height; 52 | canvas.height = img.width; 53 | ctx.save() 54 | ctx.rotate(Math.PI * 3 / 2); 55 | if (!untiles) { 56 | tiles(canvas, ctx, img, function (istiles) { 57 | if (!istiles) { 58 | ctx.drawImage(img, 0, 0, -img.width, img.height); 59 | } 60 | ctx.restore() 61 | }) 62 | } else { 63 | ctx.drawImage(img, 0, 0, -img.width, img.height); 64 | ctx.restore() 65 | } 66 | // ctx.drawImage(img, 0, 0, -img.width, img.height); 67 | // ctx.restore() 68 | break; 69 | default: 70 | if (!untiles) { 71 | tiles(canvas, ctx, img, function (istiles) { 72 | if (!istiles) { 73 | ctx.drawImage(img, 0, 0, img.width, img.height); 74 | } 75 | }) 76 | } else { 77 | ctx.drawImage(img, 0, 0, img.width, img.height); 78 | } 79 | break; 80 | } 81 | } 82 | var tiles = function (canvas, ctx, img, isDone) { 83 | var width = img.width; 84 | var height = img.height; 85 | 86 | //如果图片大于四百万像素,计算压缩比并将大小压至400万以下 87 | var ratio; 88 | if ((ratio = width * height / 4000000) > 1) { 89 | ratio = Math.sqrt(ratio); 90 | width /= ratio; 91 | height /= ratio; 92 | } else { 93 | ratio = 1; 94 | } 95 | 96 | //如果图片像素大于100万则使用瓦片绘制 97 | var count; 98 | if ((count = width * height / 1000000) > 1) { 99 | canvas.width = width 100 | canvas.height = height 101 | count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片 102 | //计算每块瓦片的宽和高 103 | var nw = ~~(width / count); 104 | var nh = ~~(height / count); 105 | 106 | var tCanvas = document.createElement('canvas') 107 | tCanvas.width = nw; 108 | tCanvas.height = nh; 109 | var tctx = tCanvas.getContext('2d') 110 | 111 | for (var i = 0; i < count; i++) { 112 | for (var j = 0; j < count; j++) { 113 | tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh); 114 | ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh); 115 | } 116 | } 117 | isDone(true) 118 | rotateImg(img, canvas, { 119 | width: width, 120 | height: height 121 | }, true) 122 | } else { 123 | isDone() 124 | } 125 | } 126 | module.exports = rotateImg -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ccimg", 3 | "version": "1.0.1", 4 | "description": "A set of web image tools by js, include Compress, Watermark", 5 | "main": "index.js", 6 | "directories": { 7 | "doc": "docs" 8 | }, 9 | "scripts": { 10 | 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/palxiao/ccImg_tool.git" 15 | }, 16 | "keywords": [ 17 | "js", 18 | "javascript", 19 | "compress", 20 | "watermark" 21 | ], 22 | "author": "ShawnPhang", 23 | "license": "ISC", 24 | "bugs": { 25 | "url": "https://github.com/palxiao/ccImg_tool/issues" 26 | }, 27 | "homepage": "https://github.com/palxiao/ccImg_tool#readme" 28 | } 29 | -------------------------------------------------------------------------------- /src/build.js: -------------------------------------------------------------------------------- 1 | ({ 2 | appDir: './', 3 | baseUrl: './js', 4 | dir: '../dist', 5 | modules: [{ 6 | name: 'main' 7 | }], 8 | fileExclusionRegExp: /^(r|build)\.js$/, 9 | optimizeCss: 'standard', 10 | removeCombined: true, 11 | paths: { 12 | '$cropper': 'app/cropper', 13 | 'cropper': 'lib/cropper', 14 | 'compress': 'app/compress', 15 | 'watermark': 'app/watermark', 16 | 'isArray': 'app/is_array', 17 | 'getLength': 'app/get_length', 18 | 'base64toBlob': 'app/base64_blob', 19 | 'exif': 'lib/exif', 20 | 'rotateDraw': 'app/rotate_draw', 21 | 'gif': 'lib/gif' 22 | }, 23 | 24 | shim: { 25 | 'cropper': { 26 | // deps: ['base64toBlob'], 27 | exports: 'cropper' 28 | } 29 | } 30 | }) -------------------------------------------------------------------------------- /src/css/cropper.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Cropper.js v1.3.5 3 | * https://github.com/fengyuanchen/cropperjs 4 | * 5 | * Copyright (c) 2015-2018 Chen Fengyuan 6 | * Released under the MIT license 7 | * 8 | * Date: 2018-04-15T06:19:56.029Z 9 | */ 10 | 11 | .cropper-container { 12 | direction: ltr; 13 | font-size: 0; 14 | line-height: 0; 15 | position: relative; 16 | -ms-touch-action: none; 17 | touch-action: none; 18 | -webkit-user-select: none; 19 | -moz-user-select: none; 20 | -ms-user-select: none; 21 | user-select: none; 22 | } 23 | 24 | .cropper-container img {/*Avoid margin top issue (Occur only when margin-top <= -height) 25 | */ 26 | display: block; 27 | height: 100%; 28 | image-orientation: 0deg; 29 | max-height: none !important; 30 | max-width: none !important; 31 | min-height: 0 !important; 32 | min-width: 0 !important; 33 | width: 100%; 34 | } 35 | 36 | .cropper-wrap-box, 37 | .cropper-canvas, 38 | .cropper-drag-box, 39 | .cropper-crop-box, 40 | .cropper-modal { 41 | bottom: 0; 42 | left: 0; 43 | position: absolute; 44 | right: 0; 45 | top: 0; 46 | } 47 | 48 | .cropper-wrap-box, 49 | .cropper-canvas { 50 | overflow: hidden; 51 | } 52 | 53 | .cropper-drag-box { 54 | background-color: #fff; 55 | opacity: 0; 56 | } 57 | 58 | .cropper-modal { 59 | background-color: #000; 60 | opacity: .5; 61 | } 62 | 63 | .cropper-view-box { 64 | display: block; 65 | height: 100%; 66 | outline-color: rgba(51, 153, 255, 0.75); 67 | outline: 1px solid #39f; 68 | overflow: hidden; 69 | width: 100%; 70 | } 71 | 72 | .cropper-dashed { 73 | border: 0 dashed #eee; 74 | display: block; 75 | opacity: .5; 76 | position: absolute; 77 | } 78 | 79 | .cropper-dashed.dashed-h { 80 | border-bottom-width: 1px; 81 | border-top-width: 1px; 82 | height: 33.33333%; 83 | left: 0; 84 | top: 33.33333%; 85 | width: 100%; 86 | } 87 | 88 | .cropper-dashed.dashed-v { 89 | border-left-width: 1px; 90 | border-right-width: 1px; 91 | height: 100%; 92 | left: 33.33333%; 93 | top: 0; 94 | width: 33.33333%; 95 | } 96 | 97 | .cropper-center { 98 | display: block; 99 | height: 0; 100 | left: 50%; 101 | opacity: .75; 102 | position: absolute; 103 | top: 50%; 104 | width: 0; 105 | } 106 | 107 | .cropper-center:before, 108 | .cropper-center:after { 109 | background-color: #eee; 110 | content: ' '; 111 | display: block; 112 | position: absolute; 113 | } 114 | 115 | .cropper-center:before { 116 | height: 1px; 117 | left: -3px; 118 | top: 0; 119 | width: 7px; 120 | } 121 | 122 | .cropper-center:after { 123 | height: 7px; 124 | left: 0; 125 | top: -3px; 126 | width: 1px; 127 | } 128 | 129 | .cropper-face, 130 | .cropper-line, 131 | .cropper-point { 132 | display: block; 133 | height: 100%; 134 | opacity: .1; 135 | position: absolute; 136 | width: 100%; 137 | } 138 | 139 | .cropper-face { 140 | background-color: #fff; 141 | left: 0; 142 | top: 0; 143 | } 144 | 145 | .cropper-line { 146 | background-color: #39f; 147 | } 148 | 149 | .cropper-line.line-e { 150 | cursor: ew-resize; 151 | right: -3px; 152 | top: 0; 153 | width: 5px; 154 | } 155 | 156 | .cropper-line.line-n { 157 | cursor: ns-resize; 158 | height: 5px; 159 | left: 0; 160 | top: -3px; 161 | } 162 | 163 | .cropper-line.line-w { 164 | cursor: ew-resize; 165 | left: -3px; 166 | top: 0; 167 | width: 5px; 168 | } 169 | 170 | .cropper-line.line-s { 171 | bottom: -3px; 172 | cursor: ns-resize; 173 | height: 5px; 174 | left: 0; 175 | } 176 | 177 | .cropper-point { 178 | background-color: #39f; 179 | height: 5px; 180 | opacity: .75; 181 | width: 5px; 182 | } 183 | 184 | .cropper-point.point-e { 185 | cursor: ew-resize; 186 | margin-top: -3px; 187 | right: -3px; 188 | top: 50%; 189 | } 190 | 191 | .cropper-point.point-n { 192 | cursor: ns-resize; 193 | left: 50%; 194 | margin-left: -3px; 195 | top: -3px; 196 | } 197 | 198 | .cropper-point.point-w { 199 | cursor: ew-resize; 200 | left: -3px; 201 | margin-top: -3px; 202 | top: 50%; 203 | } 204 | 205 | .cropper-point.point-s { 206 | bottom: -3px; 207 | cursor: s-resize; 208 | left: 50%; 209 | margin-left: -3px; 210 | } 211 | 212 | .cropper-point.point-ne { 213 | cursor: nesw-resize; 214 | right: -3px; 215 | top: -3px; 216 | } 217 | 218 | .cropper-point.point-nw { 219 | cursor: nwse-resize; 220 | left: -3px; 221 | top: -3px; 222 | } 223 | 224 | .cropper-point.point-sw { 225 | bottom: -3px; 226 | cursor: nesw-resize; 227 | left: -3px; 228 | } 229 | 230 | .cropper-point.point-se { 231 | bottom: -3px; 232 | cursor: nwse-resize; 233 | height: 20px; 234 | opacity: 1; 235 | right: -3px; 236 | width: 20px; 237 | } 238 | 239 | @media (min-width: 768px) { 240 | .cropper-point.point-se { 241 | height: 15px; 242 | width: 15px; 243 | } 244 | } 245 | 246 | @media (min-width: 992px) { 247 | .cropper-point.point-se { 248 | height: 10px; 249 | width: 10px; 250 | } 251 | } 252 | 253 | @media (min-width: 1200px) { 254 | .cropper-point.point-se { 255 | height: 5px; 256 | opacity: .75; 257 | width: 5px; 258 | } 259 | } 260 | 261 | .cropper-point.point-se:before { 262 | background-color: #39f; 263 | bottom: -50%; 264 | content: ' '; 265 | display: block; 266 | height: 200%; 267 | opacity: 0; 268 | position: absolute; 269 | right: -50%; 270 | width: 200%; 271 | } 272 | 273 | .cropper-invisible { 274 | opacity: 0; 275 | } 276 | 277 | .cropper-bg { 278 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC'); 279 | } 280 | 281 | .cropper-hide { 282 | display: block; 283 | height: 0; 284 | position: absolute; 285 | width: 0; 286 | } 287 | 288 | .cropper-hidden { 289 | display: none !important; 290 | } 291 | 292 | .cropper-move { 293 | cursor: move; 294 | } 295 | 296 | .cropper-crop { 297 | cursor: crosshair; 298 | } 299 | 300 | .cropper-disabled .cropper-drag-box, 301 | .cropper-disabled .cropper-face, 302 | .cropper-disabled .cropper-line, 303 | .cropper-disabled .cropper-point { 304 | cursor: not-allowed; 305 | } 306 | 307 | /* customer */ 308 | #ccw_cropprt_out { 309 | color: beige; 310 | display: table; 311 | width: 100%; 312 | text-align: center; 313 | background:black; 314 | display: none; 315 | } 316 | .ccw_cropper_container { 317 | width: 100%; 318 | display:table-cell; 319 | vertical-align:middle; 320 | text-align:center; 321 | } 322 | .ccw_cropper_image { 323 | width: 100%; 324 | } 325 | .ccw_cropper_confirm, .ccw_cropper_cancel { 326 | color: aliceblue; 327 | position: fixed; 328 | border: 1px solid white; 329 | border-radius: 5px; 330 | bottom: 3%; 331 | padding: 6px 10px; 332 | } 333 | .ccw_cropper_confirm { 334 | left: 5%; 335 | } 336 | .ccw_cropper_cancel { 337 | right: 5%; 338 | } 339 | .cc_disScroll { 340 | position: fixed; 341 | width: 100%; 342 | } 343 | -------------------------------------------------------------------------------- /src/css/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } -------------------------------------------------------------------------------- /src/html/compress.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 21 | 22 | 23 | 24 |
25 |

图片压缩Demo

26 | 首页 27 |
28 |
29 | 30 | 34 |
压缩等级:(数值越小图片质量越小)
35 |
36 |
37 | 38 |
39 |
40 | 41 |
42 |
43 | 44 |
45 | 46 | 47 |
48 | 49 | 50 | 51 |
52 | 53 | 54 |
55 |
56 | 57 | 58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 |
66 |
    67 | 68 |
69 |
70 | 71 |
72 | 73 | 74 | 152 | 153 | -------------------------------------------------------------------------------- /src/html/cropper.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | web图片工具 9 | 10 | 11 | 57 | 58 | 59 | 60 |
61 |

图片裁剪Demo

62 | 首页 63 |
64 |
65 | 70 |
71 | 下载图片 72 | 73 | 74 | 75 | 76 | 78 | 79 | 119 | 120 | -------------------------------------------------------------------------------- /src/html/gifmaker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 21 | 22 | 23 | 24 |
25 |

GIF制作

26 | 首页 27 |
28 | 29 |
30 | iphone点击右上角选择在Safari中打开 31 | 32 | 38 | 39 |
40 | 43 | 46 |
47 |
48 | 49 |
50 |
51 | 52 |
53 |
54 | 55 |
56 |
57 | 58 |
59 | 60 | 61 |
62 | 63 | 64 | 65 | 154 | 155 | -------------------------------------------------------------------------------- /src/html/watermark.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | 17 | 18 | 19 |
20 |

图片水印Demo

21 | 首页 22 |
23 | 24 |
25 | 29 | 30 |
31 | 34 | 35 |
36 |
37 | 40 | 41 |
42 |
打水印
43 | 44 |
45 | 46 | 47 | 87 | 88 | -------------------------------------------------------------------------------- /src/image/wjz/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/10.jpg -------------------------------------------------------------------------------- /src/image/wjz/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/11.jpg -------------------------------------------------------------------------------- /src/image/wjz/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/12.jpg -------------------------------------------------------------------------------- /src/image/wjz/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/13.jpg -------------------------------------------------------------------------------- /src/image/wjz/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/14.jpg -------------------------------------------------------------------------------- /src/image/wjz/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/15.jpg -------------------------------------------------------------------------------- /src/image/wjz/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/16.jpg -------------------------------------------------------------------------------- /src/image/wjz/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/17.jpg -------------------------------------------------------------------------------- /src/image/wjz/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/18.jpg -------------------------------------------------------------------------------- /src/image/wjz/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/19.jpg -------------------------------------------------------------------------------- /src/image/wjz/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/20.jpg -------------------------------------------------------------------------------- /src/image/wjz/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/21.jpg -------------------------------------------------------------------------------- /src/image/wjz/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/22.jpg -------------------------------------------------------------------------------- /src/image/wjz/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/23.jpg -------------------------------------------------------------------------------- /src/image/wjz/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/24.jpg -------------------------------------------------------------------------------- /src/image/wjz/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/25.jpg -------------------------------------------------------------------------------- /src/image/wjz/26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/26.jpg -------------------------------------------------------------------------------- /src/image/wjz/27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/27.jpg -------------------------------------------------------------------------------- /src/image/wjz/28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/28.jpg -------------------------------------------------------------------------------- /src/image/wjz/29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/29.jpg -------------------------------------------------------------------------------- /src/image/wjz/30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/30.jpg -------------------------------------------------------------------------------- /src/image/wjz/31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/31.jpg -------------------------------------------------------------------------------- /src/image/wjz/32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/32.jpg -------------------------------------------------------------------------------- /src/image/wjz/33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/33.jpg -------------------------------------------------------------------------------- /src/image/wjz/34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/34.jpg -------------------------------------------------------------------------------- /src/image/wjz/35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/35.jpg -------------------------------------------------------------------------------- /src/image/wjz/36.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/36.jpg -------------------------------------------------------------------------------- /src/image/wjz/37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/37.jpg -------------------------------------------------------------------------------- /src/image/wjz/38.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/38.jpg -------------------------------------------------------------------------------- /src/image/wjz/39.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/39.jpg -------------------------------------------------------------------------------- /src/image/wjz/40.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/40.jpg -------------------------------------------------------------------------------- /src/image/wjz/41.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/41.jpg -------------------------------------------------------------------------------- /src/image/wjz/42.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/42.jpg -------------------------------------------------------------------------------- /src/image/wjz/43.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/43.jpg -------------------------------------------------------------------------------- /src/image/wjz/44.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/44.jpg -------------------------------------------------------------------------------- /src/image/wjz/45.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/45.jpg -------------------------------------------------------------------------------- /src/image/wjz/46.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/46.jpg -------------------------------------------------------------------------------- /src/image/wjz/47.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/47.jpg -------------------------------------------------------------------------------- /src/image/wjz/48.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/48.jpg -------------------------------------------------------------------------------- /src/image/wjz/49.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/49.jpg -------------------------------------------------------------------------------- /src/image/wjz/50.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/50.jpg -------------------------------------------------------------------------------- /src/image/wjz/51.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/51.jpg -------------------------------------------------------------------------------- /src/image/wjz/52.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/52.jpg -------------------------------------------------------------------------------- /src/image/wjz/53.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/53.jpg -------------------------------------------------------------------------------- /src/image/wjz/54.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/54.jpg -------------------------------------------------------------------------------- /src/image/wjz/55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/55.jpg -------------------------------------------------------------------------------- /src/image/wjz/56.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/56.jpg -------------------------------------------------------------------------------- /src/image/wjz/57.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/57.jpg -------------------------------------------------------------------------------- /src/image/wjz/58.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/58.jpg -------------------------------------------------------------------------------- /src/image/wjz/59.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/59.jpg -------------------------------------------------------------------------------- /src/image/wjz/60.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/60.jpg -------------------------------------------------------------------------------- /src/image/wjz/61.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/61.jpg -------------------------------------------------------------------------------- /src/image/wjz/62.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/62.jpg -------------------------------------------------------------------------------- /src/image/wjz/63.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/63.jpg -------------------------------------------------------------------------------- /src/image/wjz/64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/64.jpg -------------------------------------------------------------------------------- /src/image/wjz/65.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/65.jpg -------------------------------------------------------------------------------- /src/image/wjz/66.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/66.jpg -------------------------------------------------------------------------------- /src/image/wjz/67.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/67.jpg -------------------------------------------------------------------------------- /src/image/wjz/68.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/68.jpg -------------------------------------------------------------------------------- /src/image/wjz/69.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/69.jpg -------------------------------------------------------------------------------- /src/image/wjz/70.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/70.jpg -------------------------------------------------------------------------------- /src/image/wjz/71.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/71.jpg -------------------------------------------------------------------------------- /src/image/wjz/72.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/72.jpg -------------------------------------------------------------------------------- /src/image/wjz/73.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/73.jpg -------------------------------------------------------------------------------- /src/image/wjz/74.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/74.jpg -------------------------------------------------------------------------------- /src/image/wjz/75.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/75.jpg -------------------------------------------------------------------------------- /src/image/wjz/76.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/76.jpg -------------------------------------------------------------------------------- /src/image/wjz/77.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/77.jpg -------------------------------------------------------------------------------- /src/image/wjz/78.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/78.jpg -------------------------------------------------------------------------------- /src/image/wjz/79.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/79.jpg -------------------------------------------------------------------------------- /src/image/wjz/80.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/80.jpg -------------------------------------------------------------------------------- /src/image/wjz/81.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/81.jpg -------------------------------------------------------------------------------- /src/image/wjz/82.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/82.jpg -------------------------------------------------------------------------------- /src/image/wjz/83.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/83.jpg -------------------------------------------------------------------------------- /src/image/wjz/84.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/84.jpg -------------------------------------------------------------------------------- /src/image/wjz/85.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/85.jpg -------------------------------------------------------------------------------- /src/image/wjz/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz/9.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/10.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/11.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/12.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/13.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/14.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/15.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/16.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/17.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/18.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/19.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/20.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/21.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/22.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/23.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/24.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/25.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/26.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/27.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/28.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/29.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/30.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/31.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/32.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/33.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/34.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/35.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/36.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/36.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/37.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/38.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/38.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/39.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/39.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/40.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/40.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/41.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/41.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/42.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/42.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/43.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/43.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/44.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/44.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/45.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/45.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/46.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/46.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/47.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/47.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/48.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/48.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/49.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/49.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/50.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/50.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/51.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/51.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/52.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/52.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/53.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/53.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/54.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/54.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/55.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/56.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/56.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/57.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/57.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/58.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/58.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/59.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/59.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/60.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/60.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/61.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/61.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/62.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/62.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/63.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/63.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/64.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/65.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/65.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/66.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/66.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/67.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/67.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/68.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/68.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/69.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/69.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/70.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/70.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/71.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/71.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/72.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/72.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/73.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/73.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/74.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/74.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/75.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/75.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/76.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/76.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/77.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/77.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/78.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/78.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/79.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/79.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/80.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/80.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/81.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/81.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/82.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/82.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/83.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/83.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/84.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/84.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/85.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/85.jpg -------------------------------------------------------------------------------- /src/image/wjz_min/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palxiao/ccImg_tool/3a004db1dcb6992a621a76e4c98e34bf9268ec9c/src/image/wjz_min/9.jpg -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | web图片工具 9 | 10 | 17 | 18 | 19 | 20 | 图片裁剪插件 21 | 图片压缩 22 | 图片加水印 23 | GIF制作 24 | 图片滤色 25 | 26 | 27 | 30 | 31 | -------------------------------------------------------------------------------- /src/js/app/base64_blob.js: -------------------------------------------------------------------------------- 1 | define(function (dataurl) { 2 | 'use strict'; 3 | var base642blob = function (dataurl) { 4 | var arr = dataurl.split(','), 5 | mime = arr[0].match(/:(.*?);/)[1], 6 | bstr = atob(arr[1]), 7 | n = bstr.length, 8 | u8arr = new Uint8Array(n); 9 | while (n--) { 10 | u8arr[n] = bstr.charCodeAt(n); 11 | } 12 | return new Blob([u8arr], { 13 | type: mime 14 | }); 15 | } 16 | return base642blob 17 | }); -------------------------------------------------------------------------------- /src/js/app/compress.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'isArray', 3 | 'base64toBlob', 4 | 'rotateDraw' 5 | ], function (isArray, base64toBlob, imgRotate) { 6 | 'use strict'; 7 | var params 8 | var Compress = function (obj) { 9 | return new Compress.prototype.init(obj) 10 | } 11 | Compress.prototype = { 12 | init: function (obj) { 13 | params = obj 14 | switch (isArray(params.src)) { 15 | case true: 16 | var dispose = this.dispose 17 | var a = 0 18 | var result = [] 19 | var blob_result = [] 20 | thumb() 21 | function thumb() { 22 | if (params.src[a]) { 23 | dispose(params.src[a], function (base64) { 24 | a++ 25 | result.push(base64) 26 | thumb() 27 | }, function (blob) { 28 | blob_result.push(blob) 29 | }) 30 | } else { 31 | if (params.ok) params.ok(result) 32 | setTimeout(function () { 33 | if (params.toBlob) params.toBlob(blob_result) 34 | }, 300); 35 | } 36 | } 37 | break; 38 | case false: 39 | this.dispose(params.src, function (base64) { 40 | if (params.ok) params.ok(base64) 41 | }, function (blob) { 42 | if (params.toBlob) params.toBlob(blob) 43 | }) 44 | break; 45 | } 46 | }, 47 | dispose: function (path, result, toBlob) { 48 | var img = new Image(); 49 | img.addEventListener("load", function () { 50 | var that = this; 51 | var w = that.width, 52 | h = that.height, 53 | scale = w / h; 54 | w = params.width || w; 55 | h = params.height || (w / scale); 56 | var scaleCount = Math.round(0.0014 * w); 57 | if (scaleCount >= 1 && !params.original) { 58 | if (scaleCount <= 2) { 59 | w = parseInt(w / 1.5); 60 | h = parseInt(h / 1.5); 61 | } else if (scaleCount == 3) { 62 | w = parseInt(w / 2); 63 | h = parseInt(h / 2); 64 | } else { 65 | w = parseInt(w / (scaleCount - 1.5)); 66 | h = parseInt(h / (scaleCount - 1.5)); 67 | } 68 | } 69 | var quality = 0.5; // 默认图片质量 70 | var canvas = document.createElement('canvas'); 71 | var ctx = canvas.getContext('2d'); 72 | var anw = document.createAttribute("width"); 73 | anw.nodeValue = w; 74 | var anh = document.createAttribute("height"); 75 | anh.nodeValue = h; 76 | canvas.setAttributeNode(anw); 77 | canvas.setAttributeNode(anh); 78 | imgRotate(that, canvas, { 79 | width: w, 80 | height: h 81 | }) 82 | if (params.quality && params.quality <= 99 && params.quality > 0) { 83 | quality = params.quality; 84 | } 85 | 86 | var base64 = canvas.toDataURL('image/jpeg', quality * 0.01); 87 | if (result) result(base64) 88 | if (toBlob) { 89 | try { 90 | canvas.toBlob(function (blob) { 91 | toBlob(blob); 92 | }) 93 | } catch (error) { 94 | toBlob(base64toBlob(base64)) 95 | } 96 | } 97 | }, false); 98 | img.crossOrigin = 'Anonymous'; 99 | img.src = path; 100 | } 101 | } 102 | Compress.prototype.init.prototype = Compress.prototype 103 | return Compress 104 | }); -------------------------------------------------------------------------------- /src/js/app/cropper.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'cropper', 3 | 'base64toBlob' 4 | ], function (Cropper, base64toBlob) { 5 | 'use strict'; 6 | var cropper, result, blobResult; 7 | var rootElement = document.scrollingElement || document.body; 8 | var scrollTop = rootElement.scrollTop; 9 | var myCropper = function (src) { 10 | return new myCropper.prototype.init(src) 11 | } 12 | myCropper.prototype = { 13 | init: function (src) { 14 | if (!src) return 15 | this.creat() 16 | this.disScroll() 17 | this.image = document.querySelector('#ccw_cropper_image'); 18 | this.image.src = src 19 | }, 20 | open: function (obj) { 21 | cropper = new Cropper(this.image, { 22 | aspectRatio: obj.aspectRatio || '', // 16/9 4/3 2/3 1/1 23 | ready: function () { 24 | this.cropper.setDragMode('move') 25 | if (obj.ok) result = obj.ok 26 | if (obj.toBlob) blobResult = obj.toBlob 27 | } 28 | }); 29 | this.model('show') 30 | }, 31 | crop: function () { 32 | var can = cropper.getCroppedCanvas(); 33 | var base64 = can.toDataURL('image/jpeg'); 34 | result(base64); 35 | try { 36 | can.toBlob(function (blob) { 37 | blobResult(blob) 38 | }) 39 | } catch (error) { 40 | blobResult(base64toBlob(can)) 41 | } finally { 42 | this.model('hide', true) 43 | } 44 | }, 45 | model: function (type, flag) { 46 | if (type === 'show') { 47 | document.getElementById('ccw_cropprt_out').style.display = 'table' 48 | } else if ('hide') { 49 | document.getElementById('ccw_cropprt_out').style.display = 'none' 50 | if (cropper) { 51 | cropper.destroy(); 52 | cropper = null; 53 | } 54 | if (!flag) result() 55 | this.returnScroll(); 56 | } 57 | }, 58 | creat: function () { 59 | var html_fragment 60 | html_fragment = '
' + 61 | '
' + 62 | '
' + 63 | '
确 认
' + 64 | '
取 消
' + 65 | '
' + 66 | '
' 67 | if (document.querySelector("#ccw_cropprt_out")) return; 68 | document.body.insertAdjacentHTML('afterbegin', html_fragment); 69 | var wHeight = document.documentElement.clientHeight; 70 | document.getElementById("ccw_cropprt_out").style.height = wHeight + "px"; 71 | }, 72 | disScroll: function () { 73 | document.body.classList.add('cc_disScroll'); 74 | document.body.style.top = -scrollTop + 'px'; 75 | }, 76 | returnScroll: function () { 77 | document.body.classList.remove('cc_disScroll'); 78 | rootElement.scrollTop = scrollTop; 79 | } 80 | } 81 | 82 | myCropper.prototype.init.prototype = myCropper.prototype 83 | return myCropper 84 | }); -------------------------------------------------------------------------------- /src/js/app/get_length.js: -------------------------------------------------------------------------------- 1 | define(function (require, factory) { 2 | 'use strict'; 3 | var getLength = function (val) { 4 | var str = new String(val); 5 | var bytesCount = 0; 6 | for (var i = 0, n = str.length; i < n; i++) { 7 | var c = str.charCodeAt(i); 8 | if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) { 9 | bytesCount += 1; 10 | } else { 11 | bytesCount += 2; 12 | } 13 | } 14 | return parseInt((bytesCount / 2).toFixed(0)); 15 | } 16 | return getLength 17 | }); -------------------------------------------------------------------------------- /src/js/app/is_array.js: -------------------------------------------------------------------------------- 1 | define(function () { 2 | 'use strict'; 3 | var isArray = function (value) { 4 | if (typeof Array.isArray === "function") { 5 | return Array.isArray(value) 6 | } else { 7 | return Object.prototype.toString.call(value) === "[object Array]" 8 | } 9 | } 10 | return isArray 11 | }); -------------------------------------------------------------------------------- /src/js/app/rotate_draw.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'exif' 3 | ], function () { 4 | 'use strict'; 5 | var rotateImg = function (img, canvas, custom, untiles) { 6 | var Orientation; 7 | EXIF.getData(img, function () { 8 | EXIF.getAllTags(this); 9 | Orientation = EXIF.getTag(this, 'Orientation'); 10 | }); 11 | var ctx = canvas.getContext("2d"); 12 | 13 | if (custom) { 14 | img.width = custom.width 15 | img.height = custom.height 16 | } 17 | switch (Orientation) { 18 | case 6: 19 | canvas.width = img.height 20 | canvas.height = img.width 21 | ctx.save() 22 | ctx.rotate(Math.PI / 2); 23 | if (!untiles) { 24 | tiles(canvas, ctx, img, function (istiles) { 25 | if (!istiles) { 26 | ctx.drawImage(img, 0, -img.height, canvas.height, canvas.width) 27 | } 28 | ctx.restore() 29 | }) 30 | } else { 31 | ctx.drawImage(img, 0, -img.height, canvas.height, canvas.width) 32 | ctx.restore() 33 | } 34 | break; 35 | case 3: 36 | ctx.save() 37 | ctx.rotate(Math.PI); 38 | if (!untiles) { 39 | tiles(canvas, ctx, img, function (istiles) { 40 | if (!istiles) { 41 | ctx.drawImage(img, 0, 0, -img.width, -img.height); 42 | } 43 | ctx.restore() 44 | }) 45 | } else { 46 | ctx.drawImage(img, 0, 0, -img.width, -img.height); 47 | ctx.restore() 48 | } 49 | // ctx.drawImage(img, 0, 0, -img.width, -img.height); 50 | // ctx.restore() 51 | break; 52 | case 8: 53 | canvas.width = img.height; 54 | canvas.height = img.width; 55 | ctx.save() 56 | ctx.rotate(Math.PI * 3 / 2); 57 | if (!untiles) { 58 | tiles(canvas, ctx, img, function (istiles) { 59 | if (!istiles) { 60 | ctx.drawImage(img, 0, 0, -img.width, img.height); 61 | } 62 | ctx.restore() 63 | }) 64 | } else { 65 | ctx.drawImage(img, 0, 0, -img.width, img.height); 66 | ctx.restore() 67 | } 68 | // ctx.drawImage(img, 0, 0, -img.width, img.height); 69 | // ctx.restore() 70 | break; 71 | default: 72 | if (!untiles) { 73 | tiles(canvas, ctx, img, function (istiles) { 74 | if (!istiles) { 75 | ctx.drawImage(img, 0, 0, img.width, img.height); 76 | } 77 | }) 78 | } else { 79 | ctx.drawImage(img, 0, 0, img.width, img.height); 80 | } 81 | break; 82 | } 83 | } 84 | var tiles = function (canvas, ctx, img, isDone) { 85 | var width = img.width; 86 | var height = img.height; 87 | 88 | //如果图片大于四百万像素,计算压缩比并将大小压至400万以下 89 | var ratio; 90 | if ((ratio = width * height / 4000000) > 1) { 91 | ratio = Math.sqrt(ratio); 92 | width /= ratio; 93 | height /= ratio; 94 | } else { 95 | ratio = 1; 96 | } 97 | 98 | //如果图片像素大于100万则使用瓦片绘制 99 | var count; 100 | if ((count = width * height / 1000000) > 1) { 101 | canvas.width = width 102 | canvas.height = height 103 | count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片 104 | //计算每块瓦片的宽和高 105 | var nw = ~~(width / count); 106 | var nh = ~~(height / count); 107 | 108 | var tCanvas = document.createElement('canvas') 109 | tCanvas.width = nw; 110 | tCanvas.height = nh; 111 | var tctx = tCanvas.getContext('2d') 112 | 113 | for (var i = 0; i < count; i++) { 114 | for (var j = 0; j < count; j++) { 115 | tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh); 116 | ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh); 117 | } 118 | } 119 | isDone(true) 120 | rotateImg(img, canvas, { 121 | width: width, 122 | height: height 123 | }, true) 124 | } else { 125 | isDone() 126 | } 127 | } 128 | return rotateImg 129 | }); -------------------------------------------------------------------------------- /src/js/app/watermark.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'getLength', 3 | 'rotateDraw' 4 | ], function (getLength, imgRotate) { 5 | // 'use strict'; 6 | var Watermark = function (obj) { 7 | return new Watermark.prototype.init(obj) 8 | } 9 | Watermark.prototype = { 10 | init: function (obj) { 11 | if (!obj) return 12 | if (typeof obj == 'object') { 13 | this.add(obj) 14 | } else { 15 | this.src = obj 16 | } 17 | }, 18 | add: function (obj) { 19 | var img = new Image(); 20 | img.addEventListener("load", function () { 21 | var canvas = document.createElement("canvas"); 22 | canvas.width = this.width; 23 | canvas.height = this.height; 24 | var ctx = canvas.getContext("2d"); 25 | var txt = obj.text || obj; 26 | 27 | imgRotate(img, canvas); 28 | 29 | var fontSize = obj.fontSize >= 1 ? obj.fontSize : parseInt(canvas.height / 14) 30 | ctx.font = fontSize + "px sans-serif"; 31 | ctx.fillStyle = "#FFFFFF"; 32 | ctx.fillText(txt, canvas.width - ((getLength(txt) + 0.5) * fontSize), canvas.height - fontSize / 2); 33 | var base64 = canvas.toDataURL('image/jpeg'); 34 | if (obj.ok) obj.ok(base64) 35 | }, false); 36 | img.crossOrigin = 'Anonymous'; 37 | obj.src ? img.src = obj.src : img.src = this.src 38 | } 39 | } 40 | Watermark.prototype.init.prototype = Watermark.prototype 41 | return Watermark 42 | }); -------------------------------------------------------------------------------- /src/js/lib/exif.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var debug = false; 4 | 5 | var root = this; 6 | 7 | var EXIF = function(obj) { 8 | if (obj instanceof EXIF) return obj; 9 | if (!(this instanceof EXIF)) return new EXIF(obj); 10 | this.EXIFwrapped = obj; 11 | }; 12 | 13 | if (typeof exports !== 'undefined') { 14 | if (typeof module !== 'undefined' && module.exports) { 15 | exports = module.exports = EXIF; 16 | } 17 | exports.EXIF = EXIF; 18 | } else { 19 | root.EXIF = EXIF; 20 | } 21 | 22 | var ExifTags = EXIF.Tags = { 23 | 24 | // version tags 25 | 0x9000 : "ExifVersion", // EXIF version 26 | 0xA000 : "FlashpixVersion", // Flashpix format version 27 | 28 | // colorspace tags 29 | 0xA001 : "ColorSpace", // Color space information tag 30 | 31 | // image configuration 32 | 0xA002 : "PixelXDimension", // Valid width of meaningful image 33 | 0xA003 : "PixelYDimension", // Valid height of meaningful image 34 | 0x9101 : "ComponentsConfiguration", // Information about channels 35 | 0x9102 : "CompressedBitsPerPixel", // Compressed bits per pixel 36 | 37 | // user information 38 | 0x927C : "MakerNote", // Any desired information written by the manufacturer 39 | 0x9286 : "UserComment", // Comments by user 40 | 41 | // related file 42 | 0xA004 : "RelatedSoundFile", // Name of related sound file 43 | 44 | // date and time 45 | 0x9003 : "DateTimeOriginal", // Date and time when the original image was generated 46 | 0x9004 : "DateTimeDigitized", // Date and time when the image was stored digitally 47 | 0x9290 : "SubsecTime", // Fractions of seconds for DateTime 48 | 0x9291 : "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal 49 | 0x9292 : "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized 50 | 51 | // picture-taking conditions 52 | 0x829A : "ExposureTime", // Exposure time (in seconds) 53 | 0x829D : "FNumber", // F number 54 | 0x8822 : "ExposureProgram", // Exposure program 55 | 0x8824 : "SpectralSensitivity", // Spectral sensitivity 56 | 0x8827 : "ISOSpeedRatings", // ISO speed rating 57 | 0x8828 : "OECF", // Optoelectric conversion factor 58 | 0x9201 : "ShutterSpeedValue", // Shutter speed 59 | 0x9202 : "ApertureValue", // Lens aperture 60 | 0x9203 : "BrightnessValue", // Value of brightness 61 | 0x9204 : "ExposureBias", // Exposure bias 62 | 0x9205 : "MaxApertureValue", // Smallest F number of lens 63 | 0x9206 : "SubjectDistance", // Distance to subject in meters 64 | 0x9207 : "MeteringMode", // Metering mode 65 | 0x9208 : "LightSource", // Kind of light source 66 | 0x9209 : "Flash", // Flash status 67 | 0x9214 : "SubjectArea", // Location and area of main subject 68 | 0x920A : "FocalLength", // Focal length of the lens in mm 69 | 0xA20B : "FlashEnergy", // Strobe energy in BCPS 70 | 0xA20C : "SpatialFrequencyResponse", // 71 | 0xA20E : "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit 72 | 0xA20F : "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit 73 | 0xA210 : "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution 74 | 0xA214 : "SubjectLocation", // Location of subject in image 75 | 0xA215 : "ExposureIndex", // Exposure index selected on camera 76 | 0xA217 : "SensingMethod", // Image sensor type 77 | 0xA300 : "FileSource", // Image source (3 == DSC) 78 | 0xA301 : "SceneType", // Scene type (1 == directly photographed) 79 | 0xA302 : "CFAPattern", // Color filter array geometric pattern 80 | 0xA401 : "CustomRendered", // Special processing 81 | 0xA402 : "ExposureMode", // Exposure mode 82 | 0xA403 : "WhiteBalance", // 1 = auto white balance, 2 = manual 83 | 0xA404 : "DigitalZoomRation", // Digital zoom ratio 84 | 0xA405 : "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm) 85 | 0xA406 : "SceneCaptureType", // Type of scene 86 | 0xA407 : "GainControl", // Degree of overall image gain adjustment 87 | 0xA408 : "Contrast", // Direction of contrast processing applied by camera 88 | 0xA409 : "Saturation", // Direction of saturation processing applied by camera 89 | 0xA40A : "Sharpness", // Direction of sharpness processing applied by camera 90 | 0xA40B : "DeviceSettingDescription", // 91 | 0xA40C : "SubjectDistanceRange", // Distance to subject 92 | 93 | // other tags 94 | 0xA005 : "InteroperabilityIFDPointer", 95 | 0xA420 : "ImageUniqueID" // Identifier assigned uniquely to each image 96 | }; 97 | 98 | var TiffTags = EXIF.TiffTags = { 99 | 0x0100 : "ImageWidth", 100 | 0x0101 : "ImageHeight", 101 | 0x8769 : "ExifIFDPointer", 102 | 0x8825 : "GPSInfoIFDPointer", 103 | 0xA005 : "InteroperabilityIFDPointer", 104 | 0x0102 : "BitsPerSample", 105 | 0x0103 : "Compression", 106 | 0x0106 : "PhotometricInterpretation", 107 | 0x0112 : "Orientation", 108 | 0x0115 : "SamplesPerPixel", 109 | 0x011C : "PlanarConfiguration", 110 | 0x0212 : "YCbCrSubSampling", 111 | 0x0213 : "YCbCrPositioning", 112 | 0x011A : "XResolution", 113 | 0x011B : "YResolution", 114 | 0x0128 : "ResolutionUnit", 115 | 0x0111 : "StripOffsets", 116 | 0x0116 : "RowsPerStrip", 117 | 0x0117 : "StripByteCounts", 118 | 0x0201 : "JPEGInterchangeFormat", 119 | 0x0202 : "JPEGInterchangeFormatLength", 120 | 0x012D : "TransferFunction", 121 | 0x013E : "WhitePoint", 122 | 0x013F : "PrimaryChromaticities", 123 | 0x0211 : "YCbCrCoefficients", 124 | 0x0214 : "ReferenceBlackWhite", 125 | 0x0132 : "DateTime", 126 | 0x010E : "ImageDescription", 127 | 0x010F : "Make", 128 | 0x0110 : "Model", 129 | 0x0131 : "Software", 130 | 0x013B : "Artist", 131 | 0x8298 : "Copyright" 132 | }; 133 | 134 | var GPSTags = EXIF.GPSTags = { 135 | 0x0000 : "GPSVersionID", 136 | 0x0001 : "GPSLatitudeRef", 137 | 0x0002 : "GPSLatitude", 138 | 0x0003 : "GPSLongitudeRef", 139 | 0x0004 : "GPSLongitude", 140 | 0x0005 : "GPSAltitudeRef", 141 | 0x0006 : "GPSAltitude", 142 | 0x0007 : "GPSTimeStamp", 143 | 0x0008 : "GPSSatellites", 144 | 0x0009 : "GPSStatus", 145 | 0x000A : "GPSMeasureMode", 146 | 0x000B : "GPSDOP", 147 | 0x000C : "GPSSpeedRef", 148 | 0x000D : "GPSSpeed", 149 | 0x000E : "GPSTrackRef", 150 | 0x000F : "GPSTrack", 151 | 0x0010 : "GPSImgDirectionRef", 152 | 0x0011 : "GPSImgDirection", 153 | 0x0012 : "GPSMapDatum", 154 | 0x0013 : "GPSDestLatitudeRef", 155 | 0x0014 : "GPSDestLatitude", 156 | 0x0015 : "GPSDestLongitudeRef", 157 | 0x0016 : "GPSDestLongitude", 158 | 0x0017 : "GPSDestBearingRef", 159 | 0x0018 : "GPSDestBearing", 160 | 0x0019 : "GPSDestDistanceRef", 161 | 0x001A : "GPSDestDistance", 162 | 0x001B : "GPSProcessingMethod", 163 | 0x001C : "GPSAreaInformation", 164 | 0x001D : "GPSDateStamp", 165 | 0x001E : "GPSDifferential" 166 | }; 167 | 168 | var StringValues = EXIF.StringValues = { 169 | ExposureProgram : { 170 | 0 : "Not defined", 171 | 1 : "Manual", 172 | 2 : "Normal program", 173 | 3 : "Aperture priority", 174 | 4 : "Shutter priority", 175 | 5 : "Creative program", 176 | 6 : "Action program", 177 | 7 : "Portrait mode", 178 | 8 : "Landscape mode" 179 | }, 180 | MeteringMode : { 181 | 0 : "Unknown", 182 | 1 : "Average", 183 | 2 : "CenterWeightedAverage", 184 | 3 : "Spot", 185 | 4 : "MultiSpot", 186 | 5 : "Pattern", 187 | 6 : "Partial", 188 | 255 : "Other" 189 | }, 190 | LightSource : { 191 | 0 : "Unknown", 192 | 1 : "Daylight", 193 | 2 : "Fluorescent", 194 | 3 : "Tungsten (incandescent light)", 195 | 4 : "Flash", 196 | 9 : "Fine weather", 197 | 10 : "Cloudy weather", 198 | 11 : "Shade", 199 | 12 : "Daylight fluorescent (D 5700 - 7100K)", 200 | 13 : "Day white fluorescent (N 4600 - 5400K)", 201 | 14 : "Cool white fluorescent (W 3900 - 4500K)", 202 | 15 : "White fluorescent (WW 3200 - 3700K)", 203 | 17 : "Standard light A", 204 | 18 : "Standard light B", 205 | 19 : "Standard light C", 206 | 20 : "D55", 207 | 21 : "D65", 208 | 22 : "D75", 209 | 23 : "D50", 210 | 24 : "ISO studio tungsten", 211 | 255 : "Other" 212 | }, 213 | Flash : { 214 | 0x0000 : "Flash did not fire", 215 | 0x0001 : "Flash fired", 216 | 0x0005 : "Strobe return light not detected", 217 | 0x0007 : "Strobe return light detected", 218 | 0x0009 : "Flash fired, compulsory flash mode", 219 | 0x000D : "Flash fired, compulsory flash mode, return light not detected", 220 | 0x000F : "Flash fired, compulsory flash mode, return light detected", 221 | 0x0010 : "Flash did not fire, compulsory flash mode", 222 | 0x0018 : "Flash did not fire, auto mode", 223 | 0x0019 : "Flash fired, auto mode", 224 | 0x001D : "Flash fired, auto mode, return light not detected", 225 | 0x001F : "Flash fired, auto mode, return light detected", 226 | 0x0020 : "No flash function", 227 | 0x0041 : "Flash fired, red-eye reduction mode", 228 | 0x0045 : "Flash fired, red-eye reduction mode, return light not detected", 229 | 0x0047 : "Flash fired, red-eye reduction mode, return light detected", 230 | 0x0049 : "Flash fired, compulsory flash mode, red-eye reduction mode", 231 | 0x004D : "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected", 232 | 0x004F : "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected", 233 | 0x0059 : "Flash fired, auto mode, red-eye reduction mode", 234 | 0x005D : "Flash fired, auto mode, return light not detected, red-eye reduction mode", 235 | 0x005F : "Flash fired, auto mode, return light detected, red-eye reduction mode" 236 | }, 237 | SensingMethod : { 238 | 1 : "Not defined", 239 | 2 : "One-chip color area sensor", 240 | 3 : "Two-chip color area sensor", 241 | 4 : "Three-chip color area sensor", 242 | 5 : "Color sequential area sensor", 243 | 7 : "Trilinear sensor", 244 | 8 : "Color sequential linear sensor" 245 | }, 246 | SceneCaptureType : { 247 | 0 : "Standard", 248 | 1 : "Landscape", 249 | 2 : "Portrait", 250 | 3 : "Night scene" 251 | }, 252 | SceneType : { 253 | 1 : "Directly photographed" 254 | }, 255 | CustomRendered : { 256 | 0 : "Normal process", 257 | 1 : "Custom process" 258 | }, 259 | WhiteBalance : { 260 | 0 : "Auto white balance", 261 | 1 : "Manual white balance" 262 | }, 263 | GainControl : { 264 | 0 : "None", 265 | 1 : "Low gain up", 266 | 2 : "High gain up", 267 | 3 : "Low gain down", 268 | 4 : "High gain down" 269 | }, 270 | Contrast : { 271 | 0 : "Normal", 272 | 1 : "Soft", 273 | 2 : "Hard" 274 | }, 275 | Saturation : { 276 | 0 : "Normal", 277 | 1 : "Low saturation", 278 | 2 : "High saturation" 279 | }, 280 | Sharpness : { 281 | 0 : "Normal", 282 | 1 : "Soft", 283 | 2 : "Hard" 284 | }, 285 | SubjectDistanceRange : { 286 | 0 : "Unknown", 287 | 1 : "Macro", 288 | 2 : "Close view", 289 | 3 : "Distant view" 290 | }, 291 | FileSource : { 292 | 3 : "DSC" 293 | }, 294 | 295 | Components : { 296 | 0 : "", 297 | 1 : "Y", 298 | 2 : "Cb", 299 | 3 : "Cr", 300 | 4 : "R", 301 | 5 : "G", 302 | 6 : "B" 303 | } 304 | }; 305 | 306 | function addEvent(element, event, handler) { 307 | if (element.addEventListener) { 308 | element.addEventListener(event, handler, false); 309 | } else if (element.attachEvent) { 310 | element.attachEvent("on" + event, handler); 311 | } 312 | } 313 | 314 | function imageHasData(img) { 315 | return !!(img.exifdata); 316 | } 317 | 318 | 319 | function base64ToArrayBuffer(base64, contentType) { 320 | contentType = contentType || base64.match(/^data\:([^\;]+)\;base64,/mi)[1] || ''; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg' 321 | base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, ''); 322 | var binary = atob(base64); 323 | var len = binary.length; 324 | var buffer = new ArrayBuffer(len); 325 | var view = new Uint8Array(buffer); 326 | for (var i = 0; i < len; i++) { 327 | view[i] = binary.charCodeAt(i); 328 | } 329 | return buffer; 330 | } 331 | 332 | function objectURLToBlob(url, callback) { 333 | var http = new XMLHttpRequest(); 334 | http.open("GET", url, true); 335 | http.responseType = "blob"; 336 | http.onload = function(e) { 337 | if (this.status == 200 || this.status === 0) { 338 | callback(this.response); 339 | } 340 | }; 341 | http.send(); 342 | } 343 | 344 | function getImageData(img, callback) { 345 | function handleBinaryFile(binFile) { 346 | var data = findEXIFinJPEG(binFile); 347 | var iptcdata = findIPTCinJPEG(binFile); 348 | img.exifdata = data || {}; 349 | img.iptcdata = iptcdata || {}; 350 | if (callback) { 351 | callback.call(img); 352 | } 353 | } 354 | 355 | if (img.src) { 356 | if (/^data\:/i.test(img.src)) { // Data URI 357 | var arrayBuffer = base64ToArrayBuffer(img.src); 358 | handleBinaryFile(arrayBuffer); 359 | 360 | } else if (/^blob\:/i.test(img.src)) { // Object URL 361 | var fileReader = new FileReader(); 362 | fileReader.onload = function(e) { 363 | handleBinaryFile(e.target.result); 364 | }; 365 | objectURLToBlob(img.src, function (blob) { 366 | fileReader.readAsArrayBuffer(blob); 367 | }); 368 | } else { 369 | var http = new XMLHttpRequest(); 370 | http.onload = function() { 371 | if (this.status == 200 || this.status === 0) { 372 | handleBinaryFile(http.response); 373 | } else { 374 | throw "Could not load image"; 375 | } 376 | http = null; 377 | }; 378 | http.open("GET", img.src, true); 379 | http.responseType = "arraybuffer"; 380 | http.send(null); 381 | } 382 | } else if (window.FileReader && (img instanceof window.Blob || img instanceof window.File)) { 383 | var fileReader = new FileReader(); 384 | fileReader.onload = function(e) { 385 | if (debug) console.log("Got file of length " + e.target.result.byteLength); 386 | handleBinaryFile(e.target.result); 387 | }; 388 | 389 | fileReader.readAsArrayBuffer(img); 390 | } 391 | } 392 | 393 | function findEXIFinJPEG(file) { 394 | var dataView = new DataView(file); 395 | 396 | if (debug) console.log("Got file of length " + file.byteLength); 397 | if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { 398 | if (debug) console.log("Not a valid JPEG"); 399 | return false; // not a valid jpeg 400 | } 401 | 402 | var offset = 2, 403 | length = file.byteLength, 404 | marker; 405 | 406 | while (offset < length) { 407 | if (dataView.getUint8(offset) != 0xFF) { 408 | if (debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(offset)); 409 | return false; // not a valid marker, something is wrong 410 | } 411 | 412 | marker = dataView.getUint8(offset + 1); 413 | if (debug) console.log(marker); 414 | 415 | // we could implement handling for other markers here, 416 | // but we're only looking for 0xFFE1 for EXIF data 417 | 418 | if (marker == 225) { 419 | if (debug) console.log("Found 0xFFE1 marker"); 420 | 421 | return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2); 422 | 423 | // offset += 2 + file.getShortAt(offset+2, true); 424 | 425 | } else { 426 | offset += 2 + dataView.getUint16(offset+2); 427 | } 428 | 429 | } 430 | 431 | } 432 | 433 | function findIPTCinJPEG(file) { 434 | var dataView = new DataView(file); 435 | 436 | if (debug) console.log("Got file of length " + file.byteLength); 437 | if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { 438 | if (debug) console.log("Not a valid JPEG"); 439 | return false; // not a valid jpeg 440 | } 441 | 442 | var offset = 2, 443 | length = file.byteLength; 444 | 445 | 446 | var isFieldSegmentStart = function(dataView, offset){ 447 | return ( 448 | dataView.getUint8(offset) === 0x38 && 449 | dataView.getUint8(offset+1) === 0x42 && 450 | dataView.getUint8(offset+2) === 0x49 && 451 | dataView.getUint8(offset+3) === 0x4D && 452 | dataView.getUint8(offset+4) === 0x04 && 453 | dataView.getUint8(offset+5) === 0x04 454 | ); 455 | }; 456 | 457 | while (offset < length) { 458 | 459 | if ( isFieldSegmentStart(dataView, offset )){ 460 | 461 | // Get the length of the name header (which is padded to an even number of bytes) 462 | var nameHeaderLength = dataView.getUint8(offset+7); 463 | if(nameHeaderLength % 2 !== 0) nameHeaderLength += 1; 464 | // Check for pre photoshop 6 format 465 | if(nameHeaderLength === 0) { 466 | // Always 4 467 | nameHeaderLength = 4; 468 | } 469 | 470 | var startOffset = offset + 8 + nameHeaderLength; 471 | var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength); 472 | 473 | return readIPTCData(file, startOffset, sectionLength); 474 | 475 | break; 476 | 477 | } 478 | 479 | 480 | // Not the marker, continue searching 481 | offset++; 482 | 483 | } 484 | 485 | } 486 | var IptcFieldMap = { 487 | 0x78 : 'caption', 488 | 0x6E : 'credit', 489 | 0x19 : 'keywords', 490 | 0x37 : 'dateCreated', 491 | 0x50 : 'byline', 492 | 0x55 : 'bylineTitle', 493 | 0x7A : 'captionWriter', 494 | 0x69 : 'headline', 495 | 0x74 : 'copyright', 496 | 0x0F : 'category' 497 | }; 498 | function readIPTCData(file, startOffset, sectionLength){ 499 | var dataView = new DataView(file); 500 | var data = {}; 501 | var fieldValue, fieldName, dataSize, segmentType, segmentSize; 502 | var segmentStartPos = startOffset; 503 | while(segmentStartPos < startOffset+sectionLength) { 504 | if(dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos+1) === 0x02){ 505 | segmentType = dataView.getUint8(segmentStartPos+2); 506 | if(segmentType in IptcFieldMap) { 507 | dataSize = dataView.getInt16(segmentStartPos+3); 508 | segmentSize = dataSize + 5; 509 | fieldName = IptcFieldMap[segmentType]; 510 | fieldValue = getStringFromDB(dataView, segmentStartPos+5, dataSize); 511 | // Check if we already stored a value with this name 512 | if(data.hasOwnProperty(fieldName)) { 513 | // Value already stored with this name, create multivalue field 514 | if(data[fieldName] instanceof Array) { 515 | data[fieldName].push(fieldValue); 516 | } 517 | else { 518 | data[fieldName] = [data[fieldName], fieldValue]; 519 | } 520 | } 521 | else { 522 | data[fieldName] = fieldValue; 523 | } 524 | } 525 | 526 | } 527 | segmentStartPos++; 528 | } 529 | return data; 530 | } 531 | 532 | 533 | 534 | function readTags(file, tiffStart, dirStart, strings, bigEnd) { 535 | var entries = file.getUint16(dirStart, !bigEnd), 536 | tags = {}, 537 | entryOffset, tag, 538 | i; 539 | 540 | for (i=0;i 4 ? valueOffset : (entryOffset + 8); 565 | vals = []; 566 | for (n=0;n 4 ? valueOffset : (entryOffset + 8); 574 | return getStringFromDB(file, offset, numValues-1); 575 | 576 | case 3: // short, 16 bit int 577 | if (numValues == 1) { 578 | return file.getUint16(entryOffset + 8, !bigEnd); 579 | } else { 580 | offset = numValues > 2 ? valueOffset : (entryOffset + 8); 581 | vals = []; 582 | for (n=0;n0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1)}if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},{}],2:[function(require,module,exports){var UA,browser,mode,platform,ua;ua=navigator.userAgent.toLowerCase();platform=navigator.platform.toLowerCase();UA=ua.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0];mode=UA[1]==="ie"&&document.documentMode;browser={name:UA[1]==="version"?UA[3]:UA[1],version:mode||parseFloat(UA[1]==="opera"&&UA[4]?UA[4]:UA[2]),platform:{name:ua.match(/ip(?:ad|od|hone)/)?"ios":(ua.match(/(?:webos|android)/)||platform.match(/mac|win|linux/)||["other"])[0]}};browser[browser.name]=true;browser[browser.name+parseInt(browser.version,10)]=true;browser.platform[browser.platform.name]=true;module.exports=browser},{}],3:[function(require,module,exports){var EventEmitter,GIF,browser,extend=function(child,parent){for(var key in parent){if(hasProp.call(parent,key))child[key]=parent[key]}function ctor(){this.constructor=child}ctor.prototype=parent.prototype;child.prototype=new ctor;child.__super__=parent.prototype;return child},hasProp={}.hasOwnProperty,indexOf=[].indexOf||function(item){for(var i=0,l=this.length;iref;i=0<=ref?++j:--j){results.push(null)}return results}.call(this);numWorkers=this.spawnWorkers();if(this.options.globalPalette===true){this.renderNextFrame()}else{for(i=j=0,ref=numWorkers;0<=ref?jref;i=0<=ref?++j:--j){this.renderNextFrame()}}this.emit("start");return this.emit("progress",0)};GIF.prototype.abort=function(){var worker;while(true){worker=this.activeWorkers.shift();if(worker==null){break}this.log("killing active worker");worker.terminate()}this.running=false;return this.emit("abort")};GIF.prototype.spawnWorkers=function(){var j,numWorkers,ref,results;numWorkers=Math.min(this.options.workers,this.frames.length);(function(){results=[];for(var j=ref=this.freeWorkers.length;ref<=numWorkers?jnumWorkers;ref<=numWorkers?j++:j--){results.push(j)}return results}).apply(this).forEach(function(_this){return function(i){var worker;_this.log("spawning worker "+i);worker=new Worker(_this.options.workerScript);worker.onmessage=function(event){_this.activeWorkers.splice(_this.activeWorkers.indexOf(worker),1);_this.freeWorkers.push(worker);return _this.frameFinished(event.data)};return _this.freeWorkers.push(worker)}}(this));return numWorkers};GIF.prototype.frameFinished=function(frame){var i,j,ref;this.log("frame "+frame.index+" finished - "+this.activeWorkers.length+" active");this.finishedFrames++;this.emit("progress",this.finishedFrames/this.frames.length);this.imageParts[frame.index]=frame;if(this.options.globalPalette===true){this.options.globalPalette=frame.globalPalette;this.log("global palette analyzed");if(this.frames.length>2){for(i=j=1,ref=this.freeWorkers.length;1<=ref?jref;i=1<=ref?++j:--j){this.renderNextFrame()}}}if(indexOf.call(this.imageParts,null)>=0){return this.renderNextFrame()}else{return this.finishRendering()}};GIF.prototype.finishRendering=function(){var data,frame,i,image,j,k,l,len,len1,len2,len3,offset,page,ref,ref1,ref2;len=0;ref=this.imageParts;for(j=0,len1=ref.length;j=this.frames.length){return}frame=this.frames[this.nextFrame++];worker=this.freeWorkers.shift();task=this.getTask(frame);this.log("starting frame "+(task.index+1)+" of "+this.frames.length);this.activeWorkers.push(worker);return worker.postMessage(task)};GIF.prototype.getContextData=function(ctx){return ctx.getImageData(0,0,this.options.width,this.options.height).data};GIF.prototype.getImageData=function(image){var ctx;if(this._canvas==null){this._canvas=document.createElement("canvas");this._canvas.width=this.options.width;this._canvas.height=this.options.height}ctx=this._canvas.getContext("2d");ctx.setFill=this.options.background;ctx.fillRect(0,0,this.options.width,this.options.height);ctx.drawImage(image,0,0);return this.getContextData(ctx)};GIF.prototype.getTask=function(frame){var index,task;index=this.frames.indexOf(frame);task={index:index,last:index===this.frames.length-1,delay:frame.delay,transparent:frame.transparent,width:this.options.width,height:this.options.height,quality:this.options.quality,dither:this.options.dither,globalPalette:this.options.globalPalette,repeat:this.options.repeat,canTransfer:browser.name==="chrome"};if(frame.data!=null){task.data=frame.data}else if(frame.context!=null){task.data=this.getContextData(frame.context)}else if(frame.image!=null){task.data=this.getImageData(frame.image)}else{throw new Error("Invalid frame")}return task};GIF.prototype.log=function(){var args;args=1<=arguments.length?slice.call(arguments,0):[];if(!this.options.debug){return}return console.log.apply(console,args)};return GIF}(EventEmitter);module.exports=GIF},{"./browser.coffee":2,events:1}]},{},[3])(3)}); 3 | //# sourceMappingURL=gif.js.map -------------------------------------------------------------------------------- /src/js/lib/gif.worker.js: -------------------------------------------------------------------------------- 1 | // gif.worker.js 0.2.0 - https://github.com/jnordberg/gif.js 2 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o=ByteArray.pageSize)this.newPage();this.pages[this.page][this.cursor++]=val};ByteArray.prototype.writeUTFBytes=function(string){for(var l=string.length,i=0;i=0)this.dispose=disposalCode};GIFEncoder.prototype.setRepeat=function(repeat){this.repeat=repeat};GIFEncoder.prototype.setTransparent=function(color){this.transparent=color};GIFEncoder.prototype.addFrame=function(imageData){this.image=imageData;this.colorTab=this.globalPalette&&this.globalPalette.slice?this.globalPalette:null;this.getImagePixels();this.analyzePixels();if(this.globalPalette===true)this.globalPalette=this.colorTab;if(this.firstFrame){this.writeLSD();this.writePalette();if(this.repeat>=0){this.writeNetscapeExt()}}this.writeGraphicCtrlExt();this.writeImageDesc();if(!this.firstFrame&&!this.globalPalette)this.writePalette();this.writePixels();this.firstFrame=false};GIFEncoder.prototype.finish=function(){this.out.writeByte(59)};GIFEncoder.prototype.setQuality=function(quality){if(quality<1)quality=1;this.sample=quality};GIFEncoder.prototype.setDither=function(dither){if(dither===true)dither="FloydSteinberg";this.dither=dither};GIFEncoder.prototype.setGlobalPalette=function(palette){this.globalPalette=palette};GIFEncoder.prototype.getGlobalPalette=function(){return this.globalPalette&&this.globalPalette.slice&&this.globalPalette.slice(0)||this.globalPalette};GIFEncoder.prototype.writeHeader=function(){this.out.writeUTFBytes("GIF89a")};GIFEncoder.prototype.analyzePixels=function(){if(!this.colorTab){this.neuQuant=new NeuQuant(this.pixels,this.sample);this.neuQuant.buildColormap();this.colorTab=this.neuQuant.getColormap()}if(this.dither){this.ditherPixels(this.dither.replace("-serpentine",""),this.dither.match(/-serpentine/)!==null)}else{this.indexPixels()}this.pixels=null;this.colorDepth=8;this.palSize=7;if(this.transparent!==null){this.transIndex=this.findClosest(this.transparent,true)}};GIFEncoder.prototype.indexPixels=function(imgq){var nPix=this.pixels.length/3;this.indexedPixels=new Uint8Array(nPix);var k=0;for(var j=0;j=0&&x1+x=0&&y1+y>16,(c&65280)>>8,c&255,used)};GIFEncoder.prototype.findClosestRGB=function(r,g,b,used){if(this.colorTab===null)return-1;if(this.neuQuant&&!used){return this.neuQuant.lookupRGB(r,g,b)}var c=b|g<<8|r<<16;var minpos=0;var dmin=256*256*256;var len=this.colorTab.length;for(var i=0,index=0;i=0){disp=dispose&7}disp<<=2;this.out.writeByte(0|disp|0|transp);this.writeShort(this.delay);this.out.writeByte(this.transIndex);this.out.writeByte(0)};GIFEncoder.prototype.writeImageDesc=function(){this.out.writeByte(44);this.writeShort(0);this.writeShort(0);this.writeShort(this.width);this.writeShort(this.height);if(this.firstFrame||this.globalPalette){this.out.writeByte(0)}else{this.out.writeByte(128|0|0|0|this.palSize)}};GIFEncoder.prototype.writeLSD=function(){this.writeShort(this.width);this.writeShort(this.height);this.out.writeByte(128|112|0|this.palSize);this.out.writeByte(0);this.out.writeByte(0)};GIFEncoder.prototype.writeNetscapeExt=function(){this.out.writeByte(33);this.out.writeByte(255);this.out.writeByte(11);this.out.writeUTFBytes("NETSCAPE2.0");this.out.writeByte(3);this.out.writeByte(1);this.writeShort(this.repeat);this.out.writeByte(0)};GIFEncoder.prototype.writePalette=function(){this.out.writeBytes(this.colorTab);var n=3*256-this.colorTab.length;for(var i=0;i>8&255)};GIFEncoder.prototype.writePixels=function(){var enc=new LZWEncoder(this.width,this.height,this.indexedPixels,this.colorDepth);enc.encode(this.out)};GIFEncoder.prototype.stream=function(){return this.out};module.exports=GIFEncoder},{"./LZWEncoder.js":2,"./TypedNeuQuant.js":3}],2:[function(require,module,exports){var EOF=-1;var BITS=12;var HSIZE=5003;var masks=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535];function LZWEncoder(width,height,pixels,colorDepth){var initCodeSize=Math.max(2,colorDepth);var accum=new Uint8Array(256);var htab=new Int32Array(HSIZE);var codetab=new Int32Array(HSIZE);var cur_accum,cur_bits=0;var a_count;var free_ent=0;var maxcode;var clear_flg=false;var g_init_bits,ClearCode,EOFCode;function char_out(c,outs){accum[a_count++]=c;if(a_count>=254)flush_char(outs)}function cl_block(outs){cl_hash(HSIZE);free_ent=ClearCode+2;clear_flg=true;output(ClearCode,outs)}function cl_hash(hsize){for(var i=0;i=0){disp=hsize_reg-i;if(i===0)disp=1;do{if((i-=disp)<0)i+=hsize_reg;if(htab[i]===fcode){ent=codetab[i];continue outer_loop}}while(htab[i]>=0)}output(ent,outs);ent=c;if(free_ent<1<0){outs.writeByte(a_count);outs.writeBytes(accum,0,a_count);a_count=0}}function MAXCODE(n_bits){return(1<0)cur_accum|=code<=8){char_out(cur_accum&255,outs);cur_accum>>=8;cur_bits-=8}if(free_ent>maxcode||clear_flg){if(clear_flg){maxcode=MAXCODE(n_bits=g_init_bits);clear_flg=false}else{++n_bits;if(n_bits==BITS)maxcode=1<0){char_out(cur_accum&255,outs);cur_accum>>=8;cur_bits-=8}flush_char(outs)}}this.encode=encode}module.exports=LZWEncoder},{}],3:[function(require,module,exports){var ncycles=100;var netsize=256;var maxnetpos=netsize-1;var netbiasshift=4;var intbiasshift=16;var intbias=1<>betashift;var betagamma=intbias<>3;var radiusbiasshift=6;var radiusbias=1<>3);var i,v;for(i=0;i>=netbiasshift;network[i][1]>>=netbiasshift;network[i][2]>>=netbiasshift;network[i][3]=i}}function altersingle(alpha,i,b,g,r){network[i][0]-=alpha*(network[i][0]-b)/initalpha;network[i][1]-=alpha*(network[i][1]-g)/initalpha;network[i][2]-=alpha*(network[i][2]-r)/initalpha}function alterneigh(radius,i,b,g,r){var lo=Math.abs(i-radius);var hi=Math.min(i+radius,netsize);var j=i+1;var k=i-1;var m=1;var p,a;while(jlo){a=radpower[m++];if(jlo){p=network[k--];p[0]-=a*(p[0]-b)/alpharadbias;p[1]-=a*(p[1]-g)/alpharadbias;p[2]-=a*(p[2]-r)/alpharadbias}}}function contest(b,g,r){var bestd=~(1<<31);var bestbiasd=bestd;var bestpos=-1;var bestbiaspos=bestpos;var i,n,dist,biasdist,betafreq;for(i=0;i>intbiasshift-netbiasshift);if(biasdist>betashift;freq[i]-=betafreq;bias[i]+=betafreq<>1;for(j=previouscol+1;j>1;for(j=previouscol+1;j<256;j++)netindex[j]=maxnetpos}function inxsearch(b,g,r){var a,p,dist;var bestd=1e3;var best=-1;var i=netindex[g];var j=i-1;while(i=0){if(i=bestd)i=netsize;else{i++;if(dist<0)dist=-dist;a=p[0]-b;if(a<0)a=-a;dist+=a;if(dist=0){p=network[j];dist=g-p[1];if(dist>=bestd)j=-1;else{j--;if(dist<0)dist=-dist;a=p[0]-b;if(a<0)a=-a;dist+=a;if(dist>radiusbiasshift;if(rad<=1)rad=0;for(i=0;i=lengthcount)pix-=lengthcount;i++;if(delta===0)delta=1;if(i%delta===0){alpha-=alpha/alphadec;radius-=radius/radiusdec;rad=radius>>radiusbiasshift;if(rad<=1)rad=0;for(j=0;j