(适用于react+ts)
第一种
<FontAwesomeIcon
icon={faDownload}
onClick={() => this.downloadCurrentImage()}
className="ImageFrame-downloadIcon"
/>
private downloadCurrentImage() {
const image = new Image();
image.crossOrigin = "anonymous";
image.onload = () => {
const canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
const context = canvas.getContext("2d") as CanvasRenderingContext2D;
context.drawImage(image, 0, 0, image.width, image.height);
const url = canvas.toDataURL("image/png");
const a = document.createElement("a");
a.download = "a.png"
a.href = url;
a.click();
};
image.src = XXXXX;
}
存在的问题 a.download 只兼容firefox和chrome. 在IE浏览器中无效果
然后我尝试了判断浏览器,如果是IE和microSoft Edge, 就用window.open(url)
/** get current browser */
private getBrowser() {
const userAgent = navigator.userAgent;
const browserArr = ["Opera", "IE", "Edge", "FF", "Safari", "Chrome"];
const isOpera = userAgent.includes("Opera");
//IE
const isIE = userAgent.includes("compatible") && userAgent.includes("MSIE") && !isOpera;
const isEdge = userAgent.includes("Edge");
const isFF = userAgent.includes("Firefox");
// safari
const isSafari = userAgent.includes("Safari") && !userAgent.includes("Chrome");
// chrome
const isChrome = userAgent.includes("Chrome") && userAgent.includes("Safari");
const agentArr = [isOpera, isIE, isEdge, isFF, isSafari, isChrome];
for (let i = 0; i < agentArr.length; i++) {
if (agentArr[i] === true) {
return browserArr[i];
}
}
}
const currentBrowser = this.getBrowser()
if(currentBrowser === "IE" ||currentBrowser === "Edge") {
//直接打开图片的路径
window.open(XXXX)
}
但是并没有解决根本问题, 我从网上查了很多资料,最终完成了功能,仅此记录
//触发下载事件
<div onClick={() => this.downloadCurrentImage()} />
/**download current image as PNG */
private downloadCurrentImage() {
const browserName = this.getBrowser();
const {id} = {...this.props};
//在我的项目中获取imageSrc是这样的,请根据自己的项目内容来写;
const imageSrc = this.props.imageUrlProvider.getImageUrl(this.props.id);
this.convertUrlToBase64(imageSrc).then((base64) => {
if (browserName === "IE" || browserName === "Edge") {
const blob = this.convertBase64UrlToBlob(base64 as string);
//第二个参数是下载文件名
window.navigator.msSaveBlob(blob, `${id}.png`);
} else {
const a = document.createElement("a");
//下载文件名:我是用id
a.download = `${id}.png`;
a.href = imageSrc;
a.click();
}
});
}
/**
* convert image's url to base64
* @param url `string` image's url
*/
private convertUrlToBase64(url: string) {
return new Promise((resolve, reject) => {
const images = new Image();
images.crossOrigin = "Anonymous";
images.onload = () => {
const canvas = document.createElement("canvas");
canvas.width = images.width;
canvas.height = images.height;
const ctx = canvas.getContext("2d") as CanvasRenderingContext2D;
ctx.drawImage(images, 0, 0, images.width, images.height);
resolve(canvas.toDataURL("image/png", 1));
};
images.onerror = () => {
reject(new Error("get image error"));
};
images.src = url;
});
}
/**
* convert image's base64 url to Blob
* @param base64`string` image's base64 url
*/
private convertBase64UrlToBlob(base64: string) {
//baseArr[0]: head of base64, image's type(eg: "image/png")
const baseArr = base64.split(",");
//baseArr[1]: after removing the head of base64, the rest of content
const newCode = window.atob(baseArr[1]);
const newArr = new Uint8Array(newCode.length);
for (let i = 0; i < newCode.length; i++) {
newArr[i] = newCode.charCodeAt(i);
}
//type可以根据需求修改
return new Blob([newArr], {type: "image/png"});
}
/** get current browser */
private getBrowser() {
const userAgent = navigator.userAgent;
const browserArr = ["Opera", "IE", "Edge", "FF", "Safari", "Chrome"];
const isOpera = userAgent.includes("Opera");
//IE
const isIE = userAgent.includes("compatible") && userAgent.includes("MSIE") && !isOpera;
const isEdge = userAgent.includes("Edge");
const isFF = userAgent.includes("Firefox");
// safari
const isSafari = userAgent.includes("Safari") && !userAgent.includes("Chrome");
// chrome
const isChrome = userAgent.includes("Chrome") && userAgent.includes("Safari");
const agentArr = [isOpera, isIE, isEdge, isFF, isSafari, isChrome];
for (let i = 0; i < agentArr.length; i++) {
if (agentArr[i] === true) {
return browserArr[i];
}
}
}
这种能够解决下载图片的效果,使用a标签的download属性时,无法识别 " / " " :"这样的符号,所以如果你命名时带这样的符号,下载出来的文件里面要么显示" _ " 要么显示空格,暂时没找到方法解决,所以尽量避免用 这种符号
欢迎大佬指导
参考文章:
js 通过 blob 类文件对象下载图片,修改图片保存的名字(兼容式写法)
js 图片 base64 与 blob 与 img实例 互相转换