Страница 1 из 1

Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 05 авг 2016, 02:10
DbIMok
Все знают, как важен размер билдов для мобилок и веба. Один из вариантов сэкономить (размер билда, не в памяти) положить часть графики в виде jpg/png в StreamingAssets. Но не все знают, что "обычный", сохраняемый графическим редактором png зачастую можно сжать еще на 10-15%. Этим занимаются различные утилитки. Я, протестировав несколько штук, остановился на OptiPNG. И так, качаем ее и кладем в Assets/OptiPNG каталог. Для автоматизации процесса оптимизации копипастим следующий код в свой любимый Editor скрипт:
Синтаксис:
Используется csharp
    #region OptiPNG

    static void OptiPNG(string path) {
        string fileName = Application.dataPath + "/OptiPNG/optipng.exe";
        Process opti = new Process();
        try {
            opti.StartInfo.FileName = fileName;
            opti.StartInfo.Arguments = path;
            opti.StartInfo.CreateNoWindow = true;
            opti.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            opti.Start();
        } catch (Exception e) {
            Debug.LogErrorFormat("{0} exe: {1} param: {2}", e.Message, fileName, path);
        }
    }

    [MenuItem("Assets/OptiPNG", true)]
    public static bool OptiPNG_Validator() {
        string[] guids = Selection.assetGUIDs;
        string path;
        for (int i = 0; i < guids.Length; i++) {
            path = AssetDatabase.GUIDToAssetPath(guids[i]);
            if (path.Contains(".png") || Directory.Exists(path)) return true;
        }
        return false;
    }

    [MenuItem("Assets/OptiPNG")]
    public static void OptiPNG_Menu() {
        string[] guids = Selection.assetGUIDs;
        string path;
        for (int i = 0; i < guids.Length; i++) {
            EditorUtility.DisplayProgressBar("Optimizing PNG", i + "/" + guids.Length, (float)i / guids.Length);
            path = AssetDatabase.GUIDToAssetPath(guids[i]);
            if (path.Contains(".png")) {
                path = new DirectoryInfo(path).FullName;
                OptiPNG(path);
            } else {
                if (Directory.Exists(path)) {
                    OptiPNG(new DirectoryInfo(path).FullName + "/*.png");
                    foreach (DirectoryInfo d in new DirectoryInfo(path).GetDirectories("*", SearchOption.AllDirectories)) {
                        OptiPNG(d.FullName + "/*.png");
                    }
                }
            }
        }
        EditorUtility.ClearProgressBar();
    }

    #endregion
 

Выделяем каталог или png файлы в StreamingAssets (все же понимают, что в других местах оптимизировать нет смысла?) щелкаем ПКМ и в меню выбираем OptiPNG. В случае каталога, будут обработаны файлы в том числе во всех подкаталогах.
OptiPngExample.zip

Не из юнити можно использовать FileOptimizer

Re: Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 05 авг 2016, 09:29
samana
Ух ты, я вообще не знал, что Unity так умеет, спасибо!

Re: Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 07 ноя 2016, 18:35
jet_aleks
а можно получить от автора папочку с вложения optipng, а то скачанная с интернета по ссылке дает ошибки.?

Re: Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 07 ноя 2016, 20:01
DbIMok
добавил пример с котиками, заодно исправил баг с необработкой файлов в текущем выбранном каталоге, перенес OptiPng в корень проекта из Assets, для утилит это правильнее.

Re: Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 08 ноя 2016, 11:08
jet_aleks
я дико извиняюсь, но я не пойму как использовать дальше текстуры которые в стриминг ассет пережаты?

Re: Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 08 ноя 2016, 11:25
DbIMok
грузить через www или файловыми операциями

Re: Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 08 ноя 2016, 11:31
jet_aleks
ага, я понял, спасибо, давно искал как работать со сжатием в стрисминг ассет!!=)) :ymparty:

Re: Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 11 мар 2017, 16:17
DbIMok
OptiPNG очень старая https://css-ig.net/png-test-corpus поэтому лучше использовать ECT или pingo
Синтаксис:
Используется csharp
    #region Compress

    static void Compress(string path) {
        Process opti = new Process();
        try {
            Stopwatch sw = Stopwatch.StartNew();
            opti.StartInfo.FileName = prjPath + "Compress/ECT_x64_default.exe";
            opti.StartInfo.Arguments = string.Format("-9 -strip -recurse {0}", path);
            opti.StartInfo.CreateNoWindow = true;
            opti.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            opti.StartInfo.UseShellExecute = false;
            opti.StartInfo.RedirectStandardOutput = true;
            opti.Start();
            string output = opti.StandardOutput.ReadToEnd();
            opti.WaitForExit();
            Debug.LogFormat("Time: {0} s {1}", sw.ElapsedMilliseconds / 1000, output);
        } catch (Exception e) {
            Debug.LogErrorFormat("{0}", e.Message);
        }
    }

    [MenuItem("Assets/Compress", true)]
    public static bool Compress_Validator() {
        string[] guids = Selection.assetGUIDs;
        string path;
        for (int i = 0; i < guids.Length; i++) {
            path = AssetDatabase.GUIDToAssetPath(guids[i]);
            if (path.Contains(".png") || path.Contains(".jpg") || Directory.Exists(path)) return true;
        }
        return false;
    }

    [MenuItem("Assets/Compress")]
    public static void Compress_Menu() {
        string[] guids = Selection.assetGUIDs;
        string path;
        for (int i = 0; i < guids.Length; i++) {
                path = AssetDatabase.GUIDToAssetPath(guids[i]);
                EditorUtility.DisplayProgressBar("Compress Images", string.Format("{0}/{1} {2}", i, guids.Length, path), (float)i/guids.Length);
                Compress(path);
        }
        EditorUtility.ClearProgressBar();
    }

    #endregion

Re: Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 17 мар 2017, 21:48
DbIMok
вот этой можно jpg хорошо жать https://github.com/google/guetzli

Re: Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 17 мар 2017, 23:22
Woolf
Расскажу маленький секрет - для многих "тяжелых" изображений, достаточно в фотошопе перевести его в 8мибитный индексированный цвет, а потом обратно в RGBA и сохранить в jpg или png. Размер уменьшится в разы, без видимой потери качества. Разумеется, не стоит жать таким образом картинки, содержащие большие градиенты, например, небо.

Пример:

Исходное фото, размер 730 кб
Изображение


После процедуры, размер 215 кб
Изображение

Re: Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 17 мар 2017, 23:56
DbIMok
Изображение
и ручками вообще ничего делать не надо. а если оригинал пожать в jpg через guetzli, то 81,5 КБ (83 509 байт) в смысле трюк хороший, но утилиты не заменит

Re: Оптимизация размера PNG файлов в билде

СообщениеДобавлено: 28 мар 2017, 22:59
DbIMok
свежая версия ECT на максимальном сжатии теперь работает быстро
Архив тестового проекта с котиками. в окне Project жмем ПКМ на файлах или каталогах, выбираем Compress > JPG или Compress > PNG. в StreamingAssets пара JPG/PNG файликов и их .bak копии для сравнения