kh-tool
Version:
784 lines (651 loc) • 21 kB
JavaScript
import { enc } from 'crypto-js';
/**
* 把文件读取成 base64 格式
* @param file 文件对象
*/
function FileToBase64(file) {
var reading = new FileReader();
return new Promise(function (resolve, reject) {
reading.onload = function (event) {
var _event$target;
return resolve((event === null || event === void 0 ? void 0 : (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.result) || null);
};
reading.onerror = function () {
return reject(new Error("文件读取失败"));
};
reading.readAsDataURL(file);
});
}
function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArrayLimit(arr, i) {
if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
/**
* 将base64转换为文件对象
* @param base64 base64格式的编码
* @param getFile 获得 File 的结果吗
*/
function Base64ToFile(base64) {
var getFile = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
try {
var _base64$split = base64.split(","),
_base64$split2 = _slicedToArray(_base64$split, 2),
typeStr = _base64$split2[0],
atobStr = _base64$split2[1];
var matchRst = typeStr.match(/:(.*?);/);
var mime = matchRst ? matchRst[1] : function () {
throw new Error("未捕获到结果");
}();
var bstr = atob(atobStr);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
var filename = "".concat(mime.replace("/", "."));
return getFile ? new File([u8arr], filename, {
type: mime
}) : new Blob([u8arr], {
type: mime
});
} catch (error) {
return error;
}
}
/**
* 把文件读取成 ArrayBuffer格式
* @param file 文件对象
*/
function FileToArrayBuffer(file) {
var reading = new FileReader();
return new Promise(function (resolve, reject) {
reading.onload = function (event) {
var _event$target;
return resolve((event === null || event === void 0 ? void 0 : (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.result) || null);
};
reading.onerror = function () {
return reject(new Error("文件读取失败"));
};
reading.readAsArrayBuffer(file);
});
}
function GetType(val) {
return Object.prototype.toString.call(val).toLowerCase().replace(/\[object\s|]/g, "");
}
function GetTypeOf(val, type) {
return GetType(val) === type;
}
/**
* 不是空数组
*/
function NoEmptyArr(param) {
return !!param && param instanceof Array && param.length !== 0;
}
/**
* 不为空值
*/
function NoEmpty(value) {
if (value === null || value === "" || value === "undefined" || value === undefined || value === "null") {
return false;
}
if (typeof value === "string") {
value = value.replace(/\s/g, "");
if (value == "") {
return false;
}
}
return true;
}
/**
* 是 JSON 字符串
* @param str
*/
function IsJsonString(str) {
try {
_typeof(JSON.parse(str)) == "object";
return true;
} catch (_unused) {
return false;
}
}
/**
* 是 URL 字符串
* @param str
*/
var IsUrlStr = function IsUrlStr(url) {
try {
return new URL(url);
} catch (error) {
return false;
}
};
// function
var k = 0;
/**
* diff Object 的格式
*/
function DiffType(one, other) {
console.log(k++, one, other);
if (GetTypeOf(one, "object") && GetTypeOf(other, "object")) {
for (var i in one) {
if (!one[i] || !other[i]) {
return false;
}
if (GetTypeOf(one[i], "object") && GetTypeOf(other[i], "object")) {
if (!DiffType(one[i], other[i])) {
return false;
}
}
}
}
return true;
}
function IdRandom() {
var num = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
return Math.random().toString(36).substr(2, num);
}
/**
* 主要用于格式化数字
* eg: 1234567 => 1,234,567
*/
function FormatNumber(str) {
return str.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
/**
* 将数字每3位之间用逗号分割,例如12345.22格式化为 12,345.22
* @param {String} s 要格式化的数值
* @param {Number} n 保留小数的位数
*/
function FormatNumber2Decimal(s) {
var n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
var decimal = n > 0 && n <= 20 ? n : 2;
var _s$split = s.split("."),
_s$split2 = _slicedToArray(_s$split, 2),
front = _s$split2[0],
_s$split2$ = _s$split2[1],
back = _s$split2$ === void 0 ? "" : _s$split2$;
return [FormatNumber(front), back.substr(0, decimal).padEnd(decimal, "0")].join(".");
}
var Base64 = enc.Base64,
Utf8 = enc.Utf8;
function StrToBase64(str) {
return Base64.stringify(Utf8.parse(str));
}
function StrFromBase64(str) {
return Base64.parse(str).toString(Utf8);
}
/** 解析为url路径str专用 */
function StrToUrlStr(str) {
return StrToBase64(str).replace(/\//g, "-").replace(/=/g, "_");
}
/** 从url路径str解析原意专用 */
function StrFromUrlStr(str) {
return StrFromBase64(str.replace(/-/g, "/").replace(/_/g, "="));
}
/**
* 命名法:
* kebab 串式 asd-fgh
* snake 蛇形 asd_fgh
* Camel 驼峰命名法 AsdFgh
* upperCamel 大驼峰命名法 同 Camel
* lowerCamel 小驼峰命名法 asdFgh
*/
/** 短横线转换为驼峰(大驼峰) */
function Kebab2Camel(s) {
return s.replace(/(^|-)(\w)/g, function (all, $1, $2) {
return $2.toUpperCase();
});
}
/** 短横线转换为小驼峰 */
function Kebab2lowerCamel(s) {
return s.replace(/-(\w)/g, function (all, $1) {
return $1.toUpperCase();
});
}
/** 下划线转换为驼峰 */
function Snake2Camel(s) {
return s.replace(/(^|_)(\w)/g, function (all, $1, $2) {
return $2.toUpperCase();
});
}
/** 下划线转换为小驼峰 */
function Snake2lowerCamel(s) {
return s.replace(/_(\w)/g, function (all, $1) {
return $1.toUpperCase();
});
}
/** 驼峰转换为短横线 */
function Camel2Kebab(s) {
return s.replace(/\w([A-Z])/g, "-$1").toLowerCase();
}
/** 驼峰转换为下划线 */
function Camel2Snake(s) {
return s.replace(/\w([A-Z])/g, "_$1").toLowerCase();
}
/**
* Mega pixel image rendering library for iOS6 Safari
*
* Fixes iOS6 Safari's image file rendering issue for large size image (over mega-pixel),
* which causes unexpected subsampling when drawing it in canvas.
* By using this library, you can safely render the image with proper stretching.
*
* Copyright (c) 2012 Shinichi Tomita <shinichi.tomita@gmail.com>
* Released under the MIT license
*/
/**
* Detect subsampling in loaded image.
* In iOS, larger images than 2M pixels may be subsampled in rendering.
*/
function detectSubsampling(img) {
var iw = img.naturalWidth;
var ih = img.naturalHeight;
if (iw * ih > 1024 * 1024) {
// subsampling may happen over megapixel image
var canvas = document.createElement("canvas");
canvas.width = canvas.height = 1;
var ctx = canvas.getContext("2d");
ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(img, -iw + 1, 0); // subsampled image becomes half smaller in rendering size.
// check alpha channel value to confirm image is covering edge pixel or not.
// if alpha value is 0 image is not covering, hence subsampled.
return (ctx === null || ctx === void 0 ? void 0 : ctx.getImageData(0, 0, 1, 1).data[3]) === 0;
} else {
return false;
}
}
/**
* Detecting vertical squash in loaded image.
* Fixes a bug which squash image vertically while drawing into canvas for some images.
*/
function detectVerticalSquash(img, iw, ih) {
var canvas = document.createElement("canvas");
canvas.width = 1;
canvas.height = ih;
var ctx = canvas.getContext("2d");
ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(img, 0, 0);
var data = ctx === null || ctx === void 0 ? void 0 : ctx.getImageData(0, 0, 1, ih).data; // search image edge pixel position in case it is squashed vertically.
var sy = 0;
var ey = ih;
var py = ih;
while (py > sy) {
var alpha = data === null || data === void 0 ? void 0 : data[(py - 1) * 4 + 3];
if (alpha === 0) {
ey = py;
} else {
sy = py;
}
py = ey + sy >> 1;
}
var ratio = py / ih;
return ratio === 0 ? 1 : ratio;
}
/**
* Rendering image element (with resizing) and get its data URL
*/
function renderImageToDataURL(img, options, doSquash) {
var canvas = document.createElement("canvas");
renderImageToCanvas(img, canvas, options, doSquash); // return canvas.toDataURL("image/jpeg", options.quality || 0.8);
return canvas.toDataURL(options, options.quality || 0.8);
}
/**
* Rendering image element (with resizing) into the canvas element
*/
function renderImageToCanvas(img, canvas, options, doSquash) {
var iw = img.naturalWidth;
var ih = img.naturalHeight;
if (!(iw + ih)) return;
var width = options.width;
var height = options.height;
var ctx = canvas.getContext("2d");
ctx === null || ctx === void 0 ? void 0 : ctx.save();
transformCoordinate(canvas, ctx, width, height, options.orientation);
var subsampled = detectSubsampling(img);
if (subsampled) {
iw /= 2;
ih /= 2;
}
var d = 1024; // size of tiling canvas
var tmpCanvas = document.createElement("canvas");
tmpCanvas.width = tmpCanvas.height = d;
var tmpCtx = tmpCanvas.getContext("2d");
var vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1;
var dw = Math.ceil(d * width / iw);
var dh = Math.ceil(d * height / ih / vertSquashRatio);
var sy = 0;
var dy = 0;
while (sy < ih) {
var sx = 0;
var dx = 0;
while (sx < iw) {
var _tmpCtx, _tmpCtx2;
(_tmpCtx = tmpCtx) === null || _tmpCtx === void 0 ? void 0 : _tmpCtx.clearRect(0, 0, d, d);
(_tmpCtx2 = tmpCtx) === null || _tmpCtx2 === void 0 ? void 0 : _tmpCtx2.drawImage(img, -sx, -sy);
ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);
sx += d;
dx += dw;
}
sy += d;
dy += dh;
}
ctx === null || ctx === void 0 ? void 0 : ctx.restore();
tmpCanvas = tmpCtx = null;
}
/**
* Transform canvas coordination according to specified frame size and orientation
* Orientation value is from EXIF tag
*/
function transformCoordinate(canvas, ctx, width, height, orientation) {
switch (orientation) {
case 5:
case 6:
case 7:
case 8:
canvas.width = height;
canvas.height = width;
break;
default:
canvas.width = width;
canvas.height = height;
}
switch (orientation) {
case 2:
// horizontal flip
ctx === null || ctx === void 0 ? void 0 : ctx.translate(width, 0);
ctx === null || ctx === void 0 ? void 0 : ctx.scale(-1, 1);
break;
case 3:
// 180 rotate left
ctx === null || ctx === void 0 ? void 0 : ctx.translate(width, height);
ctx === null || ctx === void 0 ? void 0 : ctx.rotate(Math.PI);
break;
case 4:
// vertical flip
ctx === null || ctx === void 0 ? void 0 : ctx.translate(0, height);
ctx === null || ctx === void 0 ? void 0 : ctx.scale(1, -1);
break;
case 5:
// vertical flip + 90 rotate right
ctx === null || ctx === void 0 ? void 0 : ctx.rotate(0.5 * Math.PI);
ctx === null || ctx === void 0 ? void 0 : ctx.scale(1, -1);
break;
case 6:
// 90 rotate right
ctx === null || ctx === void 0 ? void 0 : ctx.rotate(0.5 * Math.PI);
ctx === null || ctx === void 0 ? void 0 : ctx.translate(0, -height);
break;
case 7:
// horizontal flip + 90 rotate right
ctx === null || ctx === void 0 ? void 0 : ctx.rotate(0.5 * Math.PI);
ctx === null || ctx === void 0 ? void 0 : ctx.translate(width, -height);
ctx === null || ctx === void 0 ? void 0 : ctx.scale(-1, 1);
break;
case 8:
// 90 rotate left
ctx === null || ctx === void 0 ? void 0 : ctx.rotate(-0.5 * Math.PI);
ctx === null || ctx === void 0 ? void 0 : ctx.translate(-width, 0);
break;
}
}
var URL$1 = globalThis.URL || globalThis.webkitURL || null;
/**
* MegaPixImage class
*/
var MegaPixImage = /*#__PURE__*/function () {
function MegaPixImage(param) {
var _this = this;
_classCallCheck(this, MegaPixImage);
var srcImage;
if (globalThis.Blob && param instanceof Blob) {
if (!URL$1) {
throw Error("No createObjectURL function found to create blob url");
}
var img = new Image();
img.src = URL$1.createObjectURL(param);
this.blob = param;
srcImage = img;
} else {
srcImage = param;
}
if (!srcImage.naturalWidth && !srcImage.naturalHeight) {
srcImage.onload = srcImage.onerror = function () {
var listeners = _this.imageLoadListeners;
if (listeners) {
_this.imageLoadListeners = null;
for (var i = 0, len = listeners.length; i < len; i++) {
listeners[i]();
}
}
};
this.imageLoadListeners = [];
}
this.srcImage = srcImage;
}
/**
* Rendering megapix image into specified target element
*/
_createClass(MegaPixImage, [{
key: "render",
value: function render(target, options) {
var _this2 = this;
var callback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {
return "";
};
if (this.imageLoadListeners) {
this.imageLoadListeners.push(function () {
_this2.render(target, options, callback);
});
return;
}
options = options || {};
var imgWidth = this.srcImage.naturalWidth;
var imgHeight = this.srcImage.naturalHeight;
var width = options.width;
var height = options.height;
var maxWidth = options.maxWidth;
var maxHeight = options.maxHeight;
var doSquash = !this.blob || this.blob.type === "image/jpeg";
if (width && !height) {
height = imgHeight * width / imgWidth << 0;
} else if (height && !width) {
width = imgWidth * height / imgHeight << 0;
} else {
width = imgWidth;
height = imgHeight;
}
if (maxWidth && width > maxWidth) {
width = maxWidth;
height = imgHeight * width / imgWidth << 0;
}
if (maxHeight && height > maxHeight) {
height = maxHeight;
width = imgWidth * height / imgHeight << 0;
}
var opt = {
width: width,
height: height
};
for (var k in options) {
opt[k] = options[k];
}
var tagName = target.tagName.toLowerCase();
if (tagName === "img") {
target.src = renderImageToDataURL(this.srcImage, opt, doSquash);
} else if (tagName === "canvas") {
renderImageToCanvas(this.srcImage, target, opt, doSquash);
} // if (typeof this.onrender === "function") {
// this.onrender(target);
// }
callback();
if (this.blob) {
this.blob = null;
URL$1 === null || URL$1 === void 0 ? void 0 : URL$1.revokeObjectURL(this.srcImage.src);
}
}
}]);
return MegaPixImage;
}();
/**
* @description 图片压缩的最核心的步骤——压缩
* @param image Image对象 dom
* @param options.max_length 设置压缩的图片的最长边
* @param options.quality 压缩质量
*/
function MinImg(image) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var max_length = options.max_length,
quality = options.quality,
_options$type = options.type,
type = _options$type === void 0 ? "image/jpeg" : _options$type;
var canvas = document.createElement("canvas");
var c_width = image.width;
var c_height = image.height;
if (max_length) {
var bl;
if (c_width > c_height) {
bl = c_width / c_height;
c_width = max_length;
c_height = c_width / bl;
} else {
bl = c_height / c_width;
c_height = max_length;
c_width = c_height / bl;
}
}
canvas.width = c_width;
canvas.height = c_height; // const mpimg = canvas.getContext("2d");
// mpimg.drawImage(imageObj, 0, 0, c_width, c_height);
var mpimg = new MegaPixImage(image);
mpimg.render(canvas, {
width: c_width,
height: c_height,
quality: quality,
type: type
});
var imgFile = canvas.toDataURL(type, quality);
var getZipRstFile = Base64ToFile(imgFile);
if (getZipRstFile instanceof File || getZipRstFile instanceof Blob) {
return getZipRstFile;
} else {
throw getZipRstFile;
}
}
/**
* @description 压缩图片
* @param file 文件
* @param options 文件
* @use 读取文件方法示例
* js async写法
* ```js
* async getFile(e) {
* const file = e.target.files[0];
* let zipFile = await getZipImg(file);
* console.log(zipFile);
* }
* ```
* ts Promise链写法
* ```ts
* getFile(e: any) {
* const file = e.target.files[0];
* console.log(file); // 压缩前
* ZipImg(file, { quality: 0.1, type: "image/webp" })
* .then((resp: File | Blob) => {
* console.log(resp); // 压缩后
* })
* }
* ```
*/
function ZipImg(file) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
quality: 0.8
};
var reading = new FileReader();
var imageObj = new Image();
return new Promise(function (resolve, reject) {
reading.onload = function (event) {
var _event$target;
var rst = (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.result;
imageObj.src = rst;
imageObj.onload = function () {
var ImgFile = MinImg(imageObj, options);
return resolve(ImgFile);
};
};
reading.onerror = function () {
reject(new Error("图片加载失败"));
};
reading.readAsDataURL(file);
});
}
export { Base64ToFile, Camel2Kebab, Camel2Snake, DiffType, FileToArrayBuffer, FileToBase64, FormatNumber, FormatNumber2Decimal, GetType, GetTypeOf, IdRandom, IsJsonString, IsUrlStr, Kebab2Camel, Kebab2lowerCamel, MinImg, NoEmpty, NoEmptyArr, Snake2Camel, Snake2lowerCamel, StrFromBase64, StrFromUrlStr, StrToBase64, StrToUrlStr, ZipImg };