I am building a web app using asp.net-core with angular 4 templates and uses svg-edit to allow user to draw / load / save images on mobile devices particularly on the IOS devices / android devices. The svg-edit works well for what I need but I've encounter an issue on the IOS devices regarding to generate/ convert the user drawing (svg) into another format (png base64) which will be POST to the api as part of the saving process.
I use the following code which uses html canvas to convert the svg into png base64
svg-editor.js
editor.getDrawingPngBase64 = function (svgString) {
if (!$('#export_canvas').length) {
$('<canvas>', { id: 'export_canvas' }).hide().appendTo('body');
}
var canvas = $('#export_canvas')[0];
canvas.width = $("#svgcanvas").width(); // svgCanvas.contentW;
canvas.height = $("#svgcanvas").height(); // svgCanvas.contentH;
var ctx = canvas.getContext("2d");
var promise = new Promise(function (resolve, reject) {
function drawInlineSVG(ctx, rawSVG, callback) {
var svg = new Blob([rawSVG], { type: "image/svg+xml;charset=utf-8" }),
domURL = self.URL || self.webkitURL || self,
url = domURL.createObjectURL(svg),
img = new Image;
img.onload = function () {
ctx.drawImage(this, 0, 0);
var base64 = canvas.toDataURL("image/png");
resolve(base64);
};
img.src = url;
}
drawInlineSVG(ctx, svgString);
});
return promise;
}
However, this only works sometime on the IOS device using chrome or safari browser. The onload method simply not getting called. I am guessing the svg image could be too big for it to convert.
I have also tried this method which doesn't work reliably either....
editor.getDrawingPngBase64 = function (svgString) {
if (!$('#export_canvas').length) {
$('<canvas>', { id: 'export_canvas' }).hide().appendTo('body');
}
var canvas = $('#export_canvas')[0];
canvas.width = svgCanvas.contentW;
canvas.height = svgCanvas.contentH;
var ctx = canvas.getContext("2d");
var promise = new Promise(function (resolve, reject) {
function webkitNamespaceBugWorkaround(pText) {
var lText = pText.replace(/\ xlink=/g, " xmlns:xlink=", "g");
lText = lText.replace(/\ href=/g, " xlink:href=", "g");
return lText;
}
canvg(canvas, webkitNamespaceBugWorkaround(svgString), {
renderCallback: function () {
var base64 = canvas.toDataURL("image/png");
resolve(base64);
}
});
});
return promise;
}
I have also tried canvg library and it does not work reliably either
These method is called by the angular4 component.ts
public save() {
const svgString: String = svgEditor.getSvgString();
(<any>window).svgEditor.getDrawingPngBase64(svgString).then(pngBase64: string) => {
// Call api and save the image
}
}
The reason I am converting svg to png on the client side is because I am not able to install the C# SVG Rendering library on dotnet-core solution (https://www.nuget.org/packages/Svg/)
Please help!
I had this exact same issue previously on a dotnetcore solution except I was not using svg-edit. Here's my workaround solution for this problem....
Create a new console app using dotnet framework...and install the Svg library on the package manager
In Program.cs for the console app, read the svg file and uses the Svg library to convert it to png and output it using Console.WriteLine
In your dotnet-core side, you need to post the SVG back to the api, save it on the server, run the consoleApp.exe as a process and read the base64 from the StandardOutput.