Hangi görüntü formatı hafızadan tasarruf etmek için daha verimlidir? PNG, JPEG veya GIF?
Hangi görüntü formatı hafızadan tasarruf etmek için daha verimlidir? PNG, JPEG veya GIF?
Yanıtlar:
"Bellek" ve "verimlilik" genel olarak kötüye kullanılan terimlerdir, bu yüzden size oyununuzun performansını etkileyebilecek dört farklı öğeye cevap vereceğim.
Kısa ve özlü tutmak için çok fazla şeyi aşırı basitleştireceğim, ancak bu metinde tonlarca yanlışlık var, bu yüzden bir tutam tuzla alın. Ancak, ana kavramlar anlaşılabilir olmalıdır.
Depolama
Bu, resimlerinizin yazılım dağıtımınızda kullandığı boyuttur. Kaynaklarınız ne kadar fazla yer kaplarsa, indirme (web sitenizden olduğu gibi) o kadar uzun olacaktır. CD veya DVD gibi fiziksel ortamlara dağıtıyorsanız, muhtemelen bu cephede bazı ciddi optimizasyonlar yapmanız gerekecektir.
Genel olarak, JPEG keskin sınırları olmayan fotoğraflar ve görüntüler için en iyi olanı sıkıştırır. Ancak, JPEG, kayıplı sıkıştırma kullandığından görüntü kalitesinin düşmesine neden olacaktır (görüntüleri JPEG olarak dışa aktarırken sıkıştırma seviyesini / bozulmasını ayarlayabilirsiniz. Bu konuda daha fazla bilgi için görüntüleme yazılımınızın belgelerine bakın).
Ancak, JPEG olabildiğince iyi, saydamlığı desteklemiyor . Başkalarının içinden geçen görüntülere sahip olmak veya düzensiz şekilli görüntülere sahip olmak istiyorsanız, bu çok önemlidir. GIF iyi bir seçimdir, ancak PNG tarafından büyük ölçüde yerine getirildi (GIF'in PNG'nin desteklemediği birkaç şey var, ancak oyun programlamasında büyük önemsizler).
PNG, saydamlığı (ve yarı saydamlığı) destekler, kaliteyi bozmadan verileri sıkıştırır (yani kayıpsız sıkıştırma kullanır) ve JPG kadar değil, oldukça iyi sıkıştırır.
Sorun, saydamlığın yanı sıra iyi bir sıkıştırmaya ihtiyaç duyduğunuzda ortaya çıkar. Biraz bozulmuş resimlere aldırış etmiyorsanız , çevrimiçi olarak TinyPNG'de test edebileceğiniz pngquant gibi PNG miktarlandırma programlarını kullanabilirsiniz . Kendi kendine nicelemeyle yapılan görüntü bozulmasının JPEG'inkinden farklı olduğunu unutmayın (ki bu, diğer agresif tekniklerin yanı sıra nicelemeyi de içerir);
Dağıtım boyutunuzu agresif bir şekilde küçültmek istiyorsanız, aşağıdaki gibi her görüntüyü manuel olarak işleyebilirsiniz:
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
İpucu: Bazı görüntüleri tek bir formatta, diğerlerini başka bir formatta saklamak iyidir.
DXT, ETC ve PVRTC gibi başka özel biçimler de vardır. Sıkıştırmayı desteklerler ve ayrıca belleğe sıkıştırılmış olarak da yüklenebilirler, ancak yalnızca belirli GPU'lar tarafından desteklenirler ve bu GPU'ların çoğu yalnızca birini desteklemektedir, bu nedenle hedef donanımınızın tam donanım özelliklerini bilmiyorsanız (dikkate değer bir durum PVRTC dokularını destekleyen iPhone / iPad), bu formatlardan kaçınmalısınız.
Program hafızası
Buraya dahil ettim, çünkü yaygın olarak "hafıza" olarak bilinen şey bu. Ancak, oyununuz grafik hızlandırmayı kullanıyorsa (ve 1998'den sonra bir oyun yapıyorsanız, büyük olasılıkla vardır), o zaman hafıza tüketen tek şey doku tanımlayıcılarınızdır (görüntü başına sadece birkaç bayt), bu sadece görüntülerin miktarından etkilenir , boyutlarına veya biçimlerine değil (bunun birkaç uyarısı vardır, ancak çoğunlukla ilgisizdir).
Platformunuzda özel video belleği yoksa, donanım hızlandırması veya nadir görülen durumlar yoksa, VRAM ile ilgili bir sonraki bölüm tamamen veya kısmen RAM'de gerçekleşecek, ancak ana prensipler aynı olacaktır.
Video belleği
Burası programınız çalıştığında resimlerinizin depolanacağı yerdir. Genel olarak, içinde sakladığınız format burada fark yaratmaz, çünkü tüm görüntüler video belleğine yüklenmeden önce sıkıştırılır.
Artık, resimleriniz tarafından tüketilen VRAM, VRAM'a yüklenen width * height * bitdepth
her resim için kabaca olacaktır . Burada dikkat edilmesi gereken birkaç şey var:
Görüntülerin VRAM'da saklandığı genişlik ve yükseklik, mutlaka orijinal görüntünüzünkilerle eşleşmeyecektir. Bazı GPU'lar yalnızca 2 boyutundaki dokulara sahip dokuları kullanabilir, bu nedenle 320x240 görüntünüz VRAM'de 512x256 alanda ve kullanılmayan bellek etkin bir şekilde boşa harcanabilir. Bazı zamanlar 2'nin gücü olmayan boyutta doku yüklemenize bile izin verilmez (GLES 1.1'de olduğu gibi).
Bu nedenle, VRAM kullanımını en aza indirmek istiyorsanız , resimlerinizi atlatmayı ve bunları 2 güçleriyle boyutlandırmayı düşünebilirsiniz ; bu, oluşturma sırasında daha az oluşturma durumu değişikliği avantajına da sahip olur. Bunun üzerine daha sonra.
Bit hızı çok önemlidir. Genellikle dokular 32 bit ARGB veya 32 bit XRGB’de VRAM’e yüklenir, ancak donanımınız 16 bit derinlikleri destekliyorsa ve bit bit hızının düşük olmasını önemsemiyorsanız, her görüntü tarafından tüketilen VRAM miktarının yarısını , dikkate alınması gereken ilginç bir şey olabilir.
Ancak ne yaparsanız yapın, oyununuzun kullandığı VRAM miktarını göz önünde bulundururken en önemli faktör, VRAM'da verilen görüntülerin miktarıdır . İyi bir performans sergileyen bir oyun istiyorsanız, mümkün olduğu kadar düşük tutmak isteyebileceğiniz sayı budur. Dokuları VRAM'a yüklemek ve boşaltmak pahalıdır, bu nedenle kullanacağınız her görüntüyü yalnızca yükleyemezsiniz. Büyük olasılıkla kullanacağınız görüntülerin önceden yüklenmesi ve artık kullanmayacağınızdan emin olduğunuzda bunları boşaltmanız arasında bir denge kurmanız gerekir. Bu hakkı yapmak önemsiz değildir ve kendi oyununuz için kendi stratejinizi düşünmeniz gerekir.
Yürütme hızı
“Hafıza” olmasa da, oyunlardaki performansla çok ilgili. Görüntüleri çizmek pahalıdır ve oluşturma işleminizin olabildiğince hızlı çalıştığından emin olmak istersiniz. Elbette, burada, format önemli değil, fakat başka şeyler de var:
Görüntü boyutu (aslında, "örnekleme boyutu" olur): Bir resmin çizeceği bölge en büyük, çizilmesi gereken süre o kadar fazla olur. Ekranın küçük bir bölümünde büyük bir görüntüyü oluşturmak çok etkili değildir; bu nedenle , görüntülerinizi birkaç kez saklayarak ve en düşük çözünürlükte kullanarak görüntülerini hızlandıran VRAM'den oluşan mipmapping adı verilen bir teknik vardır. herhangi bir zamanda istediğiniz kalitede size. Görüntüler yüklendiğinde, yükleme hızını ve VRAM kullanımını etkileyebilecek veya ön işleme sırasında (aynı görüntünün farklı sürümlerini elle depolayarak veya depolamayı etkileyecek DDS gibi mipmaplamayı doğal olarak destekleyen bir format kullanarak), mipmap oluşturma gerçekleştirilebilir ve VRAM kullanımı, ancak yükleme hızı üzerinde çok az etkisi olacaktır.
Render durum değişiklikleri. Aynı anda ekranda birkaç farklı görüntü çizmek isteyeceksiniz. Ancak, GPU herhangi bir zamanda yalnızca tek bir kaynak görüntü kullanabilir (bu doğru değildir, ancak lütfen burada benimle birlikte hareket edin). Oluşturma için şu anda kullanılan resim birçok biridir hale devletler ve pahalıdır. Bu yüzden, aynı görüntüyü birkaç kez kullanacaksanız ( doku atlaslarından bahsettiğimde hatırlıyor musunuz?), Görüntü oluşturma durumunu değiştirmeden ve kullanmaya başlamadan önce görüntüyü olabildiğince tekrar kullanırsanız büyük bir performans kazancı fark edeceksiniz. farklı görüntü (bunun dışında başka oluşturma durumları da vardır ve oluşturma durumu değişikliklerini en aza indirmek için eşyalarını çizdiğiniz sıraya göre ince ayar yapmak bir oyunun performansını artırırken çok yaygın bir etkinliktir)
Bununla birlikte , görüntü kullanımı optimizasyonu çok karmaşık bir konudur ve burada yazdıklarım, bir oyun yazarken göz önünde bulundurmanız gereken bazı faktörlere ilişkin çok geniş ve basitleştirilmiş bir genel bakış; ve sadece gerçekten yapmanız gerektiğinde optimize edin. Önceden optimize etmek çoğu zaman gereksizdir (ve hatta bazen zararlıdır), bu yüzden kolay.
setEnforcePotImages
1.0 için 2 boyutlu dokunun gücünün uygulanmasını engelliyor . Bu iyi bir fikir değil, çünkü tüm donanım 2 güçten arındırılmış dokuları desteklemiyor. OpenGLES 2.0 2 güçlü olmayan dokular için destek gerektirir, böylece 2.0'ı hedefliyorsanız, istediğiniz boyutta dokular kullanabilirsiniz. Daha fazla bilgi için libgdx belgelerine bakın.
Bir görüntü diskten yüklenip oluşturma için biçimlendirildikten sonra, o görüntünün PNG, JPEG veya GIF kullanılarak diske kaydedilmesine bakılmaksızın aynı miktarda bellek kullanır.
Genel kural: JPEG kayıplı bir formattır ve görüntüyü diskte küçültmek için görüntü kalitesini düşürür. PNG, diğer taraftan, kayıpsız bir görüntü formatıdır ve bu nedenle genellikle diskte daha büyük dosya boyutlarına neden olur. GIF ayrıca teknik olarak kayıpsız bir formattır, ancak görüntü başına yalnızca maksimum 256 rengi destekler ve bu nedenle yüksek renkli bir görüntü, GIF olarak kaydedildiğinde genellikle ağır kalite kaybına neden olur.
Ancak bu onların yalnızca diskteki temsili için. Bellekte, PNG olarak mı yoksa JPEG olarak mı yoksa GIF olarak mı kaydettiğinizden bağımsız olarak, aynı miktarda bellek kullanarak aynı doku biçiminde genişlerler.
Değişir.
Jpeg, fotoğraflar için en verimli olanıdır. Kayıpsız değildir, ancak bu kullanım durumunda sıkıştırmanın neden olduğu eserler en az görülebilir.
PNG, keskin çizgiler ve az renkli pikseller için kayıpsız ve en verimli olanıdır. Aynı zamanda alfa saydamlığını da destekler.
GIF, PNG'nin daha iyi yapamayacağı bir şey yapamaz, animasyonları saklayabilmesi dışında. Ancak bu sadece web uygulamaları bağlamında geçerlidir. Oyun geliştirmede genellikle bir spritesheet kullanarak animasyonlar yaratırsınız.
Libgdx gibi bir grafik motoru kullandığınızda, görüntüleri yükledikten hemen sonra açacağınızı ve ardından sıkıştırılmamış RGBA değerleri olarak bellekte tutacağını unutmayın. Bu nedenle, görüntü formatı yalnızca yükleme hızı için önemlidir ve sürücü alanı (veya ağ üzerinden gönderdiğinizde bant genişliği kullanımı) vardır.
Libgdx hakkında değil, resim biçimleri ve grafikler hakkında çok fazla bilgim yok:
JPEG, gerçek dünya fotoğrafları için çok iyidir. Kayıplıdırlar, örneğin yazılı metin veya çizgi roman gibi düz renkli alanlarda keskin kenarların resimlerini çekmediğiniz sürece fotoğraflarda eserler görmezsiniz. Büyük arka plan grafikleri için bunları kullanın.
GIF eskidir, tam saydamlık için yalnızca özel renkle paletlenmiş renkleri (piksel başına 8 bit'e kadar) depolayabilir. Çerçevelere dayalı küçük animasyonlara izin verir. Bir zamanlar ambalaj algoritmasında patent vardı, böylece yasal olarak her yerde kullanılamazdı. Bu patent nedeniyle PNG geliştirilmiştir.
PNG, RGB + alpha (32bit'e kadar) ve diğer piksel biçimlerini depolayabilen sıkıştırılmış bir bitmap aşağı yukarı hareket eder. Çok küçük ve yavaş cihazlar (10 yaşında bir cep telefonu gibi) için uygun olan bu resmin küçük parçalarının hızla açılması için uzmanlaşmıştır, ancak günümüz kütüphaneleri yüklendiklerinde bunları bitmaplere kadar açmaktadır.
PNG, boyut ve hız ve özelliklerde GIF'den daha iyidir, ancak bitmapleri verimli bir şekilde saklamak istiyorsanız, şunu önerebilirim: .PNM.BZ2 ([değiştir] Farklı paketleme yöntemi nedeniyle, .PNM.BZ2 her zaman daha verimli değildir .PNG'den [[değiştir])
PNM / PBM / PGM / PAM , düz metin halinde KISS başlıklı düz bitmap formatlarıdır. Bunlarda gzip kullanmak PNG'ye benzer bir dosya boyutuna neden olacaktır, bu nedenle bzip2 bunun için daha iyi bir çözümdür. Programınızda dahili olarak bitmap'ler kullanacaksanız, bir .tar veya .zip kabında bzip2 sıkıştırılmış bitmap'ler kullanmak isteyebilirsiniz. Bzip2'niz yoksa, PNM'leri bir zip kabında (maksimum sıkıştırmalı zip) kullanmak PNG'leri kullanmaya benzer olabilir. - PNG'leri ZIP dosyasına kaydetmenin çok küçük bir faydası olabilir veya faydası olmayabilir - büyük olasılıkla görüntünün yüklenme süresini uzatacaktır.
Bunun yanında, birkaç küçük sprite / resmi bir bitmapte, özellikle hepsine aynı durumda birlikte ihtiyaç duyduğunuzda saklamak için iyi bir seçimdir.
Depolama formatı olarak JPEG, bilgi kaybının muhtemelen tespit edilemeyeceği çim veya duvar gibi bazı dokular için en iyi seçimdir. Saydamlığa ihtiyacınız olduğunda veya bilgi kaybıyla ödeme yapamadığınızda PNG tarafından takip edilir, örneğin 2D bir oyuna (oyuncu, düşmanlar, bir hazine sandığı) yazılır, muhtemelen bu görüntüler için PNG kullanmak istersiniz.
Hafıza maliyeti hakkında konuşurken, oyun grafiklerini dosya sisteminde saklamak için kullanılan format hiç önemli değildir. Ya piksel arabelleklerini VRAM'da ya da RAM'de (yazılım oluşturucu) saklarsanız, büyük olasılıkla sıkıştırılmamış olarak depolanmış olmalarını sağlarsınız;
Bellekte depolanan sıkıştırılmış verilerin disk okumalarını kaydetmek için bir tür önbellek bulundurmanız dışında bir anlamı yoktur, ancak oyununuzda belirli bir zamanda kullanılan görüntüler için bu önbellekten sıkıştırılmamış bir duruma okumak zorundasınızdır.
Hızlı donanım kod çözme mümkün olduğunda, sıkıştırılmış görüntü verileri biraz daha anlamlı olur. En azından normal haritalama için bunu http://en.wikipedia.org/wiki/3Dc hatırlıyorum . Bununla VRAM tasarruf edebilirsiniz. Henüz diğer donanım kod çözme örneklerinden haberdar değilim.
Özgeçmiş: Oyununuz için grafikleri kalıcı depolamada saklamak için kullanılan formatlar ne olursa olsun, gerektiğinde hızlı bir şekilde görüntüleyebilmek için dinamik hafıza, video belleği veya her ikisinde sıkıştırılmamış bir versiyonun kodunu çözmeniz ve korumanız gerekecektir.
Sonunda: Ben bir masaüstü adamıyım. "Bellek" derken her zaman dinamik belleğe atıfta bulunurum. "Disk", "dosya sistemi" veya "kalıcı depolama" deyince, cihazınızın her zaman kalıcı depolama olarak kullandığı her bir şeyi kastediyorum, genellikle sabit disklerde düşünüyorum. "Hafıza verimliliği" derken, "kalıcı hafıza" değil "dinamik hafıza" için kullandım. Son zamanlarda "kalıcı depolama" ("mobil cihazların terminolojisi" anlamına gelir) için "hafıza" kelimesini kullanan bir çok insan görüyorum.