@2080code/pic-processer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # pic-processer
2
+ 图片压缩、改变图片尺寸、File和base64互转
3
+
4
+ ## 安装
5
+ ```bash
6
+ npm install @2080code/pic-processer
7
+ ```
8
+
9
+ ## 使用
10
+ ```javascript
11
+ import { compress, getDataURL, toFile } from '@2080code/pic-processer'
12
+ ```
13
+
14
+ ```html
15
+ <script src="lib/pic-processer.min.js"></script>
16
+ ```
17
+ ```javascript
18
+ const picProcesser=new PicProcesser()
19
+ ```
20
+
21
+ ## 方法
22
+ ### 压缩图片质量、改变图片尺寸
23
+
24
+ ```javascript
25
+ picProcesser.compress(file,0.2,1000,'image/png')
26
+ ```
27
+ 参数|类型|默认值|说明
28
+ ---|---|---|---
29
+ `file` | File | `null` | 图片文件
30
+ `ratio` | number | `0.5` | 压缩比例,`0`-`1` 之间的小数
31
+ `maxWidth` | number | `null` | 图片宽度上限,>1的整数,单位px,`0` 或 `null` 表示不限制,输出图片的高度会等比例缩放
32
+ `mime` | string | `image/jpeg` | 输出图片类型
33
+
34
+ 返回值|类型|说明
35
+ ---|---|---
36
+ `Promise<string>` | `Promise<string>` | 压缩后的图片 dataURL 编码
37
+
38
+ *注意:因为是借助 canvas 渲染输出,几乎是重绘了图片,所以如果压缩比率(`ratio`)设置得太高,最终文件字节可能会比原图更大*
39
+
40
+ ### File 转 dataURL
41
+ ```javascript
42
+ picProcesser.getDataURL(file)
43
+ ```
44
+ 参数|类型|默认值|说明
45
+ ---|---|---|---
46
+ `file` | File|Blob | `null` | 图片文件
47
+
48
+ 返回值|类型|说明
49
+ ---|---|---
50
+ `Promise<FileReader>` | `Promise<FileReader>` | 完整的 FileReader 对象,通过`result`属性获取 base64 编码
51
+
52
+ ### dataURL 转 File
53
+ ```javascript
54
+ picProcesser.dataURLtoFile('export.jpg',dataURL)
55
+ ```
56
+ 参数|类型|默认值|说明
57
+ ---|---|---|---
58
+ `fileName` | string | `null` | 输出文件名
59
+ `dataURL` | string | `null` | base64编码
60
+
61
+ 返回值|类型|说明
62
+ ---|---|---
63
+ `Promise<File>` | `Promise<File>` | File 对象
package/demo/demo.html ADDED
@@ -0,0 +1,156 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <title>@2080code/pic-processer</title>
7
+ <style>
8
+ body{
9
+ font-size: 12px;
10
+ word-wrap: break-word;
11
+ padding: 10px;
12
+ }
13
+ #data-url-text{
14
+ resize: vertical;
15
+ width: 100%;
16
+ height: 150px;
17
+ color: #888;
18
+ border: 1px solid #888;
19
+ padding: 5px;
20
+ box-sizing: border-box;
21
+ border-radius: 3px;
22
+ }
23
+ #compress-preview{
24
+ display: none
25
+ }
26
+ dl dd:not(:last-child){
27
+ margin-bottom: 5px;
28
+ }
29
+ label{
30
+ font-weight: bold;
31
+ }
32
+ em{
33
+ color: #888;
34
+ text-decoration: underline;
35
+ }
36
+ </style>
37
+ </head>
38
+
39
+ <body>
40
+ <header>
41
+ <h1>@2080code/pic-processer demo</h1>
42
+ </header>
43
+ <article>
44
+
45
+ <dl>
46
+ <dt>
47
+ <h2>选取图片</h2>
48
+ </dt>
49
+ <dd>
50
+ <input type="file" id="file" draggable onchange="handle()"/>
51
+ </dd>
52
+ </dl>
53
+
54
+ <dl>
55
+ <dt><h2>getDataURL</h2></dt>
56
+ <dd>
57
+ </dd>
58
+ <dd>
59
+ 原始图片转为 dataURL:
60
+ <textarea name="" id="data-url-text" readonly></textarea>
61
+ </dd>
62
+ </dl>
63
+
64
+ <hr/>
65
+
66
+ <dl>
67
+ <dt><h2>compress</h2></dt>
68
+ <dd>
69
+ <label for="compress-ratio">ratio:</label>
70
+ <select name="ratio" id="compress-ratio" onchange="handle()">
71
+ <option value="1" selected>1(无压缩,输出字节可能会远大于原图)</option>
72
+ <option value="0.8">0.8</option>
73
+ <option value="0.6">0.6</option>
74
+ <option value="0.4">0.4</option>
75
+ <option value="0.2">0.2</option>
76
+ </select>
77
+ </dd>
78
+ <dd>
79
+ <label for="compress-max-width">maxWidth:</label>
80
+ <input type="number" inputmode="numeric" id="compress-max-width" onchange="handle()"/>px
81
+ </dd>
82
+ <dd>
83
+ <label for="compress-mime">mime:</label>
84
+ <select name="mime" id="compress-mime" onchange="handle()">
85
+ <option value="image/jpeg" selected>image/jpeg</option>
86
+ <option value="image/png">image/png</option>
87
+ </select>
88
+ </dd>
89
+ <dd>
90
+ <div id="compress-result"></div>
91
+ </dd>
92
+ <dd>
93
+ <img id="compress-preview" src="" alt="preview">
94
+ </dd>
95
+ </dl>
96
+
97
+ <hr/>
98
+
99
+ <dl>
100
+ <dt><h2>dataURLtoFile</h2></dt>
101
+ <dd>
102
+ 通过以上 compress 方法输出的 dataURL 被转为 File 对象后的信息:
103
+ <div id="file-info"><em>请先在 compress 中选择文件</em></div>
104
+ </dd>
105
+ </dl>
106
+
107
+ <hr/>
108
+ </article>
109
+
110
+ <script src="../lib/pic-processer.min.js"></script>
111
+ <script>
112
+ const picProcesser=new PicProcesser()
113
+
114
+ // getDataURL
115
+ async function getDataURLHandle(){
116
+ }
117
+
118
+ // compress
119
+ async function handle(){
120
+ // about getDataURL
121
+ const file=document.getElementById('file').files[0]
122
+ const dataURL=await picProcesser.getDataURL(file)
123
+ // 在 fileInput元素下方显示dataURL
124
+ const dataURLText=document.getElementById('data-url-text')
125
+ dataURLText.value=dataURL
126
+ dataURLText.scrollTop=0
127
+
128
+ // about compress
129
+ const compressRatio=document.getElementById('compress-ratio')
130
+ const compressMaxWidth=document.getElementById('compress-max-width')
131
+ const compressMime=document.getElementById('compress-mime')
132
+ const compressedDataURL=await picProcesser.compress(file,+compressRatio.value,+compressMaxWidth.value,compressMime.value)
133
+ const compressPreview=document.getElementById('compress-preview')
134
+
135
+ console.log('compress',file,compressRatio.value,compressedDataURL.length)
136
+
137
+ compressPreview.src=compressedDataURL
138
+ compressPreview.style.display='initial'
139
+
140
+ // about dataURLtoFile
141
+ const exportedFile=await picProcesser.dataURLtoFile(file.name,compressedDataURL)
142
+ document.getElementById('compress-result').innerHTML=`
143
+ original file size: <em>${file.size} byte</em>,
144
+ compressed file size: <em>${exportedFile.size} byte</em>
145
+ `
146
+
147
+ document.getElementById('file-info').innerHTML=`
148
+ <div>name: <em>${exportedFile.name}</em></div>
149
+ <div>size: <em>${exportedFile.size} byte</em></div>
150
+ <div>type: <em>${exportedFile.type}</em></div>
151
+ `
152
+ }
153
+ </script>
154
+ </body>
155
+
156
+ </html>
@@ -0,0 +1,88 @@
1
+ function getDataURL(file) {
2
+ return new Promise((resolve, reject) => {
3
+ const reader = new FileReader();
4
+ reader.addEventListener('load', () => {
5
+ resolve(reader === null || reader === void 0 ? void 0 : reader.result);
6
+ }, false);
7
+ reader.addEventListener('loadend', () => {
8
+ console.log('loadend', reader);
9
+ resolve(reader === null || reader === void 0 ? void 0 : reader.result);
10
+ });
11
+ reader.addEventListener('error', () => {
12
+ reject(new Error('getDataURL error!'));
13
+ });
14
+ reader.addEventListener('abort', () => {
15
+ reject(new Error('getDataURL abort!'));
16
+ });
17
+ if (file && [Blob, File].some(type => file instanceof type)) {
18
+ reader.readAsDataURL(file);
19
+ }
20
+ else {
21
+ reject(new Error('Unspecified file!'));
22
+ }
23
+ });
24
+ }
25
+ function compress(file, ratio = 0.5, maxWidth = null, mime = 'image/jpeg') {
26
+ return new Promise((resolve, reject) => {
27
+ let dataURL = '';
28
+ const img = new Image();
29
+ if (maxWidth && maxWidth < 2) {
30
+ reject(new Error('maxWidth must be greater than 1!'));
31
+ }
32
+ img.addEventListener('loadstart', () => {
33
+ });
34
+ img.addEventListener('load', () => {
35
+ const canvas = document.createElement('canvas');
36
+ let scaleRatio = 1;
37
+ if (maxWidth && img.width > maxWidth) {
38
+ scaleRatio = maxWidth / img.width;
39
+ }
40
+ const width = img.width * scaleRatio;
41
+ const height = img.height * scaleRatio;
42
+ canvas.width = width;
43
+ canvas.height = height;
44
+ canvas.getContext('2d').drawImage(img, 0, 0, width, height);
45
+ dataURL = canvas.toDataURL(mime, +ratio);
46
+ resolve(dataURL);
47
+ }, false);
48
+ img.addEventListener('loadend', () => {
49
+ resolve(dataURL);
50
+ });
51
+ img.addEventListener('error', () => {
52
+ reject(new Error('compress error!'));
53
+ });
54
+ img.addEventListener('abort', () => {
55
+ reject(new Error('compress abort!'));
56
+ });
57
+ if (file && [Blob, File].some(type => file instanceof type)) {
58
+ this.getDataURL(file).then(res => {
59
+ img.src = res;
60
+ }).catch(error => {
61
+ reject(error);
62
+ });
63
+ }
64
+ else {
65
+ reject(new Error('no file!'));
66
+ }
67
+ });
68
+ }
69
+ function dataURLtoFile(fileName, dataURL) {
70
+ const arr = dataURL.split(',');
71
+ const mime = arr[0].match(/:(.*?);/)[1];
72
+ const bstr = window.atob(arr[1]);
73
+ let n = bstr.length;
74
+ const u8arr = new Uint8Array(n);
75
+ while (n--) {
76
+ u8arr[n] = bstr.charCodeAt(n);
77
+ }
78
+ return new File([u8arr], fileName, { type: mime });
79
+ }
80
+ class PicProcesser {
81
+ constructor() {
82
+ this.compress = compress;
83
+ this.getDataURL = getDataURL;
84
+ this.dataURLtoFile = dataURLtoFile;
85
+ }
86
+ }
87
+
88
+ export { PicProcesser as default };
package/index.js ADDED
@@ -0,0 +1,5 @@
1
+ import PicProcesser from './src/pic-processer.ts'
2
+
3
+ export {
4
+ PicProcesser as default
5
+ }
@@ -0,0 +1,2 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).PicProcesser=t()}(this,function(){"use strict";function e(e){return new Promise((t,n)=>{const r=new FileReader;r.addEventListener("load",()=>{t(null==r?void 0:r.result)},!1),r.addEventListener("loadend",()=>{console.log("loadend",r),t(null==r?void 0:r.result)}),r.addEventListener("error",()=>{n(new Error("getDataURL error!"))}),r.addEventListener("abort",()=>{n(new Error("getDataURL abort!"))}),e&&[Blob,File].some(t=>e instanceof t)?r.readAsDataURL(e):n(new Error("Unspecified file!"))})}function t(e,t=.5,n=null,r="image/jpeg"){return new Promise((o,a)=>{let i="";const s=new Image;n&&n<2&&a(new Error("maxWidth must be greater than 1!")),s.addEventListener("loadstart",()=>{}),s.addEventListener("load",()=>{const e=document.createElement("canvas");let a=1;n&&s.width>n&&(a=n/s.width);const d=s.width*a,l=s.height*a;e.width=d,e.height=l,e.getContext("2d").drawImage(s,0,0,d,l),i=e.toDataURL(r,+t),o(i)},!1),s.addEventListener("loadend",()=>{o(i)}),s.addEventListener("error",()=>{a(new Error("compress error!"))}),s.addEventListener("abort",()=>{a(new Error("compress abort!"))}),e&&[Blob,File].some(t=>e instanceof t)?this.getDataURL(e).then(e=>{s.src=e}).catch(e=>{a(e)}):a(new Error("no file!"))})}function n(e,t){const n=t.split(","),r=n[0].match(/:(.*?);/)[1],o=window.atob(n[1]);let a=o.length;const i=new Uint8Array(a);for(;a--;)i[a]=o.charCodeAt(a);return new File([i],e,{type:r})}return class{constructor(){this.compress=t,this.getDataURL=e,this.dataURLtoFile=n}}});
2
+ //# sourceMappingURL=pic-processer.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pic-processer.min.js","sources":["../src/pic-processer.ts"],"sourcesContent":["/**\r\n * compress for picture\r\n * @author Warren\r\n */\r\n\r\n/**\r\n * 转为dataURL\r\n * @param {File,Blob} file\r\n * @returns {Promise}\r\n */\r\nfunction getDataURL(file:File|Blob):Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n // reader.addEventListener('loadstart', () => {\r\n // })\r\n reader.addEventListener('load', () => {\r\n resolve(reader?.result as string)\r\n }, false);\r\n reader.addEventListener('loadend', () => {\r\n console.log('loadend',reader)\r\n resolve(reader?.result as string)\r\n })\r\n reader.addEventListener('error', () => {\r\n reject(new Error('getDataURL error!'))\r\n })\r\n reader.addEventListener('abort', () => {\r\n reject(new Error('getDataURL abort!'))\r\n })\r\n if (file && [Blob,File].some(type=>file instanceof type)) {\r\n reader.readAsDataURL(file)\r\n } else {\r\n reject(new Error('Unspecified file!'))\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 压缩\r\n * @param {File,Blob} file\r\n * @param {Number} ratio 压缩比\r\n * @param {Number} maxWidth 尺寸限制,单位像素\r\n * @param {string} mime 输出图片类型,默认`image/jpeg`\r\n * @returns {Promise}\r\n */\r\nfunction compress(file:File|Blob, ratio:number = 0.5, maxWidth:number = null,mime:string='image/jpeg'):Promise<string> {\r\n // console.log(ratio, maxWidth)\r\n // 通过构造函数来创建的 img 实例,在赋予 src 值后就会立刻下载图片,相比 createElement() 创建 <img> 省去了 append(),也就避免了文档冗余和污染\r\n return new Promise((resolve, reject) => {\r\n let dataURL = '';\r\n const img = new Image();\r\n\r\n // 尺寸限制必须大于1,否则canvas是渲染不出内容的\r\n if(maxWidth && maxWidth<2) {\r\n reject(new Error('maxWidth must be greater than 1!'))\r\n }\r\n\r\n img.addEventListener('loadstart', () => {\r\n })\r\n img.addEventListener('load', () => {\r\n const canvas = document.createElement('canvas'); // 创建canvas元素\r\n let scaleRatio = 1\r\n if (maxWidth && img.width > maxWidth) {\r\n scaleRatio = maxWidth / img.width\r\n }\r\n const width=img.width * scaleRatio\r\n const height=img.height * scaleRatio\r\n // 确保canvas的尺寸和图片一样\r\n canvas.width = width;\r\n canvas.height = height;\r\n canvas.getContext('2d').drawImage(img, 0, 0, width, height); // 将图片绘制到canvas中\r\n dataURL = canvas.toDataURL(mime, +ratio); // 转换图片为dataURL\r\n resolve(dataURL)\r\n }, false);\r\n img.addEventListener('loadend', () => {\r\n resolve(dataURL)\r\n })\r\n img.addEventListener('error', () => {\r\n reject(new Error('compress error!'))\r\n })\r\n img.addEventListener('abort', () => {\r\n reject(new Error('compress abort!'))\r\n })\r\n\r\n if (file && [Blob,File].some(type=>file instanceof type)) {\r\n this.getDataURL(file).then(res => {\r\n img.src = res\r\n }).catch(error => {\r\n reject(error)\r\n })\r\n } else {\r\n reject(new Error('no file!'))\r\n }\r\n\r\n \r\n })\r\n}\r\n\r\n/**\r\n * dataURL 转 File\r\n * @param {String} fileName 文件名\r\n * @param {String} dataURL\r\n * @returns {File}\r\n */\r\nfunction dataURLtoFile(fileName:string, dataURL:string):File {\r\n const arr = dataURL.split(',');\r\n const mime = arr[0].match(/:(.*?);/)[1];\r\n const bstr = window.atob(arr[1]);\r\n let n = bstr.length;\r\n const u8arr = new Uint8Array(n);\r\n while (n--) {\r\n u8arr[n] = bstr.charCodeAt(n);\r\n }\r\n return new File([u8arr], fileName, { type: mime });\r\n}\r\n\r\nexport default class PicProcesser {\r\n constructor() {\r\n }\r\n compress=compress\r\n getDataURL=getDataURL\r\n dataURLtoFile=dataURLtoFile\r\n}\r\n"],"names":["getDataURL","file","Promise","resolve","reject","reader","FileReader","addEventListener","result","console","log","Error","Blob","File","some","type","readAsDataURL","compress","ratio","maxWidth","mime","dataURL","img","Image","canvas","document","createElement","scaleRatio","width","height","getContext","drawImage","toDataURL","this","then","res","src","catch","error","dataURLtoFile","fileName","arr","split","match","bstr","window","atob","n","length","u8arr","Uint8Array","charCodeAt","constructor"],"mappings":"4OAUA,SAASA,EAAWC,GAChB,OAAO,IAAIC,QAAQ,CAACC,EAASC,KACzB,MAAMC,EAAS,IAAIC,WAGnBD,EAAOE,iBAAiB,OAAQ,KAC5BJ,EAAQE,eAAAA,EAAQG,UACjB,GACHH,EAAOE,iBAAiB,UAAW,KAC/BE,QAAQC,IAAI,UAAUL,GACtBF,EAAQE,eAAAA,EAAQG,UAEpBH,EAAOE,iBAAiB,QAAS,KAC7BH,EAAO,IAAIO,MAAM,wBAErBN,EAAOE,iBAAiB,QAAS,KAC7BH,EAAO,IAAIO,MAAM,wBAEjBV,GAAQ,CAACW,KAAKC,MAAMC,KAAKC,GAAMd,aAAgBc,GAC/CV,EAAOW,cAAcf,GAErBG,EAAO,IAAIO,MAAM,uBAG7B,CAUA,SAASM,EAAShB,EAAgBiB,EAAe,GAAKC,EAAkB,KAAKC,EAAY,cAGrF,OAAO,IAAIlB,QAAQ,CAACC,EAASC,KACzB,IAAIiB,EAAU,GACd,MAAMC,EAAM,IAAIC,MAGbJ,GAAYA,EAAS,GACpBf,EAAO,IAAIO,MAAM,qCAGrBW,EAAIf,iBAAiB,YAAa,QAElCe,EAAIf,iBAAiB,OAAQ,KACzB,MAAMiB,EAASC,SAASC,cAAc,UACtC,IAAIC,EAAa,EACbR,GAAYG,EAAIM,MAAQT,IACxBQ,EAAaR,EAAWG,EAAIM,OAEhC,MAAMA,EAAMN,EAAIM,MAAQD,EAClBE,EAAOP,EAAIO,OAASF,EAE1BH,EAAOI,MAAQA,EACfJ,EAAOK,OAASA,EAChBL,EAAOM,WAAW,MAAMC,UAAUT,EAAK,EAAG,EAAGM,EAAOC,GACpDR,EAAUG,EAAOQ,UAAUZ,GAAOF,GAClCf,EAAQkB,KACT,GACHC,EAAIf,iBAAiB,UAAW,KAC5BJ,EAAQkB,KAEZC,EAAIf,iBAAiB,QAAS,KAC1BH,EAAO,IAAIO,MAAM,sBAErBW,EAAIf,iBAAiB,QAAS,KAC1BH,EAAO,IAAIO,MAAM,sBAGjBV,GAAQ,CAACW,KAAKC,MAAMC,KAAKC,GAAMd,aAAgBc,GAC/CkB,KAAKjC,WAAWC,GAAMiC,KAAKC,IACvBb,EAAIc,IAAMD,IACXE,MAAMC,IACLlC,EAAOkC,KAGXlC,EAAO,IAAIO,MAAM,cAK7B,CAQA,SAAS4B,EAAcC,EAAiBnB,GACtC,MAAMoB,EAAMpB,EAAQqB,MAAM,KACpBtB,EAAOqB,EAAI,GAAGE,MAAM,WAAW,GAC/BC,EAAOC,OAAOC,KAAKL,EAAI,IAC7B,IAAIM,EAAIH,EAAKI,OACb,MAAMC,EAAQ,IAAIC,WAAWH,GAC7B,KAAOA,KACLE,EAAMF,GAAKH,EAAKO,WAAWJ,GAE7B,OAAO,IAAIlC,KAAK,CAACoC,GAAQT,EAAU,CAAEzB,KAAMK,GAC7C,QAEc,MACZ,WAAAgC,GAEAnB,KAAAhB,SAASA,EACTgB,KAAAjC,WAAWA,EACXiC,KAAAM,cAAcA,CAHd"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@2080code/pic-processer",
3
+ "version": "0.0.1",
4
+ "description": "图片压缩、File和base64互转",
5
+ "main": "index.js",
6
+ "types": "./src/types.ts",
7
+ "type": "module",
8
+ "node": ">=20.0.0",
9
+ "scripts": {
10
+ "dev": "rollup -c -w",
11
+ "build": "del \"dist\" \"lib\" /s/q/f && rollup -c"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/2080code/pic-processer.git"
16
+ },
17
+ "keywords": [
18
+ "watermark",
19
+ "html",
20
+ "svg",
21
+ "js",
22
+ "css",
23
+ "background",
24
+ "canvas"
25
+ ],
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "author": "Warren Chen",
30
+ "license": "ISC",
31
+ "bugs": {
32
+ "url": "https://github.com/2080code/pic-processer/issues"
33
+ },
34
+ "homepage": "https://github.com/2080code/pic-processer#readme",
35
+ "dependencies": {
36
+ "@babel/core": "^7.28.5",
37
+ "@babel/preset-env": "^7.28.5",
38
+ "@rollup/plugin-babel": "^6.1.0",
39
+ "@rollup/plugin-commonjs": "^29.0.0",
40
+ "@rollup/plugin-node-resolve": "^16.0.3",
41
+ "@rollup/plugin-terser": "^0.4.4",
42
+ "@rollup/plugin-typescript": "^12.3.0",
43
+ "tslib": "^2.8.1"
44
+ },
45
+ "directories": {
46
+ "lib": "lib"
47
+ },
48
+ "devDependencies": {}
49
+ }
@@ -0,0 +1,37 @@
1
+ import commonjs from '@rollup/plugin-commonjs'
2
+ import resolve from '@rollup/plugin-node-resolve'
3
+ import babel from '@rollup/plugin-babel'
4
+ import terser from '@rollup/plugin-terser'
5
+ import typescript from '@rollup/plugin-typescript'
6
+
7
+ export default {
8
+ input: 'index.js',
9
+ output: [{
10
+ file: 'dist/pic-processer.js',
11
+ name: 'PicProcesser',
12
+ },{
13
+ file: 'lib/pic-processer.min.js',
14
+ format: 'umd',
15
+ name: 'PicProcesser',
16
+ sourcemap: true,
17
+ plugins: [terser()]
18
+ }],
19
+ plugins: [
20
+ commonjs(),
21
+ resolve(),
22
+ typescript(),
23
+ babel({
24
+ babelHelpers: 'bundled',
25
+ // presets: [
26
+ // ['@babel/preset-env', {
27
+ // // 配置项
28
+ // targets: {
29
+ // chrome: '58',
30
+ // ie: '11'
31
+ // }
32
+ // }]
33
+ // ]
34
+ }),
35
+ ]
36
+
37
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * compress for picture
3
+ * @author Warren
4
+ */
5
+
6
+ /**
7
+ * 转为dataURL
8
+ * @param {File,Blob} file
9
+ * @returns {Promise}
10
+ */
11
+ function getDataURL(file:File|Blob):Promise<string> {
12
+ return new Promise((resolve, reject) => {
13
+ const reader = new FileReader();
14
+ // reader.addEventListener('loadstart', () => {
15
+ // })
16
+ reader.addEventListener('load', () => {
17
+ resolve(reader?.result as string)
18
+ }, false);
19
+ reader.addEventListener('loadend', () => {
20
+ console.log('loadend',reader)
21
+ resolve(reader?.result as string)
22
+ })
23
+ reader.addEventListener('error', () => {
24
+ reject(new Error('getDataURL error!'))
25
+ })
26
+ reader.addEventListener('abort', () => {
27
+ reject(new Error('getDataURL abort!'))
28
+ })
29
+ if (file && [Blob,File].some(type=>file instanceof type)) {
30
+ reader.readAsDataURL(file)
31
+ } else {
32
+ reject(new Error('Unspecified file!'))
33
+ }
34
+ })
35
+ }
36
+
37
+ /**
38
+ * 压缩
39
+ * @param {File,Blob} file
40
+ * @param {Number} ratio 压缩比
41
+ * @param {Number} maxWidth 尺寸限制,单位像素
42
+ * @param {string} mime 输出图片类型,默认`image/jpeg`
43
+ * @returns {Promise}
44
+ */
45
+ function compress(file:File|Blob, ratio:number = 0.5, maxWidth:number = null,mime:string='image/jpeg'):Promise<string> {
46
+ // console.log(ratio, maxWidth)
47
+ // 通过构造函数来创建的 img 实例,在赋予 src 值后就会立刻下载图片,相比 createElement() 创建 <img> 省去了 append(),也就避免了文档冗余和污染
48
+ return new Promise((resolve, reject) => {
49
+ let dataURL = '';
50
+ const img = new Image();
51
+
52
+ // 尺寸限制必须大于1,否则canvas是渲染不出内容的
53
+ if(maxWidth && maxWidth<2) {
54
+ reject(new Error('maxWidth must be greater than 1!'))
55
+ }
56
+
57
+ img.addEventListener('loadstart', () => {
58
+ })
59
+ img.addEventListener('load', () => {
60
+ const canvas = document.createElement('canvas'); // 创建canvas元素
61
+ let scaleRatio = 1
62
+ if (maxWidth && img.width > maxWidth) {
63
+ scaleRatio = maxWidth / img.width
64
+ }
65
+ const width=img.width * scaleRatio
66
+ const height=img.height * scaleRatio
67
+ // 确保canvas的尺寸和图片一样
68
+ canvas.width = width;
69
+ canvas.height = height;
70
+ canvas.getContext('2d').drawImage(img, 0, 0, width, height); // 将图片绘制到canvas中
71
+ dataURL = canvas.toDataURL(mime, +ratio); // 转换图片为dataURL
72
+ resolve(dataURL)
73
+ }, false);
74
+ img.addEventListener('loadend', () => {
75
+ resolve(dataURL)
76
+ })
77
+ img.addEventListener('error', () => {
78
+ reject(new Error('compress error!'))
79
+ })
80
+ img.addEventListener('abort', () => {
81
+ reject(new Error('compress abort!'))
82
+ })
83
+
84
+ if (file && [Blob,File].some(type=>file instanceof type)) {
85
+ this.getDataURL(file).then(res => {
86
+ img.src = res
87
+ }).catch(error => {
88
+ reject(error)
89
+ })
90
+ } else {
91
+ reject(new Error('no file!'))
92
+ }
93
+
94
+
95
+ })
96
+ }
97
+
98
+ /**
99
+ * dataURL 转 File
100
+ * @param {String} fileName 文件名
101
+ * @param {String} dataURL
102
+ * @returns {File}
103
+ */
104
+ function dataURLtoFile(fileName:string, dataURL:string):File {
105
+ const arr = dataURL.split(',');
106
+ const mime = arr[0].match(/:(.*?);/)[1];
107
+ const bstr = window.atob(arr[1]);
108
+ let n = bstr.length;
109
+ const u8arr = new Uint8Array(n);
110
+ while (n--) {
111
+ u8arr[n] = bstr.charCodeAt(n);
112
+ }
113
+ return new File([u8arr], fileName, { type: mime });
114
+ }
115
+
116
+ export default class PicProcesser {
117
+ constructor() {
118
+ }
119
+ compress=compress
120
+ getDataURL=getDataURL
121
+ dataURLtoFile=dataURLtoFile
122
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+
2
+ {
3
+ "include": [
4
+ "./src/**/*",
5
+ "rollup.config.js",
6
+ "types/types.ts"
7
+ ],
8
+ "compilerOptions": {
9
+ "target": "es2015",
10
+ "module": "es2015",
11
+ "lib": [
12
+ "es2015",
13
+ "dom"
14
+ ],
15
+ "removeComments": true,
16
+ "allowUmdGlobalAccess": true
17
+ }
18
+ }
package/types/types.ts ADDED
File without changes