200 lines
7.0 KiB
Plaintext
200 lines
7.0 KiB
Plaintext
import HashMap from '@ohos.util.HashMap';
|
||
import { Base64Util } from './Base64Util';
|
||
import { CryptoJS } from '@ohos/crypto-js';
|
||
import { logger } from './logger';
|
||
import image from '@ohos.multimedia.image';
|
||
import fs from '@ohos.file.fs';
|
||
import { fileIo } from '@kit.CoreFileKit';
|
||
import util from '@ohos.util';
|
||
import { i18n } from '@kit.LocalizationKit';
|
||
import { connection } from '@kit.NetworkKit';
|
||
export class ChangeUtil {
|
||
/**
|
||
* 将HashMap转成JsonString
|
||
* @param map
|
||
* @returns
|
||
*/
|
||
static map2Json(map:HashMap<string, string>): string {
|
||
let jsonObject: Record<string, Object> = {};
|
||
map.forEach((value, key) => {
|
||
if(key != undefined && value != undefined){
|
||
jsonObject[key] = value;
|
||
}
|
||
})
|
||
return JSON.stringify(jsonObject);
|
||
}
|
||
|
||
static getSign(extraDatas1: HashMap<string, string>, secret: string): string {
|
||
if(secret!=null) {
|
||
let keyValueStr: string = "";
|
||
let entriesArray: Array<string> = Array.from(extraDatas1.keys());
|
||
entriesArray.sort();
|
||
|
||
let sortedMap:HashMap<string, string> = new HashMap();
|
||
entriesArray.forEach((value: string, index: number) => {
|
||
sortedMap.set(value,extraDatas1.get(value));
|
||
keyValueStr +=value+extraDatas1.get(value)
|
||
});
|
||
keyValueStr = keyValueStr.replace(" ", "");
|
||
keyValueStr = keyValueStr + CryptoJS.MD5(secret).toString();
|
||
let Md5keyValueStr: string = CryptoJS.MD5(keyValueStr).toString();
|
||
let base64Str:string=Base64Util.encodeToStrSync(Md5keyValueStr);
|
||
return base64Str;
|
||
}
|
||
else
|
||
{
|
||
return '';
|
||
}
|
||
}
|
||
|
||
|
||
static isMobileNum(mobiles:string): boolean {
|
||
const reg2: RegExp = new RegExp('^(1[3-9])[0-9]{9}$')
|
||
|
||
return reg2.test(mobiles);
|
||
}
|
||
static isPassword(password:string): boolean {
|
||
const reg2: RegExp = new RegExp('^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$')
|
||
|
||
return reg2.test(password);
|
||
}
|
||
|
||
static isEmail(email:string): boolean {
|
||
const reg2: RegExp = new RegExp('^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$')
|
||
return reg2.test(email);
|
||
}
|
||
|
||
static async convertUriToBase64(uri: string): Promise<string> {
|
||
// 打开文件并读取数据
|
||
const file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
|
||
const stat = await fileIo.stat(file.fd);
|
||
const buffer = new ArrayBuffer(stat.size);
|
||
fileIo.readSync(file.fd, buffer);
|
||
fileIo.closeSync(file);
|
||
const buffernew=await ChangeUtil.compression(buffer,"image/jpeg",0.5)
|
||
|
||
// 编码为 Base64
|
||
const base64Helper = new util.Base64Helper();
|
||
return base64Helper.encodeToStringSync(new Uint8Array(buffernew));
|
||
}
|
||
/**
|
||
* 压缩图片
|
||
* @param buffer 二进制
|
||
* @param contentType image/jpeg 保存后的文件格式
|
||
* @param compressionRatio 1 就是 100%, 0.5 就是50%
|
||
* @returns
|
||
*/
|
||
static async compression(buffer: ArrayBuffer, contentType: string, compressionRatio: number = 0.5) {
|
||
// 这里判断 1,是因为压缩的时候传了 100%,也会丢失一点精度,所以直接返回了。
|
||
if (compressionRatio == 1) {
|
||
return buffer
|
||
}
|
||
const imageSource: image.ImageSource = image.createImageSource(buffer);
|
||
|
||
const imagePackerApi = image.createImagePacker();
|
||
const bf = await imagePackerApi.packing(imageSource, { format: contentType, quality: compressionRatio * 100 })
|
||
|
||
|
||
return bf
|
||
}
|
||
/**
|
||
* 将图片转换为base64字符串
|
||
* @param imageUri 图片URI
|
||
* @returns Promise<string> base64字符串
|
||
*/
|
||
static async imageToBase64(imageUri: string): Promise<string> {
|
||
// 1. 验证URI有效性
|
||
if (!imageUri || !imageUri.startsWith('file://')) {
|
||
throw new Error('无效的图片URI,必须以file://开头');
|
||
}
|
||
let imageSource: image.ImageSource | undefined;
|
||
let pixelMap: image.PixelMap | undefined;
|
||
let imagePacker: image.ImagePacker | undefined;
|
||
try {
|
||
const file = fs.openSync(imageUri, fs.OpenMode.READ_ONLY);
|
||
const imageSource = image.createImageSource(file.fd);
|
||
if (!imageSource) {
|
||
throw new Error('创建ImageSource失败,请检查图片路径');
|
||
}
|
||
logger.info('正在获取图片信息...');
|
||
const imageInfo = await imageSource.getImageInfo();
|
||
logger.info(`图片尺寸: ${imageInfo.size.width}x${imageInfo.size.height}`);
|
||
pixelMap = await imageSource.createPixelMap({
|
||
desiredSize: {
|
||
width: imageInfo.size.width,
|
||
height: imageInfo.size.height
|
||
}
|
||
});
|
||
if (!pixelMap) {
|
||
throw new Error('创建PixelMap失败');
|
||
}
|
||
// 5. 压缩图片
|
||
imagePacker = image.createImagePacker();
|
||
const packOpts: image.PackingOption = {
|
||
format: "image/jpeg",
|
||
quality: 80 // 适当提高质量保证清晰度
|
||
};
|
||
logger.info('正在压缩图片...');
|
||
const arrayBuffer = await imagePacker.packing(pixelMap, packOpts);
|
||
const unit8Array = new Uint8Array(arrayBuffer);
|
||
let binary = '';
|
||
unit8Array.forEach(byte => {
|
||
binary += String.fromCharCode(byte);
|
||
});
|
||
const base64String = Base64Util.encodeToStrSync(binary);
|
||
logger.info(`图片转换成功,大小: ${Math.round(base64String.length / 1024)}KB`);
|
||
return base64String;
|
||
} catch (error) {
|
||
logger.error('图片处理失败: ' + JSON.stringify(error));
|
||
throw new Error(`图片处理失败: ${error.message}`);
|
||
} finally {
|
||
// 7. 确保释放资源
|
||
try {
|
||
pixelMap?.release();
|
||
imageSource?.release();
|
||
imagePacker?.release();
|
||
} catch (e) {
|
||
logger.error('资源释放异常: ' + JSON.stringify(e));
|
||
}
|
||
}
|
||
}
|
||
|
||
static isLetter(char: string): boolean {
|
||
if (char.length !== 1) return false;
|
||
const code = char.charCodeAt(0);
|
||
return (code >= 65 && code <= 90) || (code >= 97 && code <= 122);
|
||
}
|
||
static isFirstDigit(str: string): boolean {
|
||
if (str.length === 0) return false;
|
||
return i18n.Unicode.isDigit(str.charAt(0));
|
||
}
|
||
//判断是否有网络
|
||
static isOnline(): boolean {
|
||
return connection.hasDefaultNetSync();
|
||
}
|
||
//length转化为数字
|
||
static parseLengthToNumber(length: Length): number {
|
||
if (typeof length === "string") {
|
||
// 移除单位并转换
|
||
const numericPart = parseFloat(length.replace(/[^0-9.]/g, ''));
|
||
return isNaN(numericPart) ? 0 : numericPart;
|
||
}
|
||
return length as number; // 已经是数值类型
|
||
}
|
||
|
||
// 将HEX颜色转换为RGBA格式
|
||
static hexToRgba (hex: string, alpha: number) : string | ResourceStr {
|
||
const r = parseInt(hex.slice(1, 3), 16);
|
||
const g = parseInt(hex.slice(3, 5), 16);
|
||
const b = parseInt(hex.slice(5, 7), 16);
|
||
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
||
}
|
||
|
||
static stringIsUndefinedAndNull (string:string | undefined):boolean {
|
||
if (string == undefined || string == "null" || string == "<null>" || string == "(null)" || string == 'undefined' || string.length <= 0) {
|
||
return true
|
||
} else {
|
||
return false
|
||
}
|
||
}
|
||
} |