Да, есть: добавьте svg в свой документ и закодируйте все включенные изображения в dataURI.
Я пишу скрипт , который делает это, а также некоторые другие вещи, такие как включая внешние таблицы стилей и другое исправление того, где toDataURL не сработает (например, внешние элементы, на которые ссылаются атрибут xlink:href
или
).
Вот функция, которую я написал для разбора содержимого изображений: / g6]
function parseImages(){
var xlinkNS = "http://www.w3.org/1999/xlink";
var total, encoded;
// convert an external bitmap image to a dataURL
var toDataURL = function (image) {
var img = new Image();
// CORS workaround, this won't work in IE<11
// If you are sure you don't need it, remove the next line and the double onerror handler
// First try with crossorigin set, it should fire an error if not needed
img.crossOrigin = 'Anonymous';
img.onload = function () {
// we should now be able to draw it without tainting the canvas
var canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
// draw the loaded image
canvas.getContext('2d').drawImage(this, 0, 0);
// set our 's href attribute to the dataURL of our canvas
image.setAttributeNS(xlinkNS, 'href', canvas.toDataURL());
// that was the last one
if (++encoded === total) exportDoc();
};
// No CORS set in the response
img.onerror = function () {
// save the src
var oldSrc = this.src;
// there is an other problem
this.onerror = function () {
console.warn('failed to load an image at : ', this.src);
if (--total === encoded && encoded > 0) exportDoc();
};
// remove the crossorigin attribute
this.removeAttribute('crossorigin');
// retry
this.src = '';
this.src = oldSrc;
};
// load our external image into our img
img.src = image.getAttributeNS(xlinkNS, 'href');
};
// get an external svg doc to data String
var parseFromUrl = function(url, element){
var xhr = new XMLHttpRequest();
xhr.onload = function(){
if(this.status === 200){
var response = this.responseText || this.response;
var dataUrl = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(response);
element.setAttributeNS(xlinkNS, 'href', dataUrl);
if(++encoded === total) exportDoc();
}
// request failed with xhr, try as an
else{
toDataURL(element);
}
};
xhr.onerror = function(){toDataURL(element);};
xhr.open('GET', url);
xhr.send();
};
var images = svg.querySelectorAll('image');
total = images.length;
encoded = 0;
// loop through all our elements
for (var i = 0; i < images.length; i++) {
var href = images[i].getAttributeNS(xlinkNS, 'href');
// check if the image is external
if (href.indexOf('data:image') < 0){
// if it points to another svg element
if(href.indexOf('.svg') > 0){
parseFromUrl(href, images[i]);
}
else // a pixel image
toDataURL(images[i]);
}
// else increment our counter
else if (++encoded === total) exportDoc();
}
// if there were no element
if (total === 0) exportDoc();
}
Здесь svgDoc называется svg
, а функция exportDoc()
может быть просто записана как:
var exportDoc = function() {
// check if our svgNode has width and height properties set to absolute values
// otherwise, canvas won't be able to draw it
var bbox = svg.getBoundingClientRect();
if (svg.width.baseVal.unitType !== 1) svg.setAttribute('width', bbox.width);
if (svg.height.baseVal.unitType !== 1) svg.setAttribute('height', bbox.height);
// serialize our node
var svgData = (new XMLSerializer()).serializeToString(svg);
// remember to encode special chars
var svgURL = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData);
var svgImg = new Image();
svgImg.onload = function () {
var canvas = document.createElement('canvas');
// IE11 doesn't set a width on svg images...
canvas.width = this.width || bbox.width;
canvas.height = this.height || bbox.height;
canvas.getContext('2d').drawImage(svgImg, 0, 0, canvas.width, canvas.height);
doSomethingWith(canvas)
};
svgImg.src = svgURL;
};
Но еще раз вам придется добавить svg в документ сначала (либо через xhr, либо в элемент или
, и вы должны быть уверены, что все ваши ресурсы совместимы с CORS (или из того же домена), чтобы для получения этих изображений.
var svg = document.querySelector('svg');
var doSomethingWith = function(canvas) {
document.body.appendChild(canvas)
};
function parseImages() {
var xlinkNS = "http://www.w3.org/1999/xlink";
var total, encoded;
// convert an external bitmap image to a dataURL
var toDataURL = function(image) {
var img = new Image();
// CORS workaround, this won't work in IE<11
// If you are sure you don't need it, remove the next line and the double onerror handler
// First try with crossorigin set, it should fire an error if not needed
img.crossOrigin = 'anonymous';
img.onload = function() {
// we should now be able to draw it without tainting the canvas
var canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
// draw the loaded image
canvas.getContext('2d').drawImage(this, 0, 0);
// set our 's href attribute to the dataURL of our canvas
image.setAttributeNS(xlinkNS, 'href', canvas.toDataURL());
// that was the last one
if (++encoded === total) exportDoc();
};
// No CORS set in the response
img.onerror = function() {
// save the src
var oldSrc = this.src;
// there is an other problem
this.onerror = function() {
console.warn('failed to load an image at : ', this.src);
if (--total === encoded && encoded > 0) exportDoc();
};
// remove the crossorigin attribute
this.removeAttribute('crossorigin');
// retry
this.src = '';
this.src = oldSrc;
};
// load our external image into our img
var href = image.getAttributeNS(xlinkNS, 'href');
// really weird bug that appeared since this answer was first posted
// we need to force a no-cached request for the crossOrigin be applied
img.src = href + (href.indexOf('?') > -1 ? + '&1': '?1');
};
// get an external svg doc to data String
var parseFromUrl = function(url, element) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if (this.status === 200) {
var response = this.responseText || this.response;
var dataUrl = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(response);
element.setAttributeNS(xlinkNS, 'href', dataUrl);
if (++encoded === total) exportDoc();
}
// request failed with xhr, try as an
else {
toDataURL(element);
}
};
xhr.onerror = function() {
toDataURL(element);
};
xhr.open('GET', url);
xhr.send();
};
var images = svg.querySelectorAll('image');
total = images.length;
encoded = 0;
// loop through all our elements
for (var i = 0; i < images.length; i++) {
var href = images[i].getAttributeNS(xlinkNS, 'href');
// check if the image is external
if (href.indexOf('data:image') < 0) {
// if it points to another svg element
if (href.indexOf('.svg') > 0) {
parseFromUrl(href, images[i]);
} else // a pixel image
toDataURL(images[i]);
}
// else increment our counter
else if (++encoded === total) exportDoc();
}
// if there were no element
if (total === 0) exportDoc();
}
var exportDoc = function() {
// check if our svgNode has width and height properties set to absolute values
// otherwise, canvas won't be able to draw it
var bbox = svg.getBoundingClientRect();
if (svg.width.baseVal.unitType !== 1) svg.setAttribute('width', bbox.width);
if (svg.height.baseVal.unitType !== 1) svg.setAttribute('height', bbox.height);
// serialize our node
var svgData = (new XMLSerializer()).serializeToString(svg);
// remember to encode special chars
var svgURL = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData);
var svgImg = new Image();
svgImg.onload = function() {
var canvas = document.createElement('canvas');
// IE11 doesn't set a width on svg images...
canvas.width = this.width || bbox.width;
canvas.height = this.height || bbox.height;
canvas.getContext('2d').drawImage(svgImg, 0, 0, canvas.width, canvas.height);
doSomethingWith(canvas)
};
svgImg.src = svgURL;
};
window.onload = parseImages;
canvas {
border: 1px solid green !important;
}
Словарь алгоритмов и структур данных является довольно полным списком и включает в себя сложность (Big-O) в описании алгоритмов. Если вам нужна дополнительная информация, она будет в одной из связанных ссылок, и всегда есть запасной вариант Википедии.
книга Cormen больше об обучении Вас, как доказать то, чем Большой-O был бы для данного алгоритма, а не механического запоминания алгоритма к его Большой-O производительности. Первый намного более ценен, чем последний, и требует инвестиций с Вашей стороны.
Попробуйте" Введение в Алгоритмы " Cormen, Leisersen и Rivest. Если не там, который, вероятно, не стоит знать.
В C++ стандарты STL определяется Большими-O характеристиками алгоритмов, а также требований пространства. Тем путем Вы могли переключиться между конкурирующими реализациями STL и все еще знать, что Ваша программа имела характеристики времени выполнения того-же-выхода. Particularily хорошие реализации STL мог даже списки особого случая конкретных типов, чтобы быть лучше, чем стандартные требования.
Это облегчило выбирать корректный итератор или тип списка для конкретной проблемы, потому что Вы могли легко весить между потреблением пространства и скоростью.
Ofcourse Большой-O только направляющая линия, когда все константы удалены. Если бы алгоритм работает в k*O (n), это было бы классифицировано как O (n), но если k достаточно высок, это могло бы быть хуже, чем O (n^2) для некоторых значений n и m.
Введение в Алгоритмы, Второй Выпуск , иначе СБРАСЫВАЕТ (Cormen, Leiserson, Rivest, Глиняная кружка), самая близкая вещь, о которой я могу думать.
, Если это перестало работать, то попробуйте Искусство Программирования Knuth. Если это не находится в тех, вероятно, необходимо провести некоторое реальное исследование.