繁体   English   中英

从 JPG/PNG/... 图像生成 Base64 字符串在画布调整大小操作后返回纯白色图像

[英]Generation of Base64 string from JPG/PNG/... image returns plain white image after canvas resize operation

语境

我试图在调整大小后生成 JPG/PNG/... 图像的 Base64 字符串。 出于某种原因,生成的 Base64 字符串是纯白色图像的字符串。

假设

我对导致这种情况的原因的假设如下: <canvas width="X" height="Y"></canvas>似乎不包含 innerHTML,我希望它包含<img src="https://static.wixstatic.com/media/6068b5_b0d5df4c3d094694bb5d348eac41128d~mv2.jpg" crossorigin="anonymous">但是,我不明白为什么ctx.drawImage()不处理这个。

相关问题

其他几个人提出了这个问题,但不幸的是,提出的解决方案似乎并没有解决我的问题。 看:

  1. 渲染 base64 图像,目前返回空白
  2. 如何使用 JavaScript 将图像转换为 Base64 字符串?
  3. 如何在 HTML 中显示 Base64 图像?

最小工作示例

 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.w, dimensions.h); //issue: <canvas width="2075" height="3112"></canvas> has no innerHTML eg <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; }
 <body onload="init()"> </body>

能够将托管在不同域上的图像绘制到画布上

a) 网络服务器需要允许它并发送适当的标头

b) 您需要将图像的crossOrigin属性设置为"anonymous"

显然你自己已经想通了,因为你已经有了这条线

res.setAttribute('crossorigin', 'anonymous');

在你的代码中。

问题是它发生得太晚了 需要在为图像的src属性分配 URL 之前设置它。

所以只需在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, 0); //issue: <canvas width="2075" height="3112"></canvas> has no innerHTML eg <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; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM