blog
blog copied to clipboard
JS检测是否是heic(heif)格式
HEIC是一种容器格式,可以存储使用HEVC格式编码的声音和图像 ,相比jpg, 具有较小的文件大小和较高的图像质量 ;
Heic(HEIF)
,虽然有更小的体积, 但是H5
显示HEIC
格式的图片目前Chrome等浏览器还不支持自动解析,并且http
协议中Content-Type默认还没有image/heic
这个属性 (微信和钉钉打开该文件会自动转码,或者发送的时候系统底层会自动转码);
有些图片后缀是.jpg
格式,但其实是heic
格式(可以用记事本打开该图片看第一行是否有heic
文字),这时候图片上传根据后缀名来判断会失效,但是其实在手机中确可以预览,但是H5上传会出现问题;;
目前的解决方案有三:
1、前端判断格式,拒绝上传;
2、前端使用 heic2any 转码;
3、后端转码(推荐);
这里介绍判断heic
格式代码:
const BASE64_MARKER = ';base64,';
function convertDataURIToBinary(dataURI) {
const base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
const base64 = dataURI.substring(base64Index);
const raw = window.atob(base64);
const rawLength = raw.length;
const array = new Uint8Array(new ArrayBuffer(rawLength));
for(let i = 0; i < rawLength; i++) {
array[i] = raw.charCodeAt(i);
}
return array;
}
const reader = new FileReader();
// file ===> 文件对象
reader.readAsDataURL(file);
reader.onload = function read(e) {
const uint8Array = convertDataURIToBinary(img.src);
isHeic= hasHeic(uint8Array);
if(isHeic){
alert('不支持Heic格式文件上传');
}
...
};
以上代码可以使用Promise
进行包装;
如果有涉及到图片压缩,推荐在img.onerror
中提示:
const reader = new FileReader();
// file ===> 文件对象
reader.readAsDataURL(file);
reader.onload = function read(e) {
img.src = e.target.result;
};
return new Promise((resolve) => {
img.onload = function load() {
const context = canvas.getContext('2d');
...图片压缩
resolve(newPhoto);
};
img.onerror = (e) =>{
//如果是heic格式的图片
const uint8Array = convertDataURIToBinary(img.src);
isHeic= hasHeic(uint8Array);
//如果是heic格式的图片
resolve({
type:'error',
message:isHeic?'不支持Heic格式文件上传':'图片读取失败'
});
}
})