Trying to convert SVG file to PNG (COM Javascript)

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
MiM
Posts: 61
Joined: 20 Apr 2021, 04:31

Trying to convert SVG file to PNG (COM Javascript)

Post by MiM » 22 Sep 2022, 21:40

I'm trying to convert an SVG file to PNG (Base64 or hBitmap)
I decided to use JS, here's a working example with svg converted to B64 ~
https://jsitor.com/YAoz60cbc
i took pretty much all of it from stackoverflow.
(console log at the bottom spits out proper base64 png)

But in autohotkey ~

Code: Select all

#SingleInstance, Force

FileRead, svg, %<path to svg here>%
B64SVG := b64Encode(svg)

html_code =
(
<!DOCTYPE html>
<a id="result" href=""></a>

<script>
var svgString = "%B64SVG%"
function svgString2Image(svgString, width, height, format, callback) {
  format = format ? format : 'png';
  var svgData = 'data:image/svg+xml;charset=utf8;base64,' + svgString
  var canvas = document.createElement('canvas');
  canvas.width = width;
  canvas.height = height;
  var context = canvas.getContext('2d');
  // context.fillStyle = 'green'; // for testing
  // context.fillRect(1, 1, 50, 50); // for testing
  var image = new Image();
  image.onload = function () {
    context.clearRect(0, 0, width, height);
    context.drawImage(image, 0, 0, width, height);
    var pngData = canvas.toDataURL('image/' + format);
    callback(pngData);
  }
  image.src = pngData;
  var pngData = canvas.toDataURL('img/png');
  callback(pngData);
};

svgString2Image(svgString, 300, 300, 'png', function (pngData) {
  result.setAttribute("href", pngData);
});
</script>
)
Doc := ComObjCreate("HTMLFile")
Doc.write(html_code)
ClipBoard := Doc.querySelector("#result").href
Return

GuiClose:
ExitApp

B64Encode(string) { ; Thanks to "jNizM" ~ "https://github.com/jNizM/AHK_Scripts/blob/master/src/encoding_decoding/base64.ahk"
  VarSetCapacity(b, StrPut(string, "UTF-8")) && len := StrPut(string, &b, "UTF-8") - 1
  if !(DllCall("crypt32\CryptBinaryToString", "ptr", &b, "uint", len, "uint", 0x40000001, "ptr", 0, "uint*", size))
    Return "Failed"
  VarSetCapacity(buf, size << 1, 0)
  if !(DllCall("crypt32\CryptBinaryToString", "ptr", &b, "uint", len, "uint", 0x40000001, "ptr", &buf, "uint*", size))
    Return "Failed"
  Return StrGet(&buf)
}

for me personally, it spits out a blank 300x300 canvas, so i guess drawImage isn't working?
i'm on IE9 (i think), could that be the cause?

I'd like to make this way work but if someone has a different approach not using javascript i'll take it as well!

Notes:
I don't want to use any external tools (or large libraries if there are any) if possible.

I've been trying to figure this out for couple days now and came across WBImg.ahk
which has a similar idea but it doesn't seem to work for me.

I'm on windows 8.1 (please don't yell at me to update)

EDIT:
Eh so apparently it's a security issue with toDataURL :/

Code: Select all

#SingleInstance, Force

FileRead, svg, %<path to svg here>%
B64SVG := B64Encode(svg)

html_code =
(
<!DOCTYPE html>
<canvas id="CanvasID" width="200" height="200" style="border:1px solid black;">
<script>
  var SVGString = 'data:image/svg+xml;charset=utf8;base64,' + '%B64SVG%';
  const canvas = document.getElementById('CanvasID');
  ctx = canvas.getContext('2d');
  image = new Image();
  image.setAttribute('crossOrigin', 'anonymous');
  image.onload = function () {
    ctx.drawImage(image, 0, 0);
    alert(canvas.toDataURL('image/png')); // Security error here!
  };
  image.src = SVGString
</script>
)

Gui, Add, ActiveX, w300 h300 vDoc, HTMLFile
Doc.write(html_code)
Gui, Show
Return

GuiClose:
ExitApp

B64Encode(string) { ; Thanks to "jNizM" ~ "https://github.com/jNizM/AHK_Scripts/blob/master/src/encoding_decoding/base64.ahk"
  VarSetCapacity(b, StrPut(string, "UTF-8")) && len := StrPut(string, &b, "UTF-8") - 1
  if !(DllCall("crypt32\CryptBinaryToString", "ptr", &b, "uint", len, "uint", 0x40000001, "ptr", 0, "uint*", size))
    Return "Failed"
  VarSetCapacity(buf, size << 1, 0)
  if !(DllCall("crypt32\CryptBinaryToString", "ptr", &b, "uint", len, "uint", 0x40000001, "ptr", &buf, "uint*", size))
    Return "Failed"
  Return StrGet(&buf)
}

Return to “Ask for Help (v1)”