π How to convert SVG to PNG with JavaScript [video version available]
This article describes how to convert SVG to PNG with frontend JavaScript. The related resources are as follows.
The workflow is as follows.
- Preparation for coding
- Coding
- Operation check
Run the following command in the terminal to prepare for coding.
mkdir javascript-svg-png
cd javascript-svg-png
touch index.html main.js
Open index.html in the editor and enter the following content.
Open main.js in the editor and enter the following content.
Open index.html in your browser. For macOS, it is convenient to run the following command in the terminal.
open index.html
Make sure you see the PNG image in the Output PNG Image section of your web page.
The sample source code contains the following sentence to convert SVG text to base64.
const svgDataBase64 = btoa(unescape(encodeURIComponent(svgData)))
I was curious about how it would be converted to base64 through the process, so I looked it up. The following is the SVG text before conversion.
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240" id="input">
<circle cx="120" cy="120" r="90" fill="#888888"/>
</svg>
Next, the following is the execution result of encodeURIComponent(svgData)
.
%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22240%22%20height%3D%22240%22%20id%3D%22input%22%3E%0A%20%20%20%20%20%20%20%20%3Ccircle%20cx%3D%22120%22%20cy%3D%22120%22%20r%3D%2290%22%20fill%3D%22%23888888%22%2F%3E%0A%20%20%20%20%20%20%3C%2Fsvg%3E
Next, the following is the execution result of unescape(encodeURIComponent(svgData))
.
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240" id="input">
<circle cx="120" cy="120" r="90" fill="#888888"/>
</svg>
Finally, the following is the execution result of btoa(unescape(encodeURIComponent(svgData)))
.
PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNDAiIGhlaWdodD0iMjQwIiBpZD0iaW5wdXQiPgogICAgICAgIDxjaXJjbGUgY3g9IjEyMCIgY3k9IjEyMCIgcj0iOTAiIGZpbGw9IiM4ODg4ODgiLz4KICAgICAgPC9zdmc+
btoa is a function that converts a string to Base64, but you cannot pass a string containing non-ASCII characters as an argument. Therefore, I use the encodeURIComponent function and the unescape function to convert non-ASCII characters to ASCII characters. For example, the Japanese hiragana "γ" is 0xE3 0x81 0x82 in UTF-8, so the result of encodeURIComponent ('γ')
is %E3%81%82 (By the way, in the case of encode ('γ')
Will raise a SyntaxError exception). On the other hand, the unescape function recognizes %E3 %81 %82 as 3 characters, so the result of unescape('%E3%81%82')
is'Γ£\x81\x82'.
I understand that the JavaScript btoa(unescape(encodeURIComponent(text)))
is similar to the Buffer.from(text).toString('base64')
in Node.js. So is it possible to convert from base64 to text with decodeURIComponent(escape(atob(base64)))
(same asBuffer.from(base64,'base64'). toString()
in Node.js? Is it something like that?). When I executed the code below, it was evaluated as "A", so it seems to be correct.
decodeURIComponent(escape(atob(btoa(unescape(encodeURIComponent('γ'))))))
I didn't always understand the reason and just copied and pasted it, so I got smarter because I had time to investigate. I hope this article helps anyone with similar questions. Thank you for reading!
@welpher
Thank you for your comment! Since your comment was interesting, I created the demo below and deployed it to Vercel.
https://github.com/tatsuyasusukida/svg-to-png
https://svg-to-png-nine.vercel.app/
As a result, I have confirmed that both methods are successful. I used Google Chrome, Firefox, and Safari on macOS.
Thank you for the motivation to check!