کاهش حجم فایل‌های PNG

نویسنده : سید ایوب کوکبی ۲۱ شهریور ۱۳۹۷

کاهش حجم فایل‌های PNG

فرمت (PNG: Portable Network Graphics) یکی از محبوب‌ترین فرمت‌های گرافیکی است که طی چند دهه‌ی اخیر جایش را در توسعه‌ی نرم‌افزار از بازی‌ها گرفته تا وب و اپلیکیشن‌های اندروید باز کرده است. تصاویر PNG رزولوشن بالایی دارند، به همین دلیل جای زیادی برای بهینه‌سازی و کاهش حجمشان وجود دارد. در پست‌های قبلی به روش‌های متعددی برای بهینه‌سازی تصاویر اشاره شد. در این مقاله قصد دارم به صورت خاص‌تر در رابطه با کاهش حجم تصاویر PNG بنویسم.

فرمت PNG بسیار منعطف بوده و کیفیت این دسته از تصاویر را به راحتی می‌توان کنترل کرد. PNG از زمینه‌ی شفاف حمایت می‌کند. اما مشکل، حجم این تصاویر است. تنها افزودن ۲ پیکسل به عرض تصاویر PNG می‌تواند حجم آن را تا دوبرابر افزایش دهد. بنابراین با لحاظ کردن این موضوع اغلب تصاویر PNG را می‌توان غیربهینه دانست. با بررسی بیش از صدها APK مشخص شد که بخش عمده‌ی تصاویر PNG به کار رفته در این برنامه‌ها را می‌توان بهینه کرد و حجم نهایی برنامه را به طرز چشمگیری کاهش داد.

به یک ابزار بهینه‌ساز خوب نیاز دارید

اگر با ساختار فایل‌های PNG آشنا باشید، به وضوح می‌دانید که در چهار حوزه‌ی مختلف می‌توان حجم این تصاویر را کاهش داد:

  • حذف تکه‌ها (Chunk)های غیرضروری؛
  • کاهش رنگ‌های منحصر به فرد؛
  • بهینه‌سازی خط به خط فیلتر انتخابی؛
  • بهینه‌سازی الگوریتم فشرده‌سازی DEFLATE (یک الگوریتم فشرده‌سازی بدون اتلاف که چیزی بین الگوریتم هافمن و LZ77 است).

بهینه‌سازی تصاویر PNG برای مدت‌های طولانی به عنوان یک مسئله مطرح بوده است. ۲۰ سال قبل کن.سیلورمن یکی از اولین اوپتیمایزرهای محبوبش تحت عنوان PNGOUT را عرضه کرد که به بک‌بون اصلی انجین Duck Nukem 3D مبدل شد. بعد از آن اوپتیمایزرهای دیگری یکی پس از دیگری وارد صحنه شدند. همین الان عبارت Optimize PNG یا PNG Optimizer را در گوگل جستجو کنید تا با کلی انتخاب مواجه شوید:

PNGQuantImageMagick , PNGGauntletPNGOutPNGCrushOptiPNGCryoPNGPNG CompressorYahoo Smush.itPNGOptimizerPunyPNGTinyPNGPNGWolfAdvpngDeflOptDefluffHuffmixTruePNGPNGnq-s9Median Cut PosterizerscriptpngpngslimzopfliPNG

هر یک از ابزارهای فوق تنها بخشی از تکنیک‌های فشرده‌سازی تصاویر PNG را به کار می‌گیرند؛ بنابراین چیزی تحت عنوان بهترین ابزارها وجود ندارد. سعی کنید با صرف زمان کافی همه‌ی ابزارهای موجود را تست کنید و بهترین مورد را برای کار خود انتخاب نمایید. محض اطلاع شما، بهترین انتخاب من بین همه‌ی این‌ها zopfliPNG است. این ابزار اندازه‌ی فایل PNG را به صورت کارآمدتری کاهش می‌دهد. دلیلش استفاده از سطوح بیشتر فشرده‌سازی الگوریتم Deflate است. این برنامه بدون افت کیفی تصویر تا ۵% حجم آن را کاهش می‌دهد. البته دقت بالاتر این ابزار سرعتش را کمتر می‌کند که ارزشش را دارد. خلاصه اینکه در فرایند آپلود برنامه حتماً باید ابزاری جهت فشرده‌سازی و کاهش حجم تصاویر PNG موجود در آن به کار گیرید. این موضوع با توجه به اینکه حجم عمده‌ی فایل‌های APK در تصرف ریسورس‌های تصویری است بسیار حائز اهمیت است.

بخوانید  تست کدها در اندروید - بخش دوم

کاهش رنگ‌ها

حالا اگر خودمان بخواهیم به صورت دستی و قبل از استفاده از ابزارهای آنلاین حجم فایل‌های PNG را کاهش دهیم چه؟ بله این کار شدنی است و مهم‌ترین کاری که شما می‌توانید انجام دهید کاهش تعداد رنگ‌های منحصر به فرد موجود در تصویر شماست. این کار را انجام دهید و مابقی کار فشرده‌سازی را به ابزارهای معرفی شده بسپارید. دلیل تمرکز بر کاهش رنگ‌ها این است که انجام درستش مستقیماً سایر مراحل فشرده‌سازی را تحت تاثیر قرار می‌دهد.

به نحوه‌ی ارتباط پیکسل‌های مختلف در مرحله‌ی فیلترینگ فرایند فشرده‌سازی PNG دقت کنید. هر چقدر تعداد رنگ‌های منحصربه‌فرد کاهش پیدا کند، میزان ارتباط این پیکسل‌ها کمتر می‌شود که به صورت مستقیم روی حجم نهایی فایل تاثیر می‌گذارد. نهایتاً در مرحله‌ی DEFLATE تعداد بیشتری از مقادیر تکراری یافت شده و امکان فشرده‌سازی بهتر تصویر فراهم می‌شود. ما در واقع با کاهش تعداد رنگ‌های منحصر‌به‌فرد، به صورت موثری روی مرحله‌ی انکدینگ تصاویر کار می‌کنیم. به همین دلیل اعمال دستی تغییرات در این مرحله حائز اهمیت است. ابزارها به اندازه‌ی چشم انسان قادر به تشخیص ادراک بصری رنگ‌ها نیستند و به همین خاطر کوجکترین خطا برای چشم انسان بسیار بد نمایان می‌شود. ولی اگر این کارِ سخت را خودمان انجام دهیم دیگر جای نگرانی باقی نمی‌ماند.

برای پیکسل‌ها، فرمت مناسبی انتخاب کنید

این موضوع را باید چشم بسته رعایت کنید. وقتی در تصویرتان هیچ کانال آلفایی وجود ندارد چه دلیلی وجود دارد که از فرمت RGBA 32bpp استفاده کنید. این کار یک چهارم حجم فایل را بیهوده اشغال می‌کند. به جایش از فرمت ۲۴bpp true color استفاده کنید (یا حتی JPG). حتی اگر تصویر شما سیاه‌وسفید است آن را در فرم ۸bpp ذخیره کنید. بنابراین مطمئن شوید که فرمت نامناسبی برای پیکسل‌ها انتخاب نکرده باشید.

تصاویر ایندکس شده

استفاده از فرمت ایندکس‌گذاری شده تصاویر PNG می‌تواند تعداد رنگ‌ها را تا میزان بسیار زیادی کاهش دهد. در مد رنگی Indexed تنها از ۲۵۶ رنگ برای کل تصویر استفاده می‌شود. این یعنی وقتی این مد را برای تصویر خود انتخااب می‌کنید. ۱۶ میلیون رنگ موجود در آن (۲۴bpp) به ۲۵۶ رنگ کاهش پیدا می‌کند که صرفه‌جویی واقعاً چشمگیری است. این حالت را می‌توان برای برخی از تصاویر ساده فعال کرد بدون اینکه با افت کیفی آن‌ها روبرو شد. مثلاً دو تصویر پایین را ببینید:

بخوانید  آموزش زبان کاتلین – درس 6 (کامنت‌ها)

تصاویر PNG در مد INDEXED

این تصویر را در فتوشاپ Save For Web کردم و از بین فرمت تصاویر PNG8 را انتخاب کردم که باعث تولید پلت رنگی زیر شد:

اساساً، تصاویر ایندکس‌گذاری شده به جای استفاده از رنگ‌های منحصربه‌فرد، به رنگ‌های موجود در پلت رنگ اشاره می‌کنند. نتیجه، کاهش ۳۲ بیت برای هر پیکسل به ۸ بیت برای هر پیکسل خواهد بود. این مد گرافیکی در مراحل فیلترینگ و Deflate باعث صرفه‌جویی بیشتر در فضا خواهد شد:

  1. تعداد پیکسل‌های منحصربه‌فرد کاهش یافته به این معنا که احتمال بیشتری وجود دارد که پیکسل‌های مرتبط به رنگ مشابهی در پالت رنگ اشاره کرده باشند؛
  2. و از آنجایی که تعداد رنگ‌های تکراری بیشتر می‌شود، در مرحله‌ی فیلترینگ، مقادیر تکراری بیشتر شناسایی شده که باعث می‌شود در فاز LZ77 الگوریتم Deflate شاهد فشرده‌سازی بیشتری باشیم.

پس هر زمان فرصت استفاده از حالت INDEXED برای تصاویرتان وجود داشت از آن استفاده کنید.

بهینه‌سازی پیکسل‌های کاملاً شفاف در تصاویر PNG

از ویژگی‌های خوب مد INDEXED این است که می‌توانید در پلت رنگتان یک رنگ مشخص را به عنوان شفاف تعیین کنید. در این حالت وقتی فایل PNG داخل حافظه به RGBA تبدیل می‌شود، پیکسل‌های شفاف طبق رنگ انتخاب شده تنظیم می‌شوند. موضوع جالب ماجرا این است که مد شفافیت در اینجا کاملاً باینری است به این صورت که فلان پیکسل نمایش داده شود یا خیر. به همین سادگی.

این نکته در بحث فشرده‌سازی واقعاً کارایی بالایی دارد. در واقع بخش عمده‌ی رنگ مربوط به قسمت‌های شفاف تصویر است. این پیکسل‌های مشابه فرصت بسیاری خوبی برای بهره‌برداری فرمت PNG است. اما این موضوع فقط برای حالت Indexed صدق می‌کند. در شرایطی هم می‌خواهید از این تکنیک استفاده کنید و هم مد کامل RGB را از دست ندهید. اینجا به سادگی می‌توان دچار اشتباه ماسک نکردن درست پیکسل‌های ناپیدا شد. به تصویر پایین نگاه کنید، هر دو از شفافیت و Truecolor پشتیبانی می‌کنند اما یکی از آن‌ها به مراتب کم‌حجم‌تر است.

دلیل این تفاوت حجم کاملاً مشخص است. وقتی کانال آلفا را غیرفعال می‌کنیم با چنین تصویری مواجه می‌شویم:

با اینکه کانال آلفا تنها به بخشی از تصاویر اجازه‌ی رندر می‌دهد، مجموعه‌ی کاملی از پیکسل‌ها در لایه‌ی RGB وجود دارد. این یعنی مراحل Filtering و Deflate هنوز هم فرصت فشرده‌سازی داده‌ها را دارند. اما اگر مطمئنید که این پیکسل‌ها دیده نمی‌شوند مطمئن شوید که یکسان و تک رنگ باشند. وقتی پیکسل‌های غیرقابل روئیت را با مقدار مشخصی پر می‌کنیم، بخشی از تصویر که دیده نمی‌شود را به صورت تخت رنگ می‌زنیم. نتیجه این است که بخش عمده‌ی هر سطر از یک رنگ واحد تشکیل خواهد شد. بنابراین تکرار مقادیر زیاد شده و نهایتاً در مرحله‌ی Deflate فشرده‌سازی بیشتری صورت خواهد گرفت.

بخوانید  پیش گفتار:چرا من باید برنامه نویس اندروید بشم؟!

پیش‌پردازش اتلافی

مد Indexed در تصاویر PNG واقعاً جالب است ولی متاسفانه هر تصویری را نمی‌توان تنها با ۲۵۶ رنگ نشان داد. برخی از تصاویر نیازمند ۲۵۷، ۳۱۰، ۵۱۲ یا ۹۱۲ رنگ هستند. ولی از آنجایی که مد Indexed فقط ۲۵۶ رنگ دارد ناچاریم این تصاویر را به فرم پیش‌فرض ۲۴bpp ذخیره کنیم حتی اگر یک رنگ بیشتر از ۲۵۶ رنگ نیاز داشته باشیم. خوشبختانه با کاهش تعداد رنگ‌ها به صورت دستی می‌توانید به چیزی شبیه همان تصاویر Indexed دست پیدا کنید.

فرایند تولید تصاویر Indexed را شاید برای سنجش یا کوانتیزاسیون تصاویر وکتور (VQ: Vector Quantization) بهتر توضیح داد. این کار مجموعه‌ای از فرایندهای رندسازی برای اعداد چند بعدی است. به عبارت دیگر، تمام رنگ‌های داخل تصویر با توجه به شباهت و نزدیکی‌شان با هم گروه‌بندی می‌شود. برای هر گروه، همه‌ی رنگ‌های موجود در آن با یک رنگ خاص که معمولاً میانگین رنگ‌های آن دسته (یا site) می‌باشد جایگزین می‌شود.  تصویر پایین این فرایند را برای مجموعه‌ای از مقادیر در حالت دو بعدی نشان می‌دهد:

نتیجه‌ی این فرایند، کاهش تعداد رنگ‌های منحصربه‌فرد و جایگزین شدنشان با رنگ‌های نزدیک است. این کار اجازه می‌دهد تا حداکثر رنگ‌های قابل استفاده در یک تصویر را تعریف کنید. به عنوان مثال، تصویر پایین نمایشی ۲۴ بیتی در هر پیکسل از سر طوطی است. تصویر کناری تنها از ۱۶ رنگ منحصر‌به‌فرد تشکیل شده است.

همانطور که می‌بینید کیفیت تصویر دستخوش تغییر شده است. بخش عمده‌ی سایه‌ها و گرادینت‌ها با رنگ ثابتی جایگزین شده است. این تصویر به بیش از ۱۶ رنگ منحصر‌به‌فرد نیاز دارد. تنظیم فاز VQ در فرایند کاهش حجم تصاویر به شما کمک می‌کند تا حداقل تعدادرنگ‌های لازم برای توصیف یک تصویر را پیدا کنید. متاسفانه هیچ ابزاری به جز pngquant سراغ ندارم که کمک کنند این مرحله را به صورت دستی انجام دهید. بنابراین صرفنظر از اینکه بخواهید از این ابزار استفاده کنید یا نه، باید VQ شخصی خودتان را بسازید.

حرف آخر

ابزارهای زیادی برای بهینه‌سازی تصاویر PNG وجود دارد. فهرستی از آن‌ها را بیان کردم و مابقی را هم می‌توانید در اینترنت جستجو کنید. سازندگان این ابزارها  قطعاً وقت زیادی را صرف آن کرده‌اند تا بهترین نتیجه را رقم بزنند اما هیچ وقت کار خود را به صورت کامل به ابزارها نسپارید بخصوص در بحث فشرده‌سازی. سعی کنید از هنر، سلیقه و ابتکار خود استفاد کنید و قبل از دست به ابزار شدن، تصاویر را تا آنجایی که راه دارد فشرده کنید. گاهی با تغییرات کوچکی می‌توانید نتایج بزرگی را شاهد باشید. هنر شما شناسایی این تغییرات است و تصاویر کم‌حجم‌تر یعنی برنامه‌ی کم‌حجم‌تر.

سید ایوب کوکبی

نویسنده و مترجم...

0 دیدگاه

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *