मेमोरी को बचाने के लिए कौन सा छवि प्रारूप अधिक कुशल है? PNG, JPEG, या GIF?
मेमोरी को बचाने के लिए कौन सा छवि प्रारूप अधिक कुशल है? PNG, JPEG, या GIF?
जवाबों:
"मेमोरी" और "दक्षता" आमतौर पर दुरुपयोग की शर्तें हैं, इसलिए मैं आपको चार अलग-अलग तत्वों के लिए एक उत्तर दूंगा जो आपके गेम के प्रदर्शन को प्रभावित कर सकते हैं।
मैं इसे छोटा और संक्षिप्त रखने के लिए बहुत सी चीजों की देखरेख करूंगा, लेकिन नीचे दिए गए इस पाठ में कई गलतियां हैं, इसलिए इसे एक चुटकी नमक के साथ लें। हालांकि, मुख्य अवधारणाओं को समझना चाहिए।
भंडारण
यह वह आकार है जो आपके चित्र आपके सॉफ़्टवेयर वितरण पर उपभोग करते हैं। आपके संसाधनों की खपत जितनी अधिक होगी, डाउनलोड (आपकी वेबसाइट से) उतना ही लंबा होगा। यदि आप सीडी या डीवीडी जैसे भौतिक मीडिया पर वितरित कर रहे हैं, तो आप शायद इस मोर्चे पर कुछ गंभीर अनुकूलन करने जा रहे हैं।
सामान्य तौर पर, JPEG उन तस्वीरों और छवियों के लिए सबसे अच्छा कंप्रेस करता है जिनमें कोई तेज बॉर्डर नहीं है। हालांकि, आपकी छवियों की गुणवत्ता में गिरावट आई है क्योंकि JPEG हानिपूर्ण संपीड़न का उपयोग करता है (आप JPEG के रूप में छवियों को निर्यात करते समय संपीड़न स्तर / गिरावट को ठीक कर सकते हैं। इस पर अधिक जानकारी के लिए अपने इमेजिंग सॉफ़्टवेयर के दस्तावेज़ देखें)।
हालाँकि, JPEG जितना अच्छा हो सकता है, यह पारदर्शिता का समर्थन नहीं करता है । यह महत्वपूर्ण है यदि आप ऐसी छवियां रखना चाहते हैं जो दूसरों के माध्यम से दिखती हैं, या यदि आप अनियमित आकृतियों वाली छवियां चाहते हैं। जीआईएफ एक अच्छा विकल्प है, लेकिन यह काफी हद तक पीएनजी द्वारा अधिगृहीत किया गया है (जीआईएफ का समर्थन करने वाली कुछ ही चीजें हैं जो पीएनजी नहीं करती हैं, लेकिन वे गेम प्रोग्रामिंग में काफी हद तक अप्रासंगिक हैं)।
पीएनजी पारदर्शिता (और सेमीट्रांसपेरेंसी) का समर्थन करता है, गुणवत्ता में गिरावट के बिना डेटा को संपीड़ित करता है (यानी यह दोषरहित संपीड़न का उपयोग करता है), और काफी अच्छी तरह से संपीड़ित करता है, लेकिन जेपीजी के जितना नहीं।
समस्या तब पैदा होती है जब आपको अच्छे संपीड़न, साथ ही पारदर्शिता की आवश्यकता होती है। आप थोड़ा अवक्रमित छवियों कोई आपत्ति नहीं है, तो आप इस तरह के रूप पीएनजी परिमाणीकरण कार्यक्रमों का उपयोग कर सकते pngquant है, जो आपको ऑनलाइन परीक्षण कर सकते हैं TinyPNG । ध्यान रखें कि अपने आप पर परिमाणीकरण द्वारा किया गया चित्र क्षरण JPEG (जिसमें परिमाणीकरण के साथ-साथ अन्य आक्रामक तकनीक भी शामिल है) की तुलना में भिन्न है, इसलिए दोनों को विभिन्न प्रकार की सेटिंग्स के साथ आज़माना सुनिश्चित करें।
यदि आप अपने वितरण आकार को आक्रामक रूप से कम करना चाहते हैं, तो आप इस तरह से प्रत्येक छवि को मैन्युअल रूप से संसाधित कर सकते हैं:
if the image has transparency then
try pngquant on the image
if the results are not satisfactory then
revert to the non-quantized image
end
store as PNG
else
try storing it as JPG with different quality settings
if no single setting yields an image of an acceptable quality then
try pngquant on the image
if the results are not satisfactory then
revert to the non-quantized image
end
store as PNG
else
store as JPG
end
end
युक्ति: कुछ छवियों को एक प्रारूप में, और अन्य को किसी अन्य प्रारूप में संग्रहीत करना ठीक है।
अन्य विशिष्ट प्रारूप जैसे डीएक्सटी, ईटीसी और पीवीआरटीसी हैं। वे संपीड़न का समर्थन करते हैं, और उन्हें मेमोरी में संपीड़ित भी लोड किया जा सकता है, लेकिन वे केवल विशिष्ट GPU द्वारा समर्थित हैं, और इनमें से अधिकांश GPU केवल उनमें से एक का समर्थन करते हैं, इसलिए जब तक आप अपने लक्ष्य हार्डवेयर के सटीक विनिर्देशों को नहीं जानते (उल्लेखनीय मामला है) iPhone / iPad, जो PVRTC बनावट का समर्थन करता है), आपको इन प्रारूपों से बचना चाहिए।
प्रोग्राम मेमोरी
मैंने इसे यहां शामिल किया है, क्योंकि यह वह है जिसे आमतौर पर "मेमोरी" द्वारा जाना जाता है। हालाँकि, यदि आपका गेम ग्राफिक्स त्वरण का उपयोग करता है (और यदि आप 1998 के बाद एक गेम बना रहे हैं, तो आप सबसे अधिक संभावना रखते हैं), तो केवल एक चीज जो मेमोरी का उपभोग करेगी, आपके टेक्सचर डिस्क्रिप्टर (प्रति चित्र कुछ बाइट्स) हैं, जो केवल है छवियों की मात्रा से प्रभावित होता है , न कि उनके आकार या स्वरूप (इसमें कुछ कैविटीज़ होती हैं, लेकिन ज्यादातर अप्रासंगिक होती हैं)।
यदि आपके प्लेटफ़ॉर्म में समर्पित वीडियो मेमोरी नहीं है, हार्डवेयर त्वरित या अन्य असामान्य मामले नहीं हैं, तो वीआरएएम के बारे में अगला भाग पूरी तरह से या आंशिक रूप से रैम में होगा, लेकिन मुख्य सिद्धांत समान होंगे।
वीडियो स्मृति
यह वह जगह है जहाँ आपका चित्र आपके प्रोग्राम के चलने के बाद संग्रहीत किया जाएगा। सामान्य तौर पर, जिस प्रारूप में आपने उन्हें संग्रहीत किया है, यहां कोई अंतर नहीं होगा, क्योंकि सभी चित्र वीडियो मेमोरी में लोड करने से पहले विघटित हो जाते हैं।
अब, आपकी छवियों द्वारा खपत VRAM मोटे तौर पर VRAM में भरी हुई width * height * bitdepth
प्रत्येक छवि के लिए होगा । यहाँ ध्यान देने योग्य बातें हैं:
वीआरएएम में आपकी छवियों को जिस चौड़ाई और ऊंचाई में संग्रहीत किया जाता है, वह जरूरी नहीं कि आपकी मूल छवि से मेल खाता हो। कुछ जीपीयू केवल 2 की शक्तियों में आकारों के साथ बनावट को संभाल सकते हैं, इसलिए आपकी 320x240 छवि को वास्तव में वीआरएएम में 512x256 स्थान में संग्रहीत किया जा सकता है, जिसमें अप्रयुक्त मेमोरी प्रभावी रूप से बर्बाद हो जाती है। कुछ बार आपको उन आकारों के साथ बनावट लोड करने की अनुमति नहीं है जो 2 की शक्तियां नहीं हैं (जैसे GLES 1.1 में)।
इसलिए यदि आप वीआरएएम उपयोग को कम करना चाहते हैं, तो आप अपनी छवियों को एटलस करने पर विचार कर सकते हैं , और उन्हें 2 की शक्तियों के साथ आकार दे सकते हैं , जो रेंडर करते समय कम रेंडर राज्य परिवर्तनों का लाभ भी होगा। इस पर और बाद में।
बिटपथ बहुत महत्वपूर्ण है। आमतौर पर बनावट को 32-बिट ARGB या 32-बिट XRGB में VRAM में लोड किया जाता है, लेकिन अगर आपका हार्डवेयर 16-बिट डेप्थ को सपोर्ट कर सकता है, और आपको कम बिटडैप होने का कोई मतलब नहीं है, तो आप प्रत्येक इमेज से उपभोग किए गए VRAM की आधी राशि ले सकते हैं। , जो विचार करने के लिए कुछ दिलचस्प हो सकता है।
कोई फर्क नहीं पड़ता कि आप क्या करते हैं, सबसे महत्वपूर्ण कारक जब आपके गेम का उपयोग वीआरएएम की मात्रा पर विचार करता है, तो एक निश्चित समय में आपके पास वीआरएएम में मौजूद छवियों की मात्रा होती है । यह वह संख्या है जिसे आप सबसे अच्छा प्रदर्शन करना चाहते हैं यदि आप एक अच्छा प्रदर्शन करना चाहते हैं। वीआरएएम में लोडिंग और अनलोडिंग महंगा है, इसलिए जब भी आप इसका उपयोग करने जा रहे हैं, तो आप प्रत्येक छवि को लोड नहीं कर सकते। आपको उन छवियों को प्रीलोड करने के बीच एक संतुलन ढूंढना होगा जिनका आप सबसे अधिक उपयोग करेंगे, और उन्हें अनलोड करें जब आप सुनिश्चित हों कि आप अब उनका उपयोग नहीं करने जा रहे हैं। इस अधिकार को करना तुच्छ नहीं है, और आपको अपने विशेष खेल के लिए अपनी रणनीति के बारे में सोचना होगा।
निष्पादन की गति
भले ही "मेमोरी" न हो, यह खेलों में प्रदर्शन से बहुत संबंधित है। चित्र बनाना महंगा है, और आप यह सुनिश्चित करना चाहते हैं कि आपकी रेंडरिंग जितनी जल्दी हो सके। बेशक, यहाँ, प्रारूप में कोई फर्क नहीं पड़ता, लेकिन अन्य चीजें हैं:
छवि का आकार (वास्तव में, यह "नमूना आकार" होगा): एक छवि का सबसे बड़ा क्षेत्र जिसे आप ड्रा करने जा रहे हैं, उसे खींचने में जितना अधिक समय लगेगा। स्क्रीन के एक छोटे से हिस्से में एक विशाल छवि को प्रस्तुत करना बहुत प्रभावी नहीं है, इसलिए एक ऐसी तकनीक है, जिसे एमपमैपिंग कहा जाता है , जिसमें गति प्रदान करने के लिए ट्रेडिंग वीआरएएम होता है , कई बार अपने चित्रों को कई प्रस्तावों पर संग्रहीत करके और सबसे छोटा एक का उपयोग कर सकता है जो दे सकता है आप किसी भी समय आवश्यक गुणवत्ता। छवियों के लोड होने पर Mipmapping किया जा सकता है, जो लोडिंग गति और VRAM उपयोग को प्रभावित करेगा, या प्रीप्रोसेसिंग (मैन्युअल रूप से एक ही छवि के विभिन्न संस्करणों को संग्रहीत करके, या एक प्रारूप का उपयोग करके जो कि DDS जैसे mipmapping का समर्थन करता है, जो भंडारण को प्रभावित करेगा। और वीआरएएम उपयोग, लेकिन लोडिंग गति पर बहुत कम प्रभाव पड़ेगा।
रेंडर स्टेट बदल जाता है। आप संभवतः एक ही समय में स्क्रीन पर कई अलग-अलग चित्र बनाना चाहेंगे। हालांकि, GPU किसी भी समय केवल एक स्रोत छवि का उपयोग कर सकता है (यह सच नहीं है, लेकिन कृपया यहां मेरे साथ सहन करें)। रेंडरिंग के लिए वर्तमान में उपयोग की जाने वाली छवि कई रेंडर स्टेट्स में से एक है , और यह महंगी है। इसलिए यदि आप एक ही छवि का कई बार उपयोग करने जा रहे हैं (याद रखें जब मैंने बनावट atlases का उल्लेख किया है ?), तो आप एक विशाल प्रदर्शन लाभ देखेंगे यदि आप एक छवि का पुन: उपयोग करते हैं जितना आप रेंडर स्थिति बदलने से पहले कर सकते हैं और एक का उपयोग करना शुरू कर सकते हैं अलग-अलग छवि (इसके अलावा अन्य रेंडर स्टेट्स हैं, और उस ऑर्डर को ठीक से ट्यूनिंग है जिसमें आप रेंडर को कम करके स्टेट्स चेंजेस को कम करते हैं, गेम के प्रदर्शन को बढ़ाते हुए एक बहुत ही सामान्य गतिविधि है)
हालाँकि , छवि उपयोग अनुकूलन एक बहुत ही जटिल विषय है, और जो मैंने यहाँ लिखा है, वह कुछ कारकों का एक बहुत व्यापक और ओवरसिम्प्लीफाइड ओवरव्यू है, जो आपको गेम लिखते समय विचार करना होगा, इसलिए मुझे लगता है कि अगर आप इसे सरल रखते हैं, तो यह निश्चित रूप से सबसे अच्छा है। और केवल तब अनुकूलित करें जब आपको वास्तव में ऐसा करने की आवश्यकता हो। ज्यादातर बार, समय से पहले अनुकूलन अनावश्यक है (और कभी-कभी हानिकारक भी), इसलिए इसे लेना आसान है।
setEnforcePotImages
, यह ओपनजीएलईएस 1.0 के लिए 2 आकार की बनावट के प्रवर्तन को अक्षम करता है। यह एक अच्छा विचार नहीं है, क्योंकि सभी हार्डवेयर नॉन-पॉवर ऑफ -2 बनावट का समर्थन करते हैं। OpenGLES 2.0 को नॉन-पॉवर ऑफ़ -2 बनावट के लिए समर्थन की आवश्यकता होती है, इसलिए यदि आप 2.0 को लक्षित कर रहे हैं, तो आप किसी भी आकार के बनावट का उपयोग कर सकते हैं। अधिक जानकारी के लिए libgdx प्रलेखन देखें।
एक बार एक छवि डिस्क से लोड हो जाती है और रेंडरिंग के लिए स्वरूपित की जाती है, तो यह इस बात की परवाह किए बिना स्मृति की एक ही राशि का उपयोग करेगा कि क्या उस छवि को पीएनजी, जेपीईजी, या जीआईएफ का उपयोग करके डिस्क में सहेजा गया था।
अंगूठे का सामान्य नियम: जेपीईजी एक हानिपूर्ण प्रारूप है, और छवि को डिस्क पर छोटा करने के लिए छवि गुणवत्ता को नीचा दिखाएगा। दूसरी ओर, पीएनजी, एक दोषरहित छवि प्रारूप है, और इसलिए आमतौर पर डिस्क पर बड़े फ़ाइल आकार में परिणाम होगा। जीआईएफ तकनीकी रूप से एक दोषरहित प्रारूप भी है, लेकिन केवल प्रति छवि अधिकतम 256 रंगों का समर्थन करता है, और इसलिए उच्च-रंग की छवि अक्सर GIF के रूप में सहेजे जाने पर एक भारी गुणवत्ता नुकसान का कारण होगी।
हालांकि यह केवल उनके ऑन-डिस्क प्रतिनिधित्व के लिए है। स्मृति में, वे दोनों एक ही बनावट प्रारूप में विस्तार करेंगे, चाहे वे पीएनजी के रूप में या जेपीईजी के रूप में या जीआईएफ के रूप में डिस्क पर सहेजे हों, चाहे वे कितनी ही स्मृति का उपयोग कर रहे हों।
निर्भर करता है।
Jpeg तस्वीरों के लिए सबसे अधिक कुशल है। यह दोषरहित नहीं है, लेकिन कम्प्रेशन द्वारा प्रस्तुत की गई कलाकृतियाँ इस उपयोग के मामले में कम से कम दिखाई देती हैं।
पीएनजी दोषरहित है और तेज लाइनों और कुछ रंगों के साथ पिक्सेल-कला के लिए सबसे कुशल है। यह अल्फा-पारदर्शिता का भी समर्थन करता है।
GIF कुछ भी नहीं कर सकता PNG बेहतर नहीं कर सकता, सिवाय एनिमेशन स्टोर करने की क्षमता के। लेकिन यह केवल वेब अनुप्रयोगों के संदर्भ में प्रासंगिक है। खेल के विकास में आप आमतौर पर स्प्राइटशीट का उपयोग करके एनिमेशन बनाते हैं।
ध्यान दें कि जब आप Libgdx जैसे एक ग्राफिक इंजन का उपयोग करते हैं, तो यह सबसे अधिक संभावना है कि छवियों को लोड करने के बाद ही उन्हें खोल दिया जाए और फिर उन्हें RGBA मानों के रूप में स्मृति में रखें। तो छवि प्रारूप केवल लोडिंग गति के लिए मायने रखता है और ड्राइव स्पेस (या बैंडविड्थ उपयोग जब आप उन्हें नेट पर भेजते हैं)।
मैं libgdx के बारे में ज्यादा नहीं जानता, लेकिन छवि प्रारूप और ग्राफिक्स के बारे में:
असली दुनिया की तस्वीरों के मामलों में JPEG बहुत अच्छा है। वे हानिप्रद हैं, लेकिन आप तस्वीरों पर कलाकृतियों को तब तक नहीं देखेंगे जब तक कि आप सादे रंगीन स्थानों के साथ तेज किनारों की तस्वीरें नहीं लेते हैं, जैसे कि लिखित पाठ या कॉमिक्स। बड़े पृष्ठभूमि ग्राफिक्स के लिए उनका उपयोग करें।
GIF अप्रचलित है, यह केवल पूर्ण पारदर्शिता के लिए एक समर्पित रंग के साथ पैलेटेड रंगों (पिक्सेल प्रति 8 बिट तक) को स्टोर कर सकता है। यह फ्रेम के आधार पर छोटे एनिमेशन की अनुमति देता है। एक बार इसके पैकिंग एल्गोरिदम पर एक पेटेंट था ताकि इसे कानूनी रूप से हर जगह इस्तेमाल नहीं किया जा सके। उस पेटेंट की वजह से पीएनजी का विकास हुआ था।
PNG कमोबेश एक ज़िप्ड बिटमैप है जो RGB + अल्फा (32 बिट तक) और अन्य पिक्सेल फॉर्मेट को स्टोर कर सकता है। यह उस तस्वीर के छोटे हिस्सों की गति-अनजिपिंग के लिए विशिष्ट है, जो बहुत छोटे और धीमे उपकरणों (जैसे एक 10 साल पुराने सेलफोन) के लिए सुविधाजनक है, लेकिन आज पुस्तकालय लोड होने पर बिटमैप्स में अनपैक करते हैं।
PNG GIF से आकार और गति और सुविधाओं में बेहतर है, लेकिन यदि आप कुशलतापूर्वक बिटमैप स्टोर करना चाहते हैं, तो मैं सुझाव दूंगा: .PNM.BZ2 ([संपादित करें] अलग पैकिंग विधि के कारण, .PNM.BZ2 हमेशा अधिक कुशल नहीं होता है। .PNG से। [/ संपादित करें])
पीएनएम / पीबीएम / PGM / पीएएम सादे पाठ में KISS-हेडर के साथ सादे बिटमैप स्वरूप हैं। उन पर gzip का उपयोग PNG के समान फ़ाइल आकार में होगा, इसलिए bzip2 उसके लिए बेहतर समाधान है। यदि आप अपने प्रोग्राम में आंतरिक रूप से बिटमैप का उपयोग करने जा रहे हैं, तो आप एक .tar या .zip कंटेनर में bzip2 संपीड़ित बिटमैप का उपयोग करना चाह सकते हैं। यदि आपके पास bzip2 नहीं है, तो एक ज़िप कंटेनर में PNM का उपयोग करना (अधिकतम संपीड़न के साथ ज़िप) PNGs का उपयोग करने के समान हो सकता है। - तो, PNGs को एक जिप फाइल में स्टोर करने से केवल छोटा या कोई लाभ नहीं हो सकता है - यह छवि को लोड करने के लिए समय बढ़ाएगा।
इसके अलावा, एक बिटमैप में कई छोटे स्प्राइट / चित्रों को संग्रहीत करना एक अच्छा विकल्प है, खासकर जब आपको एक ही स्थिति में उन सभी की आवश्यकता होती है।
भंडारण प्रारूप के रूप में जेपीईजी शायद घास या दीवारों जैसे कुछ बनावटों के लिए सबसे अच्छा विकल्प है, जहां जानकारी का नुकसान शायद अवांछनीय है। पीएनजी द्वारा पीछा किया जाता है जब आपको पारदर्शिता की आवश्यकता होती है या जब आप सूचना के नुकसान के साथ भुगतान नहीं कर सकते हैं, उदाहरण के लिए एक 2 डी गेम (खिलाड़ी, दुश्मन, एक खजाना छाती) में स्प्राइट, तो आप शायद उस छवियों के लिए पीएनजी का उपयोग करना चाहते हैं।
जब मेमोरी लागत के बारे में बात की जाती है, तो फ़ाइल सिस्टम में गेम ग्राफिक्स को स्टोर करने के लिए उपयोग किया जाने वाला प्रारूप बिल्कुल भी प्रासंगिक नहीं है। यदि आप VRAM, या RAM (सॉफ़्टवेयर रेंडरर) में पिक्सेल बफ़र्स संग्रहीत करते हैं, तो आप शायद उन्हें असम्पीडित संग्रहित कर सकते हैं, क्योंकि गेम प्रत्येक पिक्सेल बफ़र द्वारा उपयोग किए जाने वाले पिक्सेल बनाम मेमोरी के तेजी से पढ़ने का पक्ष लेते हैं।
मेमोरी में संग्रहीत संपीड़ित डेटा का कोई मतलब नहीं है सिवाय इसके कि आप डिस्क रीड को बचाने के लिए किसी प्रकार के कैश को बनाए रखें, लेकिन आपको शायद उस कैश से अपने गेम में दिए गए समय में उपयोग की गई छवियों के लिए एक असम्पीडित स्थिति में पढ़ना होगा।
यदि तेजी से हार्डवेयर डिकोडिंग संभव हो, तो संपीडित छवि डेटा में थोड़ी अधिक समझ है। कम से कम सामान्य मैपिंग के लिए, मुझे यह याद है http://en.wikipedia.org/wiki/3Dc । इससे आप कुछ वीआरएएम को बचा सकते हैं। मुझे अभी हार्डवेयर डिकोडिंग के अन्य उदाहरणों के बारे में पता नहीं है।
रिज्यूमे में: आपके गेम के लिए जो भी फॉर्मेट लगातार स्टोरेज में ग्राफिक्स को स्टोर करने के लिए उपयोग किया जाता है, आपको उसे डायोड करना होगा और डायनेमिक मेमोरी, वीडियो मेमोरी, या दोनों में एक असम्पीडित संस्करण को बनाए रखना होगा, जब जरूरत पड़ने पर उन्हें फास्ट रेंडर करने में सक्षम होना चाहिए।
अंत में: मैं एक डेस्कटॉप आदमी हूं। जब मैं "मेमोरी" कहता हूं तो मैं हमेशा गतिशील मेमोरी का जिक्र करता हूं। जब मैं "डिस्क", "फाइल सिस्टम" या "लगातार स्टोरेज" कहता हूं, तो मैं हमेशा आपके डिवाइस को लगातार स्टोरेज के रूप में उपयोग करने की बात करता हूं, आमतौर पर मैं हार्ड डिस्क में सोचता हूं। जब आपने कहा "मेमोरी-दक्षता" तो मैंने इसे "डायनेमिक मेमोरी" के लिए लिया, न कि "लगातार स्टोरेज" के लिए। हाल ही में, मैं "मेमोरी" शब्द का उपयोग करते हुए बहुत से लोगों को "लगातार भंडारण" (शायद मोबाइल उपकरणों के शब्द?) को संदर्भित करता हूं।