如何解决画布调整大小操作后,从JPG / PNG / ...生成Base64字符串会返回纯白色图像
上下文
我正在尝试在调整大小后生成JPG / PNG / ...图像的Base64字符串。由于某种原因,生成的Base64字符串是纯白色图像的字符串。
假设
我对造成这种情况的假设如下:<canvas width="X" height="Y"></canvas>
似乎不包含innerHTML,我希望它包含<img src="https://static.wixstatic.com/media/6068b5_b0d5df4c3d094694bb5d348eac41128d~mv2.jpg" crossorigin="anonymous">
。但是,我不知道为什么{{1} }无法处理。
相关问题
其他几个人提出了这个问题,但是不幸的是,提出的解决方案似乎并没有解决我的问题。参见:
- Rendering a base64 image,currently comes back as blank
- How can I convert an image into Base64 string using JavaScript?
- How to display Base64 images in HTML?
最小工作示例
ctx.drawImage()
async function init(){
//getDataUrl
var dataUrl = await getDataUrl("https://static.wixstatic.com/media/6068b5_5888cb03ab9643febc221f3e6788d656~mv2.jpg");
console.log(dataUrl); //returns string,but white image?
//Create new image on body tag with dataurl
addBase64Image(dataUrl);
}
function getImageDimensions(file) {
return new Promise (function (resolved,rejected) {
var i = new Image()
i.onload = function(){
resolved({w: i.width,h: i.height})
};
i.src = file
})
}
async function getDataUrl(img_url) {
// Create canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
var dimensions = await getImageDimensions(img_url);
console.log(dimensions);
// Set width and height
canvas.width = dimensions.w; //img_url.width
canvas.height = dimensions.h; //img_url.height
var res = await loadImage(ctx,img_url,dimensions.w,dimensions.h);
console.log(res);
res.setAttribute('crossorigin','anonymous');
ctx.drawImage(res,dimensions.h); //issue: <canvas width="2075" height="3112"></canvas> has no innerHTML e.g. <img src="https://static.wixstatic.com/media/6068b5_b0d5df4c3d094694bb5d348eac41128d~mv2.jpg" crossorigin="anonymous">
console.log(canvas);
console.log(ctx);
dataurl = canvas.toDataURL('image/png');
return dataurl;
}
function loadImage(context,path,dimx,dimy){
return new Promise(function(resolve,reject){
var img=new Image();
img.onload = function() {
resolve.call(null,img);
};
img.src=path;
});
}
function calculateAspectRatioFit(srcWidth,srcHeight,maxWidth,maxHeight) {
var ratio = Math.min(maxWidth / srcWidth,maxHeight / srcHeight);
return { width: srcWidth*ratio,height: srcHeight*ratio };
}
async function addBase64Image(img_dataurl){
var dimensions = await getImageDimensions(img_dataurl);
console.log(dimensions);
var res = calculateAspectRatioFit(dimensions.w,dimensions.h,512,512);
console.log(res);
var image = document.createElement("img");
var imageParent = document.querySelector('body');
image.id = "user_upload";
image.width = res.width;
image.height = res.height;
image.src = img_dataurl;
imageParent.appendChild(image);
}
body {
margin: 0px;
}
#user_upload {
display: block;
margin-left: auto;
margin-right: auto;
border: 2.5px solid;
}
解决方法
为了能够将托管在其他域上的图像绘制到画布上
a)网络服务器需要允许它并发送适当的标头
b)您需要将图片的crossOrigin
属性设置为"anonymous"
很显然,您已经知道了这一点,因为您已经知道了这一点
res.setAttribute('crossorigin','anonymous');
在您的代码中。
问题是它也发生在后期。需要在为图像的src
属性分配URL之前进行设置。
因此,只需在调用{p>之前,将以上行移动到loadImage()
函数中
img.src=path;
这是一个例子:
async function init() {
//getDataUrl
var dataUrl = await getDataUrl("https://static.wixstatic.com/media/6068b5_5888cb03ab9643febc221f3e6788d656~mv2.jpg");
console.log(dataUrl); //returns string,but white image?
//Create new image on body tag with dataurl
addBase64Image(dataUrl);
}
function getImageDimensions(file) {
return new Promise(function(resolved,rejected) {
var i = new Image()
i.onload = function() {
resolved({
w: i.width,h: i.height
})
};
i.src = file
})
}
async function getDataUrl(img_url) {
// Create canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
var dimensions = await getImageDimensions(img_url);
console.log(dimensions);
// Set width and height
canvas.width = dimensions.w; //img_url.width
canvas.height = dimensions.h; //img_url.height
var res = await loadImage(ctx,img_url,dimensions.w,dimensions.h);
console.log("asd ",res);
ctx.drawImage(res,0); //issue: <canvas width="2075" height="3112"></canvas> has no innerHTML e.g. <img src="https://static.wixstatic.com/media/6068b5_b0d5df4c3d094694bb5d348eac41128d~mv2.jpg" crossorigin="anonymous">
console.log(canvas);
console.log(ctx);
dataurl = canvas.toDataURL('image/png');
return dataurl;
}
function loadImage(context,path,dimx,dimy) {
return new Promise(function(resolve,reject) {
var img = new Image();
img.onload = function() {
resolve.call(null,img);
};
img.setAttribute('crossorigin','anonymous');
img.src = path;
});
}
function calculateAspectRatioFit(srcWidth,srcHeight,maxWidth,maxHeight) {
var ratio = Math.min(maxWidth / srcWidth,maxHeight / srcHeight);
return {
width: srcWidth * ratio,height: srcHeight * ratio
};
}
async function addBase64Image(img_dataurl) {
var dimensions = await getImageDimensions(img_dataurl);
console.log(dimensions);
var res = calculateAspectRatioFit(dimensions.w,dimensions.h,512,512);
console.log(res);
var image = document.createElement("img");
var imageParent = document.querySelector('body');
image.id = "user_upload";
image.width = res.width;
image.height = res.height;
image.src = img_dataurl;
imageParent.appendChild(image);
}
init();
body {
margin: 0px;
}
#user_upload {
display: block;
margin-left: auto;
margin-right: auto;
border: 2.5px solid;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。