Изображение Base64 не отображается, если не задано жестко или в setTimeout установлено значение 0 - PullRequest
0 голосов
/ 20 декабря 2018

Я конвертирую SVG в PNG, и он работает нормально, за исключением некоторого сверхъестественного поведения, когда установка src для изображения на значение b64 работает, только если вы установите его в setTimeout, равный 0. Если вы копируете значение b64 и жестко его кодируетекак SRC это также работает.Вот JS:

var testSVG = {
  height: 31.987199999999998,
  template: '<svg width="19.2" height="31.987199999999998" viewBox="0 0 149.39 248.95" xmlns="http://www.w3.org/2000/svg"><path fill="#c599fe" stroke="#000" stroke-miterlimit="10" stroke-width="5" d="M74.89,236.14c-5.35-26.25-14.78-48.1-26.2-68.35-8.47-15-18.29-28.88-27.37-43.45-3-4.86-5.65-10-8.56-15C6.94,99.2,2.21,87.5,2.51,72.32A68.92,68.92,0,0,1,13.28,35.88,71.31,71.31,0,0,1,63.34,3.32,75.55,75.55,0,0,1,112,12.53a70.38,70.38,0,0,1,24,23.22,68.1,68.1,0,0,1,10.9,36.32A67.12,67.12,0,0,1,144,92.82c-1.8,6-4.69,11-7.26,16.34-5,10.44-11.32,20-17.64,29.57C100.29,167.24,82.62,196.3,74.89,236.14Z"/><circle cx="74.69" cy="72.16" r="25.29"/></svg>',
 width: 19.2
}

// Pass in the testSVG object
var convertSVGtoBitmap = function (svgObject) {
  if(!svgObject) return null;

  var canvas = document.createElement("canvas");
  canvas.width = Math.ceil(svgObject.width);
  canvas.height = Math.ceil(svgObject.height);
  var ctx = canvas.getContext("2d");

  // Convert the SVG string into a base64 and append a header
  var svg = btoa(svgObject.template);
  var b64Start = 'data:image/svg+xml;base64,';
  var image64 = b64Start + svg;

  // Draw the SVG onto the canvas instance
  var img = new Image();
  img.src = image64;
  ctx.drawImage(img, 0, 0);

  // Return both svg base64 and png base64
  return {svg: image64, png: canvas.toDataURL()};
};

console.warn('test')
// Get SVG base64 stuff
var svgimg = document.createElement("img");
document.getElementById('svg-render').appendChild(svgimg);
svgimg.src = convertSVGtoBitmap(testSVG).svg;

// Get converted PNG base64 stuff
var pngimg = document.createElement("img");
document.getElementById('png-render').appendChild(pngimg);
setTimeout(function () {
  pngimg.src = convertSVGtoBitmap(testSVG).png;
}, 0)

Обратите внимание, это работает из-за setTimeout, равного 0. Если я изменяю его на pngimg.src = convertSVGtoBitmap(testSVG).png; без setTimeout, он не отображается.Если я сделаю pngimg.src = '...', где ... - это жестко закодированное значение b64, то оно также будет работать.Вот JSBin, если вы хотите возиться с ним.

https://jsbin.com/qecedev/2/edit?html,js,output

Я также попытался поместить его в document.ready из jQuery, а также добавить onload к объекту pngimg и добавить в него src.

1 Ответ

0 голосов
/ 20 декабря 2018

Я понял это.Проблемной областью было это

  // Draw the SVG onto the canvas instance
  var img = new Image();
  img.src = image64;
  ctx.drawImage(img, 0, 0);

  // Return both svg base64 and png base64
  return {svg: image64, png: canvas.toDataURL()};

Значение png в возврате еще не было загружено.Я конвертировал его для обратного вызова (вы могли бы использовать async или обещания тоже), и он начал работать.

// USE CALLBACK
var convertSVGtoBitmap = function (svgObject, callback) {
  if(!svgObject) return null;

  var canvas = document.createElement("canvas");
  canvas.width = Math.ceil(svgObject.width);
  canvas.height = Math.ceil(svgObject.height);
  var ctx = canvas.getContext("2d");

  var svg = btoa(svgObject.template);
  var b64Start = 'data:image/svg+xml;base64,';
  var image64 = b64Start + svg;

  var img = new Image();
  // WAIT FOR IMAGE TO LOAD
  img.onload = function () {
    ctx.drawImage(img, 0, 0);
    // NOW WE CAN RETURN VALUES!
    callback(image64, canvas.toDataURL());
  }
  img.src = image64;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...