SVGcode: रास्टर इमेज को SVG वेक्टर ग्राफ़िक में बदलने के लिए एक PWA

SVGcode एक प्रोग्रेसिव वेब ऐप्लिकेशन है. इसकी मदद से, JPG, PNG, GIF, WebP, AVIF वगैरह जैसी रास्टर इमेज को SVG फ़ॉर्मैट में वेक्टर ग्राफ़िक में बदला जा सकता है. यह File System Access API, Async Clipboard API, और File handling API का इस्तेमाल करता है. साथ ही, यह भी आपके हिसाब से विंडो कंट्रोल करने की सुविधा का इस्तेमाल करता है.

(अगर आप पढ़ने के बजाय देखना पसंद करते हैं, तो यह लेख वीडियो के तौर पर भी उपलब्ध है.)

रास्टर से सदिश तक

क्या आपने कभी किसी इमेज की लंबाई-चौड़ाई का अनुपात चुना है और आपको नतीजा पिक्सलेट नहीं किया गया था और ऐसा करने पर वह सही नहीं था? अगर ऐसा है, तो शायद आपने WebP, PNG या JPG जैसे रास्टर इमेज फ़ॉर्मैट का इस्तेमाल किया है.

रास्टर इमेज को बड़ा करके देखने पर वह पिक्सलेट दिखने लगता है.

इसके उलट, वेक्टर ग्राफ़िक ऐसे इमेज होते हैं जिन्हें निर्देशांक सिस्टम में पॉइंट से तय किया जाता है. इन बिंदुओं को लाइनों और वक्रों से जोड़ा जाता है, ताकि पॉलीगॉन और अन्य आकृतियां बनाई जा सकें. रास्टर ग्राफ़िक की तुलना में, वेक्टर ग्राफ़िक का एक फ़ायदा है, कि उन्हें पिक्सलेशन के बिना किसी भी रिज़ॉल्यूशन में स्केल किया जा सकता है और कम किया जा सकता है.

क्वालिटी में किसी तरह का नुकसान किए बिना वेक्टर इमेज को स्केल करना.

पेश है SVGcode

मैंने SVGcode नाम का एक PWA बनाया है जो रास्टर इमेज को वेक्टर में बदलने में आपकी मदद कर सकता है. क्रेडिट जहां क्रेडिट बकाया है: यह मैंने नहीं बनाया. SVGcode के साथ, मुझे पीटर सेलिंगर के Potrace नाम के कमांड लाइन टूल के साथ काम करना है. इस टूल को मैंने वेब असेंबली में बदल दिया है, इसलिए इसे वेब ऐप्लिकेशन में इस्तेमाल किया जा सकता है.

SVGcode ऐप्लिकेशन का स्क्रीनशॉट.
SVGcode ऐप्लिकेशन.

SVGcode का इस्तेमाल करना

सबसे पहले, आपको इस ऐप्लिकेशन को इस्तेमाल करने का तरीका बताना है. मैंने Chrome Dev Summit की टीज़र इमेज से शुरुआत की, जिसे मैंने ChromiumDev Twitter चैनल से डाउनलोड किया था. यह PNG रास्टर इमेज है. इसके बाद, इसे SVGcode ऐप्लिकेशन पर खींचें और छोड़ें. जब फ़ाइल को छोड़ा जाता है, तो ऐप्लिकेशन, इमेज के रंग को रंग से ट्रेस करता है. ऐसा तब तक होता है, जब तक इनपुट का वेक्टर वर्शन नहीं दिखता. अब इमेज को ज़ूम इन किया जा सकता है और जैसा कि आपको दिख रहा है, किनारे तेज़ बने हुए हैं. लेकिन Chrome के लोगो पर ज़ूम इन करने पर, आपको दिखेगा कि ट्रेसिंग सटीक नहीं थी, और खास तौर पर लोगो की आउटलाइन कुछ धब्बेदार दिख रही थी. मैं पांच पिक्सल तक के निशानों को दबाकर ट्रेसिंग को कम करके, इस नतीजे को बेहतर बना सकती हूं.

छोड़ी गई इमेज को SVG में बदलना.

SVGcode में पोस्टराइज़ेशन

वेक्टराइज़ेशन का एक अहम कदम, खास तौर पर फ़ोटोग्राफ़िक इमेज के लिए, इनपुट इमेज का प्रमोशन करना है. इससे कलर की संख्या कम हो जाती है. SVGcode की मदद से, हर कलर चैनल के हिसाब से ऐसा किया जा सकता है. साथ ही, बदलाव करने पर आपको SVG इमेज का फ़ॉर्मैट दिखेगा. नतीजे से खुश होने के बाद, मैं SVG को अपनी हार्ड डिस्क में सेव कर सकता हूं और जहां चाहें इसका इस्तेमाल कर सकता हूं.

रंगों की संख्या कम करने के लिए, इमेज को पोस्ट करना.

SVGcode में इस्तेमाल किए गए एपीआई

अब जब आपने देख लिया है कि यह ऐप्लिकेशन क्या-क्या कर सकता है, तो मैं आपको कुछ ऐसे एपीआई दिखाती हूँ जो इसे शानदार बनाने में मदद करते हैं.

प्रोग्रेसिव वेब ऐप्लिकेशन

SVGcode एक ऐसा प्रोग्रेसिव वेब ऐप्लिकेशन है जिसे इंस्टॉल किया जा सकता है. इसलिए, इसे पूरी तरह से ऑफ़लाइन चालू किया जा सकता है. यह ऐप्लिकेशन, Vite.js के लिए Vanilla JS टेंप्लेट पर आधारित है. साथ ही, यह लोकप्रिय Vite प्लगिन PWA का इस्तेमाल करता है. यह एक ऐसा सर्विस वर्कर बनाता है जो हुड में Workbox.js का इस्तेमाल करता है. Workbox, लाइब्रेरी का एक सेट है, जिससे प्रोग्रेसिव वेब ऐप्लिकेशन के लिए प्रोडक्शन के लिए तैयार सर्विस वर्कर को चलाया जा सकता है. ज़रूरी नहीं है कि यह पैटर्न सभी ऐप्लिकेशन के लिए काम करे, लेकिन SVGcode के इस्तेमाल के उदाहरण के लिए यह बहुत अच्छा है.

विंडो कंट्रोल ओवरले

उपलब्ध स्क्रीन रीयल एस्टेट का ज़्यादा से ज़्यादा फ़ायदा उठाने के लिए, SVGcode अपने मुख्य मेन्यू को टाइटलबार वाले हिस्से में ऊपर ले जाकर, विंडो कंट्रोल ओवरले को पसंद के मुताबिक बनाने की सुविधा का इस्तेमाल करता है. आपको यह ऐप्लिकेशन, इंस्टॉल होने की प्रक्रिया के आखिर में चालू होता हुआ देख सकता है.

SVGcode इंस्टॉल करना और विंडो कंट्रोल ओवरले को पसंद के मुताबिक बनाने की सुविधा चालू करना.

फ़ाइल सिस्टम को ऐक्सेस करने का एपीआई

इनपुट इमेज फ़ाइलों को खोलने और उनसे बनने वाले SVG को सेव करने के लिए, मैं File System Access API का इस्तेमाल करता/करती हूं. इससे मुझे पहले खोली गई फ़ाइलों का संदर्भ रखने और ऐप्लिकेशन को फिर से लोड करने के बाद भी वहीं से जारी रखने में मदद मिलती है जहां मैंने छोड़ा था. जब भी कोई इमेज सेव होती है, तो उसे svgo लाइब्रेरी की मदद से ऑप्टिमाइज़ किया जाता है. इसमें SVG की जटिलता पर निर्भर करते हुए, कुछ समय लग सकता है. फ़ाइल सेव करने का डायलॉग बॉक्स दिखाने के लिए, उपयोगकर्ता के जेस्चर की ज़रूरत होती है. इसलिए, SVG ऑप्टिमाइज़ेशन से पहले फ़ाइल हैंडल पाना ज़रूरी है, ताकि ऑप्टिमाइज़ किया गया SVG तैयार होने तक, उपयोगकर्ता के जेस्चर अमान्य न हों.

try {
  let svg = svgOutput.innerHTML;
  let handle = null;
  // To not consume the user gesture obtain the handle before preparing the
  // blob, which may take longer.
  if (supported) {
    handle = await showSaveFilePicker({
      types: [{description: 'SVG file', accept: {'image/svg+xml': ['.svg']}}],
    });
  }
  showToast(i18n.t('optimizingSVG'), Infinity);
  svg = await optimizeSVG(svg);
  showToast(i18n.t('savedSVG'));
  const blob = new Blob([svg], {type: 'image/svg+xml'});
  await fileSave(blob, {description: 'SVG file'}, handle);
} catch (err) {
  console.error(err.name, err.message);
  showToast(err.message);
}

खींचें और छोड़ें

इनपुट इमेज खोलने के लिए, आप या तो फ़ाइल खोलने की सुविधा का इस्तेमाल कर सकते हैं या जैसा कि आपने ऊपर देखा, बस इमेज फ़ाइल को खींचकर ऐप्लिकेशन पर छोड़ें. फ़ाइल खोलने की सुविधा बहुत आसान है. इसमें 'खींचें और छोड़ें' केस ज़्यादा दिलचस्प है. इसकी खास बात यह है कि आपको डेटा ट्रांसफ़र आइटम से, getAsFileSystemHandle() तरीके का इस्तेमाल करके फ़ाइल सिस्टम हैंडल मिल सकता है. जैसा कि हमने पहले बताया था, मेरे पास इस हैंडल को बनाए रखने का विकल्प है. इसलिए, ऐप्लिकेशन के फिर से लोड होने पर यह हैंडल इस्तेमाल के लिए तैयार रहेगा.

document.addEventListener('drop', async (event) => {
  event.preventDefault();
  dropContainer.classList.remove('dropenter');
  const item = event.dataTransfer.items[0];
  if (item.kind === 'file') {
    inputImage.addEventListener(
      'load',
      () => {
        URL.revokeObjectURL(blobURL);
      },
      {once: true},
    );
    const handle = await item.getAsFileSystemHandle();
    if (handle.kind !== 'file') {
      return;
    }
    const file = await handle.getFile();
    const blobURL = URL.createObjectURL(file);
    inputImage.src = blobURL;
    await set(FILE_HANDLE, handle);
  }
});

ज़्यादा जानकारी के लिए, File System Access API का लेख पढ़ें. अगर इसमें आपकी दिलचस्पी है, तो src/js/filesystem.js में जाकर SVGcode के सोर्स कोड के बारे में पढ़ें.

Async Clipboard API

SVGcode, Async Clipboard API की मदद से, ऑपरेटिंग सिस्टम के क्लिपबोर्ड के साथ भी पूरी तरह से इंटिग्रेट होता है. ऑपरेटिंग सिस्टम के फ़ाइल एक्सप्लोरर से इमेज चिपकाने के लिए, 'इमेज चिपकाएं' बटन पर क्लिक करें या कीबोर्ड पर कमांड या Control + v दबाएं.

फ़ाइल एक्सप्लोरर से किसी इमेज को SVGcode में चिपकाना.

Async Clipboard API को हाल ही में SVG इमेज का इस्तेमाल करने की सुविधा भी मिली है. इसलिए, किसी SVG इमेज को कॉपी करके भी उसे किसी दूसरे ऐप्लिकेशन में चिपकाया जा सकता है, ताकि आगे की प्रोसेसिंग की जा सके.

SVGcode से किसी इमेज को SVGOMG में कॉपी करना.
copyButton.addEventListener('click', async () => {
  let svg = svgOutput.innerHTML;
  showToast(i18n.t('optimizingSVG'), Infinity);
  svg = await optimizeSVG(svg);
  const textBlob = new Blob([svg], {type: 'text/plain'});
  const svgBlob = new Blob([svg], {type: 'image/svg+xml'});
  navigator.clipboard.write([
    new ClipboardItem({
      [svgBlob.type]: svgBlob,
      [textBlob.type]: textBlob,
    }),
  ]);
  showToast(i18n.t('copiedSVG'));
});

ज़्यादा जानने के लिए, एक साथ काम नहीं करने वाले क्लिपबोर्ड लेख को पढ़ें या फ़ाइल src/js/clipboard.js देखें.

फ़ाइल मैनेज करना

SVGcode की मेरी पसंदीदा सुविधाओं में से एक यह है कि यह ऑपरेटिंग सिस्टम के साथ कितनी अच्छी तरह से घुल-मिल जाता है. इंस्टॉल किए गए PWA के तौर पर, यह इमेज फ़ाइलों के लिए फ़ाइल हैंडलर या डिफ़ॉल्ट फ़ाइल हैंडलर भी बन सकता है. इसका मतलब है कि जब मैं अपने macOS मशीन पर Finder में हूं, तो किसी इमेज पर राइट क्लिक करके उसे SVGcode की मदद से खोला जा सकता है. इस सुविधा को फ़ाइल हैंडलिंग कहते हैं. यह सुविधा, वेब ऐप्लिकेशन मेनिफ़ेस्ट और लॉन्च सूची में file_handlings प्रॉपर्टी के हिसाब से काम करती है, जिससे ऐप्लिकेशन, पास की गई फ़ाइल का इस्तेमाल कर सकता है.

इंस्टॉल किए गए SVGcode ऐप्लिकेशन का इस्तेमाल करके, डेस्कटॉप से कोई फ़ाइल खोलना.
window.launchQueue.setConsumer(async (launchParams) => {
  if (!launchParams.files.length) {
    return;
  }
  for (const handle of launchParams.files) {
    const file = await handle.getFile();
    if (file.type.startsWith('image/')) {
      const blobURL = URL.createObjectURL(file);
      inputImage.addEventListener(
        'load',
        () => {
          URL.revokeObjectURL(blobURL);
        },
        {once: true},
      );
      inputImage.src = blobURL;
      await set(FILE_HANDLE, handle);
      return;
    }
  }
});

ज़्यादा जानकारी के लिए, इंस्टॉल किए गए वेब ऐप्लिकेशन को फ़ाइल हैंडलर बनने की अनुमति दें लेख पढ़ें. साथ ही, सोर्स कोड को src/js/filehandling.js में देखें.

वेब शेयर (फ़ाइलें)

ऑपरेटिंग सिस्टम के साथ डेटा ब्लेंड करने का एक और उदाहरण, ऐप्लिकेशन की शेयर करने की सुविधा भी है. यह मानते हुए कि मुझे SVGcode से बनाए गए किसी SVG में बदलाव करना है, इसे हल करने का एक तरीका यह होगा कि आप फ़ाइल को सेव करें, SVG एडिटिंग ऐप्लिकेशन लॉन्च करें, और फिर वहां से SVG फ़ाइल खोलें. हालांकि, एक आसान फ़्लो Web Share API का इस्तेमाल करता है, जिससे फ़ाइलों को सीधे शेयर किया जा सकता है. इसलिए, अगर SVG फ़ॉर्मैट में बदलाव करने के लिए इस्तेमाल होने वाला ऐप्लिकेशन टारगेट है, तो यह बिना किसी रुकावट के सीधे फ़ाइल पा सकता है.

shareSVGButton.addEventListener('click', async () => {
  let svg = svgOutput.innerHTML;
  svg = await optimizeSVG(svg);
  const suggestedFileName =
    getSuggestedFileName(await get(FILE_HANDLE)) || 'Untitled.svg';
  const file = new File([svg], suggestedFileName, { type: 'image/svg+xml' });
  const data = {
    files: [file],
  };
  if (navigator.canShare(data)) {
    try {
      await navigator.share(data);
    } catch (err) {
      if (err.name !== 'AbortError') {
        console.error(err.name, err.message);
      }
    }
  }
});
Gmail पर SVG इमेज शेयर की जा रही है.

वेब शेयर टारगेट (फ़ाइलें)

दूसरी तरफ़, SVGcode एक टारगेट टारगेट के तौर पर भी काम कर सकता है और दूसरे ऐप्लिकेशन से फ़ाइलें पा सकता है. इससे काम हो, इसके लिए ऐप्लिकेशन को Web Share Target API की मदद से, ऑपरेटिंग सिस्टम को यह बताना होगा कि वह किस तरह का डेटा स्वीकार कर सकता है. ऐसा वेब ऐप्लिकेशन मेनिफ़ेस्ट में खास तौर पर बनाए गए फ़ील्ड के ज़रिए होता है.

{
  "share_target": {
    "action": "https://svgco.de/share-target/",
    "method": "POST",
    "enctype": "multipart/form-data",
    "params": {
      "files": [
        {
          "name": "image",
          "accept": ["image/jpeg", "image/png", "image/webp", "image/gif"]
        }
      ]
    }
  }
}

action रूट असल में मौजूद नहीं है. हालांकि, इसे पूरी तरह से सर्विस वर्कर के fetch हैंडलर में हैंडल किया जाता है. इसके बाद, यह मिली फ़ाइलों को ऐप्लिकेशन में प्रोसेस करने के लिए आगे भेजता है.

self.addEventListener('fetch', (fetchEvent) => {
  if (
    fetchEvent.request.url.endsWith('/share-target/') &&
    fetchEvent.request.method === 'POST'
  ) {
    return fetchEvent.respondWith(
      (async () => {
        const formData = await fetchEvent.request.formData();
        const image = formData.get('image');
        const keys = await caches.keys();
        const mediaCache = await caches.open(
          keys.filter((key) => key.startsWith('media'))[0],
        );
        await mediaCache.put('shared-image', new Response(image));
        return Response.redirect('./?share-target', 303);
      })(),
    );
  }
});
SVGcode पर स्क्रीनशॉट शेयर किया जा रहा है.

नतीजा

ठीक है, हमने SVGcode में मौजूद ऐप्लिकेशन की कुछ बेहतर सुविधाओं के बारे में जानकारी दी है. हमें उम्मीद है कि Squoosh या SVGOMG जैसे अन्य शानदार ऐप्लिकेशन के साथ-साथ, यह ऐप्लिकेशन भी इमेज प्रोसेसिंग की आपकी ज़रूरतों के लिए एक ज़रूरी टूल बनेगा.

SVGcode svgco.de पर उपलब्ध है. देखो, मैंने वहां क्या किया? GitHub पर इसके सोर्स कोड की समीक्षा की जा सकती है. ध्यान दें कि Potrace के पास GPL का लाइसेंस है, इसलिए SVGcode का भी लाइसेंस है. इसके साथ ही, भावुक कर देने वाले लोगों को खुश करते हुए! हमें उम्मीद है कि SVGcode आपके लिए काम का होगा. इसकी कुछ सुविधाएं, आपके अगले ऐप्लिकेशन को बेहतर बनाने में मदद कर सकती हैं.

स्वीकार हैं

इस लेख की समीक्षा जो मेडली ने की है.