कंटेंट पर जाएँ
charmotion

PNG से ट्रांसपेरेंट एनिमेटेड GIF: हेलो, किनारे और बेहतर फ़ॉर्मेट

Charmotion टीम द्वारा · अपडेट:

गाइड का कवर इलस्ट्रेशन: PNG से ट्रांसपेरेंट एनिमेटेड GIF: हेलो, किनारे और बेहतर फ़ॉर्मेट, Charmotion के डेमो कैरेक्टर के साथ

हाँ, GIF ट्रांसपेरेंट हो सकता है, लेकिन सिर्फ़ 1-bit ट्रांसपेरेंसी के साथ: हर पिक्सेल या तो पूरी तरह ट्रांसपेरेंट होता है या पूरी तरह अपारदर्शी। PNG के सॉफ़्ट किनारों को ज़बरदस्ती इनमें से किसी एक तरफ़ धकेला जाता है, जिससे किनारे दाँतेदार हो जाते हैं या सफ़ेद और गहरे हेलो (किनारों पर रंग की परत) दिखते हैं। पहले किनारों को बैकग्राउंड के रंग पर फ़्लैटन करें, ffmpeg के palettegen और paletteuse से कन्वर्ट करें, या एनिमेटेड WebP, APNG या WebM पर स्विच करें।

मुख्य बातें

  • GIF पैलेट के एक रंग को पूरी तरह ट्रांसपेरेंट मार्क करता है; इसमें आंशिक ट्रांसपेरेंसी नहीं होती।
  • हेलो उन anti-aliased किनारे वाले पिक्सेल से आते हैं जो किसी दूसरे बैकग्राउंड के साथ ब्लेंड हुए थे।
  • अगर बैकग्राउंड पहले से पता है, तो किनारों को उसी रंग पर फ़्लैटन करें और सिर्फ़ हार्ड अल्फ़ा कटआउट रखें।
  • WebM सोर्स के साथ -c:v libvpx-vp9 को -i से पहले रखें, वरना ffmpeg अल्फ़ा हटा देता है।
  • APNG और एनिमेटेड WebP स्मूद अल्फ़ा बनाए रखते हैं और सभी प्रमुख ब्राउज़र में सपोर्टेड हैं; GIF का इस्तेमाल सिर्फ़ वहीं करें जहाँ वह ज़रूरी हो।

क्या GIF का बैकग्राउंड ट्रांसपेरेंट हो सकता है?

हाँ, लेकिन एक बड़ी सीमा के साथ। MDN की इमेज फ़ॉर्मेट गाइड बताती है कि GIF पिक्सेल "अपारदर्शी होते हैं, जब तक किसी खास कलर इंडेक्स को ट्रांसपेरेंट तय न किया जाए, और उस स्थिति में उस रंग वाले पिक्सेल पूरी तरह ट्रांसपेरेंट होते हैं।" यानी GIF में पैलेट की एक एंट्री आर-पार दिखने वाली होती है और बीच का कुछ नहीं। इसे 1-bit ट्रांसपेरेंसी कहा जाता है।

GIF हर फ़्रेम में ज़्यादा से ज़्यादा 256 रंगों के पैलेट तक सीमित है, इसलिए ग्रेडिएंट और सॉफ़्ट शैडो डिथर हो जाते हैं। एनिमेशन सीक्वेंस के लिए MDN की अपनी सलाह है कि इसकी जगह "WebP, AVIF या APNG पर विचार करें"।

हार्ड किनारों वाले फ़्लैट लोगो के लिए ट्रांसपेरेंट GIF ठीक दिख सकता है। लेकिन anti-aliased आउटलाइन, ड्रॉप शैडो या ग्लो वाले कैरेक्टर में इसके किनारे साफ़ नज़र आएँगे।

मेरे ट्रांसपेरेंट GIF में सफ़ेद या गहरा हेलो क्यों दिखता है?

क्योंकि आपके PNG के किनारे वाले पिक्सेल आंशिक रूप से ट्रांसपेरेंट हैं, और GIF इसे स्टोर नहीं कर सकता। स्मूद आउटलाइन में पिक्सेल का एक घेरा होता है, जैसे 30% या 70% opacity पर। कन्वर्ट करते समय इनमें से हर पिक्सेल को या तो पूरी तरह अपारदर्शी या पूरी तरह ट्रांसपेरेंट बनना पड़ता है।

  • अगर कन्वर्टर उन्हें अपारदर्शी रखता है, तो उनमें वही रंग रहता है जिसके साथ वे ब्लेंड हुए थे। अगर वह सफ़ेद था और आपका GIF गहरे पेज पर है, तो आपको एक सफ़ेद किनारी दिखेगी।
  • अगर वह उन्हें हटा देता है, तो आउटलाइन सीढ़ीनुमा हो जाती है।
ग्रेडिएंट पर अल्फ़ा चैनल वाले स्मूथ किनारे और one-bit GIF के टेढ़े-मेढ़े किनारे की ज़ूम की गई तुलना

कोई भी सेटिंग इसे पूरी तरह नहीं हटाती, क्योंकि GIF को जिस जानकारी की ज़रूरत है वह मौजूद ही नहीं है। उपाय ये हैं: किनारों को उस रंग के साथ ब्लेंड करें जिस पर GIF असल में दिखेगा, हार्ड कटआउट स्वीकार करें, या असली अल्फ़ा वाला फ़ॉर्मेट इस्तेमाल करें।

PNG को ट्रांसपेरेंट GIF में कैसे बदलें?

एक PNG के लिए ffmpeg एक पैलेट बनाता है जिसमें एक एंट्री ट्रांसपेरेंसी के लिए रिज़र्व होती है, फिर इमेज को उस पर मैप करता है। alpha_threshold कटऑफ़ तय करता है: इससे कम अल्फ़ा वाले पिक्सेल ट्रांसपेरेंट हो जाते हैं, बाकी अपारदर्शी। हमारे टेस्ट में इससे लोगो का ट्रांसपेरेंट हिस्सा पूरी तरह बना रहा।

ffmpeg -i logo.png -filter_complex "split[a][b];[a]palettegen=reserve_transparent=1[p];[b][p]paletteuse=alpha_threshold=128" logo.gif

PNG सीक्वेंस (frame_001.png, frame_002.png वगैरह) के रूप में एक्सपोर्ट किए गए एनिमेशन के लिए यही फ़िल्टर सभी फ़्रेम पर काम करता है। यह वर्ज़न 15 fps और 320 px चौड़ाई पर भी ले आता है, जिससे फ़ाइल छोटी रहती है:

ffmpeg -framerate 30 -i frame_%03d.png -filter_complex "fps=15,scale=320:-1:flags=lanczos,split[a][b];[a]palettegen=reserve_transparent=1[p];[b][p]paletteuse=alpha_threshold=128" -loop 0 character.gif

FFmpeg फ़िल्टर डॉक्स के अनुसार हर हिस्सा क्या करता है: palettegen=reserve_transparent=1 "ट्रांसपेरेंसी के लिए एक पैलेट एंट्री" रिज़र्व करता है; paletteuse=alpha_threshold=128 "ट्रांसपेरेंसी के लिए अल्फ़ा थ्रेशोल्ड" (0 से 255) सेट करता है; split एक इनपुट को दोनों स्टेप में भेजता है; -loop 0 हमेशा लूप करता है। ज़्यादा टाइट कटआउट के लिए थ्रेशोल्ड बढ़ाएँ, और सॉफ़्ट किनारे का ज़्यादा हिस्सा अपारदर्शी पिक्सेल के रूप में रखने के लिए इसे घटाएँ।

ffmpeg से ट्रांसपेरेंट WebM को GIF में कैसे बदलें?

वही फ़िल्टर चेन इस्तेमाल करें, बस एक अतिरिक्त फ़्लैग के साथ: -i से पहले -c:v libvpx-vp9। ffmpeg का बिल्ट-इन VP9 डिकोडर WebM के अल्फ़ा चैनल को नज़रअंदाज़ करता है; libvpx उसे पढ़ता है। हमारे टेस्ट में उसी कमांड से इस फ़्लैग के साथ 77% ट्रांसपेरेंट पिक्सेल वाला GIF बना, और इसके बिना 0%।

ffmpeg -c:v libvpx-vp9 -i character.webm -filter_complex "fps=15,scale=320:-1:flags=lanczos,split[a][b];[a]palettegen=reserve_transparent=1[p];[b][p]paletteuse=alpha_threshold=128" -loop 0 character.gif

अगर आपको पता है कि GIF हमेशा एक ही बैकग्राउंड रंग पर दिखेगा, जैसे सफ़ेद ईमेल या सफ़ेद स्लाइड, तो आप हार्ड कटआउट रखते हुए सॉफ़्ट किनारों को उस रंग पर फ़्लैटन करके हेलो से बच सकते हैं। यह कमांड कैरेक्टर को सफ़ेद पर कंपोज़िट करती है, फिर paletteuse के थ्रेशोल्ड के लिए ओरिजिनल अल्फ़ा वापस लगाती है:

ffmpeg -c:v libvpx-vp9 -i character.webm -filter_complex "[0:v]format=rgba,split=3[fg][al][sz];[sz]drawbox=c=white:t=fill[bg];[bg][fg]overlay[flat];[al]alphaextract[a];[flat][a]alphamerge,fps=15,scale=320:-1:flags=lanczos,split[x][y];[x]palettegen=reserve_transparent=1[p];[y][p]paletteuse=alpha_threshold=128" -loop 0 character-on-white.gif

c=white को अपने बैकग्राउंड रंग में बदलें। नतीजा उस रंग पर साफ़ दिखता है और दूसरे रंगों पर हेलो के साथ, इसलिए अगर कई बैकग्राउंड चाहिए तो हर बैकग्राउंड के लिए एक GIF बनाएँ।

WebP, APNG या WebM कब GIF से बेहतर हैं?

लगभग हमेशा, अगर डेस्टिनेशन उन्हें स्वीकार करता हो:

फ़ॉर्मेटTransparencyकहाँ काम आता है
GIF1-bitहर जगह, ईमेल क्लाइंट और GIF माँगने वाले प्लेटफ़ॉर्म (Twitch emotes, कई चैट ऐप) सहित
APNGपूरा 8-bit अल्फ़ासभी प्रमुख ब्राउज़र (MDN के अनुसार Chrome 59, Edge 79, Firefox 3, Opera 46, Safari 8); iMessage स्टिकर
Animated WebPपूरा alphaमॉडर्न ब्राउज़र; WhatsApp स्टिकर
VP9 WebMपूरा alphaChrome, Edge, Firefox; Safari इसे बिना alpha के चलाता है

GIF वहीं इस्तेमाल करें जहाँ वही एकमात्र विकल्प हो। वेबसाइट के लिए ट्रांसपेरेंट वीडियो की जोड़ी (पहले Safari के लिए HEVC MOV, फिर WebM) हल्की और ज़्यादा शार्प होती है; देखें वेबसाइट पर ट्रांसपेरेंट वीडियो। स्टिकर के लिए देखें ट्रांसपेरेंट WebM को स्टिकर फ़ॉर्मेट में बदलना।

क्या Charmotion सेट से ट्रांसपेरेंट GIF मिल सकता है?

सीधे नहीं। Charmotion के GIF सॉलिड बैकग्राउंड पर 480 px के प्रीव्यू हैं, जो चैट, डॉक्स और ईमेल के लिए हैं जहाँ बैकग्राउंड से कोई दिक्कत नहीं। Charmotion ट्रांसपेरेंट GIF एक्सपोर्ट नहीं करता, क्योंकि 1-bit GIF आपके कैरेक्टर के हर सॉफ़्ट किनारे पर ऊपर बताई गई हेलो की समस्या ले आएगा।

ट्रांसपेरेंसी पेड प्लान के ट्रांसपेरेंट वीडियो से आती है: एक WebM (VP9 alpha) और एक MOV (HEVC alpha), दोनों 1080×1080। अगर कोई प्लेटफ़ॉर्म ट्रांसपेरेंट GIF ही माँगे, तो ऊपर के कमांड में उस WebM को character.webm के रूप में इस्तेमाल करें, और उस जगह का मैट रंग चुनें जहाँ वह दिखेगा।

अक्सर पूछे जाने वाले सवाल

मेरा कन्वर्ट किया गया GIF ट्रांसपेरेंट की जगह काला क्यों है?

पैलेट स्टेप से पहले ही अल्फ़ा चैनल खो गया था। WebM सोर्स के साथ -c:v libvpx-vp9 को -i से पहले रखें ताकि ffmpeg अल्फ़ा पढ़ सके, और palettegen=reserve_transparent=1 इस्तेमाल करें।

ffmpeg के paletteuse में alpha_threshold क्या करता है?

यह तय करता है कि कौन से पिक्सेल ट्रांसपेरेंट होंगे। थ्रेशोल्ड (0 से 255, डिफ़ॉल्ट 128) से कम अल्फ़ा वाले पिक्सेल पूरी तरह ट्रांसपेरेंट हो जाते हैं और बाकी पूरी तरह अपारदर्शी, क्योंकि GIF बीच का कुछ भी स्टोर नहीं कर सकता। ज़्यादा वैल्यू कैरेक्टर के आसपास ज़्यादा टाइट कटआउट देती है।

क्या ट्रांसपेरेंट एनिमेशन के लिए APNG, GIF से बेहतर है?

आमतौर पर, हाँ। APNG पूरा अल्फ़ा सपोर्ट करता है, इसलिए सॉफ़्ट किनारे और शैडो स्मूद रहते हैं, और MDN के अनुसार Chrome, Edge, Firefox, Opera और Safari में इसका सपोर्ट है। GIF सिर्फ़ तब इस्तेमाल करें जब डेस्टिनेशन को उसकी ज़रूरत हो, जैसे Twitch emotes या पुराने ईमेल क्लाइंट।

इस गाइड से झटपट जवाब

स्रोत

संबंधित गाइड