h5图片压缩、uni-app 中h5图片压缩、
【代码】h5图片压缩、uni-app 中h5图片压缩、
·
你只需要使用下面recursionCompress 这个方法就好了、
import { recursionCompress } from '@/libs/tools';
recursionCompress(data , type, false).then(({base64,blobData}) => {
// 你的业务逻辑
});
提供ts和js版本、开发者可根据自己的版本来选择
第一个js版本 第二个ts版本。
data : 数据源 ( blob| base64)
status(boolean): 是否是uni的环境 默认不是
返回值包括压缩之后的 base64 和 blob流
使用者需要注意: blob 不能直接 img.src = blob
需要你转换一下URL.createObjectURL(blob) 这样才可以在图片上面显示
uni 中是没有img这个标签的,所以需要 new Image()创建
如果是app或者小程序 uni 提供uni.compressImage这方法了就不需要自己手写
为了让调用者直观感受 图片是否被压缩 提供 imageSize() 计算base64图片大小
因blob流本身具有size属性、所以不提供检查blob大小的方法
// base64转换为blob
const dataUrlToBlob = (base64) => {
let bytes = window.atob(base64.split(',')[1]);
let ab = new ArrayBuffer(bytes.length);
let ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], {type: 'image/jpeg'});
};
// blob转base64
export const blobToBase64 = (blob) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = (e) => {
resolve(e.target.result);
};
fileReader.readAsDataURL(blob);
fileReader.onerror = () => {
reject(new Error('blobToBase64 error'));
};
});
};
// base64计算图片大小
export const imageSize = (base64Str) => {
const indexBase64 = base64Str.indexOf('base64,');
if (indexBase64 < 0) return -1;
const str = base64Str.substr(indexBase64 + 6);
return (str.length * 0.75).toFixed(2);
};
// 图片压缩逻辑
const recursionCompressH5 = (blobUrl, quality, status) => {
let canvas = document.createElement('canvas');
return new Promise((resolve) => {
let blob, img;
// 如果不是uni 就正常创建
if (!status) {
img = document.createElement('img');
blob = URL.createObjectURL(blobUrl);
} else {
// uni的情况
img = new Image();
blob = URL.createObjectURL(blobUrl);
}
img.src = blob;
img.onload = () => {
let screenWidth = img.width;
let screenHeight = img.height;
canvas.width = screenWidth;
canvas.height = screenHeight;
let ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除画布
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
let imageData = canvas.toDataURL('image/jpeg', quality);
resolve(imageData);
};
});
};
/*
* data : 数据源
* status : 是否是uni的环境 默认不是
* */
export const recursionCompress = (data, status = false) => {
return new Promise(async (resolve) => {
if (typeof data === 'string') {
const result = await handlerBase64(data, status);
resolve(result);
// 处理base64
} else if (typeof data === 'object') {
const result = await handlerBlob(data, status);
resolve(result);
}
});
};
// 处理base64
const handlerBase64 = (data, status) => {
return new Promise(async (resolve) => {
// 如果是base64先转换为blob
const blob = dataUrlToBlob(data);
// 计算大小
const quality = checkMagnification(blob.size);
// 压缩之后的base64
const base64 = await recursionCompressH5(blob, quality, status);
// 压缩之后的blob
const blobData = dataUrlToBlob(base64);
resolve(
{
base64,
blobData
}
);
});
};
// 处理blob
const handlerBlob = (data, status) => {
return new Promise(async (resolve) => {
// 处理blob
const quality = checkMagnification(data.size);
// 压缩之后的base64
const base64 = await recursionCompressH5(data, quality, status);
// 压缩之后的blob
const blobData = dataUrlToBlob(base64);
resolve(
{
base64,
blobData
}
);
});
};
const checkMagnification = (size) => {
let resultSize = size / 1024 / 1024;
let quality = 1;
if (resultSize > 0 && resultSize <= 0.8) {
quality = 0.5;
} else if (resultSize >= 1 && resultSize <= 2) {
quality = 0.35;
} else if (resultSize > 2 && resultSize <= 8) {
quality = 0.2;
} else if (resultSize > 8) {
quality = 0.1;
}
return quality;
};
ts版本
// base64转换为blob
const dataUrlToBlob = (base64: string) => {
let bytes = window.atob(base64.split(',')[1]);
let ab = new ArrayBuffer(bytes.length);
let ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], {type: 'image/jpeg'});
};
// blob转base64
export const blobToBase64 = (blob: Blob) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = (e) => {
resolve(e.target?.result);
};
fileReader.readAsDataURL(blob);
fileReader.onerror = () => {
reject(new Error('blobToBase64 error'));
};
});
};
// base64计算图片大小
export const imageSize = (base64Str: string) => {
const indexBase64 = base64Str.indexOf('base64,');
if (indexBase64 < 0) return -1;
const str = base64Str.substr(indexBase64 + 6);
return (str.length * 0.75).toFixed(2);
};
// 图片压缩逻辑
const recursionCompressH5 = (blobUrl: Blob, quality: number, status: boolean): Promise<string> => {
let canvas = document.createElement('canvas');
return new Promise((resolve) => {
let blob, img: HTMLImageElement;
// 如果不是uni 就正常创建
if (!status) {
img = document.createElement('img');
blob = URL.createObjectURL(blobUrl);
} else {
// uni的情况
img = new Image();
blob = URL.createObjectURL(blobUrl);
}
img.src = blob;
img.onload = () => {
let screenWidth = img.width;
let screenHeight = img.height;
canvas.width = screenWidth;
canvas.height = screenHeight;
let ctx = canvas.getContext('2d');
ctx?.clearRect(0, 0, canvas.width, canvas.height); // 清除画布
ctx?.drawImage(img, 0, 0, canvas.width, canvas.height);
// 这里image/jpeg不可修改
let imageData = canvas.toDataURL('image/jpeg', quality);
resolve(imageData);
};
});
};
/*
* data : 数据源
* status : 是否是uni的环境 默认不是
* */
export const recursionCompress = (data: Blob | string, status = false): Promise<{ base64: string, blobData: Blob }> => {
return new Promise(async (resolve) => {
if (typeof data === 'string') {
const result = await handlerBase64(data, status);
resolve(result);
// 处理base64
} else if (typeof data === 'object') {
const result = await handlerBlob(data, status);
resolve(result);
}
});
};
// 处理blob
const handlerBlob = (data: Blob, status: boolean): Promise<{ base64: string, blobData: Blob }> => {
return new Promise(async (resolve) => {
// 处理blob
const quality = checkMagnification(data.size);
// 压缩之后的base64
const base64 = await recursionCompressH5(data, quality, status);
// 压缩之后的blob
const blobData = dataUrlToBlob(base64);
resolve(
{
base64,
blobData
}
);
})
}
// 处理base64
const handlerBase64 = (data: string, status: boolean): Promise<{ base64: string, blobData: Blob }> => {
return new Promise(async (resolve) => {
// 如果是base64先转换为blob
const blob = dataUrlToBlob(data);
// 计算大小
const quality = checkMagnification(blob.size);
// 压缩之后的base64
const base64 = await recursionCompressH5(blob, quality, status);
// 压缩之后的blob
const blobData = dataUrlToBlob(base64);
resolve(
{
base64,
blobData
}
)
})
}
// 压缩比重
const checkMagnification = (size: number) => {
let resultSize = size / 1024 / 1024;
let quality = 1;
if (resultSize > 0 && resultSize <= 0.8) {
quality = 0.5;
} else if (resultSize >= 1 && resultSize <= 2) {
quality = 0.35;
} else if (resultSize > 2 && resultSize <= 8) {
quality = 0.2;
} else if (resultSize > 8) {
quality = 0.1;
}
return quality;
};
更多推荐
已为社区贡献4条内容
所有评论(0)