4 पॉइंट द्वारा GN⁺ 2024-12-04 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Skia Canvas Node.js में HTML Canvas ड्रॉइंग API को on-screen और off-screen rendering के लिए इस्तेमाल करने देता है, और Google Skia पर आधारित होने के कारण Chrome `<canvas>`` जैसा बहुत मिलता-जुलता output देता है
  • आउटपुट को PDF·SVG जैसे vector formats और JPEG·PNG·WEBP जैसे bitmap formats में export किया जा सकता है, और इसे file·dataURL·Buffer·Sharp object से जोड़ा जा सकता है
  • यह browser Canvas के दायरे से बाहर की क्षमताएँ भी संभालता है, जैसे GUI Window rendering, event framework, multi-page Canvas, path operations, 3D perspective transforms, CSS filter, और advanced typography control
  • asynchronous rendering और file I/O यूज़र द्वारा configure किए गए worker pool के native threads पर प्रोसेस होते हैं, इसलिए यह server-side image generation और serverless environments के लिए उपयुक्त है
  • benchmarks को serial और async modes में अलग-अलग मापा गया है, और async में कई repeated tasks को एक साथ शुरू करके multithreading प्रभाव की तुलना की जाती है

Node.js में इस्तेमाल होने वाला Canvas implementation

  • Skia Canvas Node.js के लिए HTML Canvas ड्रॉइंग API का implementation है, जो on-screen और off-screen rendering दोनों को support करता है
  • यह Google Skia graphics engine का उपयोग करता है, जिससे Chrome <canvas> element जैसा बहुत मिलता-जुलता परिणाम मिलता है
  • इसमें browser Canvas में अभी उपलब्ध न होने वाली सुविधाएँ भी शामिल हैं

आउटपुट formats और export के तरीके

  • image output में vector formats और bitmap formats दोनों supported हैं
    • vector: PDF, SVG
    • bitmap: JPEG, PNG, WEBP
  • Canvas output को कई destinations पर भेजा जा सकता है
    • file के रूप में save करना
    • dataURL string encoding
    • Buffer return करना
    • Sharp object return करना
  • interactive GUI Window पर सीधे draw किया जा सकता है, और browser-जैसा event framework भी दिया गया है

asynchronous rendering और multi-page support

  • rendering और file I/O native threads का उपयोग करने वाले worker pool में asynchronous तरीके से चलाए जाते हैं
    • worker pool को user configuration के अनुसार सेट किया जा सकता है
  • एक ही Canvas में multiple pages बनाई जा सकती हैं
    • एक single multi-page PDF के रूप में export किया जा सकता है
    • या अलग-अलग files में बँटी image sequence के रूप में save किया जा सकता है

browser Canvas से आगे की graphics capabilities

  • Bézier paths boolean operations और point-level interpolation को support करते हैं
  • transform features basic Canvas scale·rotation·translation के अलावा 3D perspective transform भी देती हैं
  • shape fill के लिए bitmap-based Pattern के साथ vector-based Texture भी इस्तेमाल किया जा सकता है
  • line drawing में custom marker जोड़ा जा सकता है
  • image processing पूरी CSS filter operator set को support करती है

typography control

  • text rendering multiple lines और automatic line wrapping को handle करता है
  • line-level text metrics देता है
  • small-caps, ligature जैसी OpenType features को standard font-variant syntax से इस्तेमाल किया जा सकता है
  • character spacing, word spacing, और leading को proportionally control किया जा सकता है
  • variable fonts को support करता है और weight values को transparently map करता है
  • local files से load किए गए non-system fonts भी इस्तेमाल किए जा सकते हैं

उपयोग के उदाहरण

  • image file generation के उदाहरण में Canvas बनाया जाता है और getContext("2d") से 2D context लेकर conic gradient को stroke style के रूप में इस्तेमाल करते हुए rectangle draw किया जाता है
    • saveAs("rainbox.png", {density:2}) से high-density image save की जाती है
    • canvas.png, canvas.toBuffer("png") का shorthand है
    • toDataURL("png") के result को HTML string के अंदर डाला जा सकता है
    • saveAsSync("rainbox.pdf") से main thread पर synchronous save भी संभव है
  • multi-page sequence के उदाहरण में canvas.newPage() से अलग-अलग रंगों वाले pages बनाए और save किए जाते हैं
    • all-pages.pdf के रूप में multi-page PDF save होती है
    • page-{2}.png pattern से page-01.png, page-02.png जैसी कई files बनती हैं
  • Window rendering के उदाहरण में Window(300, 300) बनाया जाता है और draw event में frame value के अनुसार line thickness बदलने वाला circle draw किया जाता है
  • Sharp.js integration के उदाहरण में Canvas output को Sharp object में बदलकर post-processing की जाती है, या Sharp से बनी image को loadImage से Canvas पर draw करने का flow दिखाया गया है

benchmark method और results

  • benchmark में Skia Canvas को दो modes में test किया गया है
    • serial: हर rendering task का इंतज़ार करने के बाद अगली repetition पर बढ़ा जाता है
    • async: सभी test repetitions एक साथ शुरू की जाती हैं और multithreading support के साथ parallel execution होता है
  • पूरा result canvas-benchmarks result page पर देखा जा सकता है
  • startup latency test में 100 repetitions के आधार पर skia-canvas ने प्रति run 1ms से कम, कुल 33ms दर्ज किया
    • canvaskit-wasm: प्रति run 25ms, कुल 2.47 सेकंड
    • canvas: प्रति run 88ms, कुल 8.77 सेकंड
    • @napi-rs/canvas: प्रति run 69ms, कुल 6.87 सेकंड
  • Bézier curves test में 20 repetitions के आधार पर async mode की parallel processing का अंतर साफ दिखता है
    • skia-canvas serial: प्रति run 137ms, कुल 2.74 सेकंड
    • skia-canvas async: प्रति run 28ms, कुल 558ms
    • comparison targets थे canvaskit-wasm 790ms, canvas 486ms, @napi-rs/canvas 230ms
  • SVG to PNG test में 100 repetitions के आधार पर canvaskit-wasm supported नहीं था, जबकि skia-canvas ने serial में प्रति run 58ms और async में प्रति run 11ms दर्ज किया
    • skia-canvas serial: कुल 5.83 सेकंड
    • skia-canvas async: कुल 1.08 सेकंड
  • image scale·rotation test के 50 repetitions के result
    • skia-canvas serial: प्रति run 100ms, कुल 5.00 सेकंड
    • skia-canvas async: प्रति run 19ms, कुल 935ms
  • basic text test के 200 repetitions के result
    • skia-canvas serial: प्रति run 21ms, कुल 4.26 सेकंड
    • skia-canvas async: प्रति run 4ms, कुल 819ms

1 टिप्पणियां

 
GN⁺ 2024-12-04
Hacker News की राय
  • https://windowjs.org भी काफी मिलता-जुलता concept है
    यह Skia को wrap करके Canvas API के रूप में expose करता है, लेकिन Node के बजाय v8 को embed कर बहुत छोटे runtime के तौर पर चलता है
    यह लगभग 3 साल पहले public किया गया मेरा पहला open-source project था, और WebGL, audio वगैरह expose करके इसे desktop के लिए JavaScript game platform बनाने की योजना भी थी, लेकिन दूसरे काम और projects की वजह से development रुक गया
    browser के बाहर भी Canvas इस्तेमाल करने देने वाले ऐसे project को देखकर अच्छा लगा

    • काफी अच्छा है, लेकिन अगर isolation जरूरी नहीं है तो सिर्फ v8 वाला environment थोड़ा खलता है
      कभी-कभी बस network request करना भी होता है
    • बढ़िया project है
      Node.js के बजाय सिर्फ V8 embed करने से binary size कितना कम होता है, यह जानने की उत्सुकता है
      Node.js भी V8 इस्तेमाल करता है, इसलिए यह भी जानना चाहूँगा कि Node binary size का बड़ा हिस्सा V8 से नहीं बल्कि runtime से आता है या नहीं
      website और GitHub repository देखी, लेकिन Window.js binary आम तौर पर कितने kB या MB की होती है, यह नहीं मिला
  • जिज्ञासा है कि ऐसी library का इस्तेमाल कहाँ होता है
    desktop पर shapes draw करने के लिए इससे बेहतर native libraries नहीं होतीं क्या, ऐसा लगता है

    • Soundslice में हम frontend JavaScript/Canvas से बनी custom sheet music rendering graphics library इस्तेमाल करते हैं
      server side पर भी vector PDF generate करने होते हैं, इसलिए HTML Canvas API इस्तेमाल करके PDF बना सकने वाली Node library इस्तेमाल करते हैं
      इससे अच्छा यह होता है कि web browser में render हुई sheet music और output बिल्कुल समान रहते हैं
      कुल मिलाकर ऐसी library browser के अलावा environments में भी code reuse संभव बनाती है
    • 2D drawing में Skia जितना powerful और जिसे आम तौर पर “native” कहा जा सके, ऐसी चीजें असल में ज्यादा नहीं हैं
      Skia का बड़ा फायदा native graphics का असरदार उपयोग करने में है, और browser engines में इसके इस्तेमाल होने की मूल वजह भी यही है
      ऊपर से target API एक ही होना भी फायदा है
    • portability इसका फायदा नहीं है क्या? GPU-accelerated 2D rendering libraries में और क्या-क्या है, जानना चाहूँगा
      एक ओर यह ज्यादा low-level है, लेकिन दूसरी ओर मैंने Puppeteer को 2D graphics library की तरह भी इस्तेमाल किया है
      Canvas 2D, WebGL, WebGPU और पूरा HTML/CSS मिल जाता है, और text effects, background images, CSS transforms भी इस्तेमाल कर सकते हैं
      images और videos load कर सकते हैं, और screenshot feature से compose किए गए result को image बना सकते हैं
      यह जरूरत से ज्यादा है, लेकिन मेरे use case में इससे फर्क नहीं पड़ा; यह चलता है, cross-platform है और समस्या हल कर देता है
    • अगर आप Canvas से बेहतर 2D graphics drawing API वाला platform बता सकें तो मुझे हैरानी होगी
      Skia Direct2D से थोड़ा तेज और Cairo से काफी तेज है
      यह बहुत optimize किया गया है और इसमें GPU-accelerated backend भी है
    • वही code कई platforms पर चला पाना बड़ा bonus है
      Canvas बहुत आम 2D drawing API भी है
      iOS में भी इसका native version है और Android में भी native version है, और drawing operations भी कुल मिलाकर मिलते-जुलते हैं
      इसका फायदा उठाने से काफी लाभ मिलता है
  • Skia में CanvasKit शामिल है, जो Node को support करने वाला WASM build है: https://www.npmjs.com/package/canvaskit-wasm, और यह module शायद Rust bindings है
    दोनों approaches के pros और cons जानने की उत्सुकता है

    • “Rust bindings” कहने से ज्यादा यह precompiled Node binary के करीब है
      बस internally यह Rust/C++ mixed codebase से generate हुआ है
      इसलिए मुख्य अंतर यह है कि WASM को अलग runtime चाहिए, जबकि Node binary को नहीं
  • क्या यह किसी Rust crate को wrap करने वाला wrapper जैसा है?
    https://rust-skia.github.io/doc/skia_safe/canvas/struct.Canvas.html

    • मेरी समझ में Skia Canvas bindings हों तो लगभग किसी भी programming language में चल सकता है https://www.swig.org/
      Node में कुछ खास अलग बात बहुत नहीं दिखती
    • हाँ, यह napi-rs से generated है
  • इसका लंबे समय से इंतजार था
    पहले इसी तरह की चीज करने की कोशिशों में Node-Gyp installation चाहिए होता था, जो सचमुच nightmare था

  • यह simple rendering API से ज्यादा है: इसमें लिखा है कि “OS native graphics pipeline से window में render कर सकता है और browser जैसा UI event framework देता है”
    WebGPU support के लिए wgpu और WebGL support के लिए ANGLE भी जोड़ा जा सकता है

    • Skia बहुत widely used library है; तुरंत याद आने वालों में Chrome, Firefox और LibreOffice इसका इस्तेमाल करते हैं
      यह WebGPU और ANGLE सहित कई rendering targets support करता है
    • यह Qt पहले से जो देता है, उससे काफी मिलता-जुलता है
      QPainter raw images और windows को संभालता है, और event support वाले ज्यादा refined widgets भी हैं
      और एक feature जिसे मैं काफी समय से ढूँढ रहा था: Qt में graphicsview है, जो window से बड़े graphics plane पर लाखों objects को resolution-independent तरीके से render कर सकता है और events भी handle कर सकता है
  • अगर Node-compatible Canvas implementations में interest है तो कुछ options हैं
    Skia project का canvaskit-wasm शायद GPU-accelerated नहीं है: https://github.com/google/skia/tree/main/modules/canvaskit/npm_build
    @napi-rs/canvas सबसे तेज binding है: https://github.com/Brooooooklyn/canvas?tab=readme-ov-file#performance
    node-canvas Skia के बजाय Cairo इस्तेमाल करता है: https://github.com/Automattic/node-canvas

  • Advent of Code में जब simple graphics window चाहिए होती है, तब मैं इसे अभी Deno के साथ इस्तेमाल कर रहा हूँ
    window-example भी है: https://skia-canvas.org/#rendering-to-a-window
    deno add npm:skia-canvas से add करें, deno.json में "nodeModulesDir": "auto" डालें और फिर deno install --allow-scripts चलाएँ

  • इसे देखकर सच में excitement हो रही है
    लगता है यह standalone चल सकने वाली और web-compatible graphics लिखना कहीं ज्यादा आसान बना देगा
    पहली scripting language के लिए library compile करने के लिए दूसरी scripting language से source से build और code generate करने की जरूरत भी नहीं रहेगी
    VS Code जैसी जगहों पर Canvas code को real-time render करने या web Canvas पर चलाने के लिए transformation layer वाले code को run करने में यह कितना fit बैठेगा, यह भी दिलचस्प होगा