├── .gitattributes ├── Tools ├── apps │ ├── advdef.exe │ ├── deflopt.exe │ ├── gifsicle.exe │ ├── jpegtran.exe │ ├── jpginfo.exe │ ├── truepng.exe │ ├── browsefolder.exe │ ├── jpegstripper.exe │ └── pngwolfzopfli.exe ├── scripts │ ├── filter.js │ ├── pfilter.js │ └── update.js └── config.ini ├── LICENSE.md ├── LICENSE.RU.md ├── README.md ├── README.RU.md └── iCatalyst.bat /.gitattributes: -------------------------------------------------------------------------------- 1 | *.bat text eol=crlf 2 | *.ini text eol=crlf 3 | *.js text eol=crlf -------------------------------------------------------------------------------- /Tools/apps/advdef.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorents17/iCatalyst/HEAD/Tools/apps/advdef.exe -------------------------------------------------------------------------------- /Tools/apps/deflopt.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorents17/iCatalyst/HEAD/Tools/apps/deflopt.exe -------------------------------------------------------------------------------- /Tools/apps/gifsicle.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorents17/iCatalyst/HEAD/Tools/apps/gifsicle.exe -------------------------------------------------------------------------------- /Tools/apps/jpegtran.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorents17/iCatalyst/HEAD/Tools/apps/jpegtran.exe -------------------------------------------------------------------------------- /Tools/apps/jpginfo.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorents17/iCatalyst/HEAD/Tools/apps/jpginfo.exe -------------------------------------------------------------------------------- /Tools/apps/truepng.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorents17/iCatalyst/HEAD/Tools/apps/truepng.exe -------------------------------------------------------------------------------- /Tools/scripts/filter.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorents17/iCatalyst/HEAD/Tools/scripts/filter.js -------------------------------------------------------------------------------- /Tools/scripts/pfilter.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorents17/iCatalyst/HEAD/Tools/scripts/pfilter.js -------------------------------------------------------------------------------- /Tools/apps/browsefolder.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorents17/iCatalyst/HEAD/Tools/apps/browsefolder.exe -------------------------------------------------------------------------------- /Tools/apps/jpegstripper.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorents17/iCatalyst/HEAD/Tools/apps/jpegstripper.exe -------------------------------------------------------------------------------- /Tools/apps/pngwolfzopfli.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lorents17/iCatalyst/HEAD/Tools/apps/pngwolfzopfli.exe -------------------------------------------------------------------------------- /Tools/scripts/update.js: -------------------------------------------------------------------------------- 1 | var args = WScript.Arguments; 2 | if(args.Count() != 1) WScript.Quit(1); 3 | var req = new ActiveXObject("Msxml2.ServerXMLHTTP"); 4 | //var req = new ActiveXObject("Microsoft.XMLHTTP"); 5 | if (req) { 6 | req.open("GET", args(0), false); 7 | req.setRequestHeader("Cache-Control", "max-age=0"); 8 | try { 9 | req.send(null); 10 | if (req.readyState == 4) 11 | if (req.status == 200) { 12 | WScript.echo(req.responseText); 13 | WScript.Quit(0); 14 | } 15 | } catch(e) { 16 | WScript.Quit(3); 17 | } 18 | } 19 | WScript.Quit(2); -------------------------------------------------------------------------------- /Tools/config.ini: -------------------------------------------------------------------------------- 1 | [options] 2 | ;Number of streams. If value is 0, the %NUMBER_OF_PROCESSORS% value is used 3 | thread=0 4 | 5 | ;Image saving options: 6 | ;true - open dialog box for saving images; 7 | ;false - replace original image with optimized; 8 | ;path - directory for output files. 9 | outdir=true 10 | 11 | ;Check update 12 | update=true 13 | 14 | [PNG] 15 | ;PNG optimization modes: 16 | ;/a# - PNG dirty transparency 0=Clean, 1=Optimize; 17 | ;/g# - PNG gamma 0=Remove, 1=Apply & Remove, 2=Keep; 18 | ;/na - PNG don't change RGB values for fully transparent pixels; 19 | ;/nc - PNG don't change ColorType and BitDepth; 20 | ;/np - PNG don't change Palette. 21 | advanced=/a0 /g0 22 | xtreme=/a1 /g0 23 | 24 | ;Remove PNG Metadata (Chunks) 25 | pngtags=true 26 | 27 | [JPEG] 28 | ;Remove JPEG Metadata 29 | jpegtags=true 30 | 31 | [GIF] 32 | ;Remove GIF Metadata 33 | giftags=true -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2010-2016 Lorents & Res2001 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /LICENSE.RU.md: -------------------------------------------------------------------------------- 1 | Лицензия MIT 2 | 3 | Copyright (c) 2010-2016 Lorents & Res2001 4 | 5 | Данная лицензия разрешает лицам, получившим копию данного программного обеспечения и сопутствующей документации (в дальнейшем именуемыми «Программное Обеспечение»), безвозмездно использовать Программное Обеспечение без ограничений, включая неограниченное право на использование, копирование, изменение, добавление, публикацию, распространение, сублицензирование и/или продажу копий Программного Обеспечения, также как и лицам, которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий: 6 | 7 | Указанное выше уведомление об авторском праве и данные условия должны быть включены во все копии или значимые части данного Программного Обеспечения. 8 | 9 | ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ ИЛИ ДРУГИХ ТРЕБОВАНИЙ ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ ИНОМУ, ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Image Catalyst 2 | 3 | Lossless PNG, JPEG and GIF image optimization / compression for Windows. 4 | 5 | |![Adobe Photoshop](https://cloud.githubusercontent.com/assets/3890881/12113971/831d0e22-b3b7-11e5-8f6d-a5cc8f993767.png)|![Image Catalyst](https://cloud.githubusercontent.com/assets/3890881/12110952/70ce4462-b3a2-11e5-8b29-a3822b246dfe.png)| 6 | |:----------|:----------| 7 | |Adobe Photoshop CC 2015 (Export as) — 56.10 KB|Image Catalyst (Xtreme) — 51.25 KB| 8 | 9 | Created by [**Lorents**](https://github.com/lorents17) & [**Res2001**](https://github.com/res2001) 10 | 11 | ### Tools 12 | 13 | ##### PNG: 14 | - AdvDef ([AdvanceComp](https://github.com/amadvance/advancecomp) 1.23) 15 | - DeflOpt 2.07 16 | - [PNGWolfZopfli](https://github.com/jibsen/pngwolf-zopfli) 1.0.1 17 | - [TruePNG](http://x128.ho.ua/pngutils.html) 0.6.2.2 18 | 19 | ##### JPEG: 20 | - [JPEGinfo](http://rtfreesoft.blogspot.ru/2014/03/jpginfo.html) от 16.03.2014 21 | - [JPEGstripper](http://rtfreesoft.blogspot.ru/2014/03/jpegstripper.html) от 16.03.2014 22 | - JPEGTran ([MozJPEG](https://github.com/mozilla/mozjpeg) 3.1) 23 | 24 | ##### GIF: 25 | - [GIFSicle](https://github.com/kohler/gifsicle) 1.88 26 | 27 | ### System requirements 28 | 29 | Operating system — Windows XP SP3 and higher. 30 | 31 | ### Command line options (cmd.exe) 32 | 33 | ``` 34 | call iCatalyst.bat [options] [add directories \ add files] 35 | 36 | Options: 37 | 38 | /png:# PNG optimization mode (Non-Interlaced): 39 | 1 - Compression level - Advanced 40 | 2 - Compression level - Xtreme 41 | 0 - Skip (default) 42 | 43 | /jpg:# JPEG optimization mode: 44 | 1 - Encoding Process - Baseline 45 | 2 - Encoding Process - Progressive 46 | 3 - use settings of original image 47 | 0 - Skip (default) 48 | 49 | /gif:# GIF optimization mode: 50 | 1 - use settings of original image 51 | 0 - Skip (default) 52 | 53 | "/outdir:#" image saving options: 54 | true - open dialog box for saving images (default) 55 | false - replace original image with optimized 56 | "full path to directory" - specify directory to save images to. 57 | for example: "/outdir:C:\temp". If the destination directory 58 | does not exist, it will be created automatically. 59 | 60 | Add directories \ Add files: 61 | - Specify full image paths and / or paths to directories containing images. 62 | For example: "C:\Images" "C:\logo.png" 63 | - Full image paths should not contain any special characters such as 64 | "&", "%", "(", ")" etc. 65 | - Images in sub-directories are optimized recursively. 66 | 67 | Examples: 68 | call iCatalyst.bat /gif:1 "/outdir:C:\photos" "C:\images" 69 | call iCatalyst.bat /png:2 /jpg:2 "/outdir:true" "C:\images" 70 | ``` 71 | 72 | ### Drag and Drop 73 | 74 | ![Drag and Drop](https://cloud.githubusercontent.com/assets/3890881/7943598/28496fd4-096e-11e5-8df6-d6415e47caf8.png) 75 | 76 | - Full image paths should not contain any special characters such as `&`, `%`, `(`, `)`, `!` etc. 77 | - Images in sub-directories are optimized recursively. 78 | 79 | ### PNG optimization settings 80 | 81 | ![PNG](https://cloud.githubusercontent.com/assets/3890881/10802485/3504f4e4-7dce-11e5-85cf-a07fdb822c2b.PNG) 82 | 83 | |Advanced|Xtreme| 84 | |:-------|:----------| 85 | |![Advanced](https://cloud.githubusercontent.com/assets/3890881/7943713/f816fd26-096e-11e5-8a8d-036e9fd443bf.png)|![Xtreme](https://cloud.githubusercontent.com/assets/3890881/12110960/92a49db6-b3a2-11e5-9953-adde90844087.png)| 86 | |Size — 55.57 KB; Optimization time — 1.5 s|Size — 54.67 KB; Optimization time — 7.5 s| 87 | |`TruePNG` ([zlib](https://github.com/madler/zlib)) + `Advdef` ([libdeflate](https://github.com/ebiggers/libdeflate))|`TruePNG` ([zlib](https://github.com/madler/zlib)) + `PNGWolfZopfli` ([zopfli](https://github.com/google/zopfli))||Compression ratio is about 10% higher compared to Adobe Photoshop CC 2015 (Export as)|Compression ratio is about 2% higher compared to Advanced optimization modes, compression speed is 5 times better| 88 | 89 | - `Skip` — skip optimization of PNG images. 90 | 91 | Interlace option: 92 | - `None` — displays the image in a browser only when download is complete. 93 | - `Interlaced` — displays low-resolution versions of the image in a browser as the file downloads. Interlacing makes download time seem shorter, but it also increases file size (not support). 94 | 95 | ### JPEG optimization settings 96 | 97 | ![JPEG](https://cloud.githubusercontent.com/assets/3890881/10802484/34d79cec-7dce-11e5-886f-ea71fdc93214.PNG) 98 | 99 | |Baseline|Progressive| 100 | |:-------|:----------| 101 | |![Baseline](https://cloud.githubusercontent.com/assets/3890881/7943666/9c3c1324-096e-11e5-8cf1-bceade0ebd85.gif)|![Progressive](https://cloud.githubusercontent.com/assets/3890881/7943679/ace1271e-096e-11e5-9ca4-6f33f421ca52.gif)| 102 | |For image < 10 KB, it is recommended to use — `Baseline` ([read more](http://yuiblog.com/blog/2008/12/05/imageopt-4/))|For image > 10 KB, it is recommended to use — `Progressive` ([read more](http://yuiblog.com/blog/2008/12/05/imageopt-4/))| 103 | 104 | - `Default` — uses settings of original images; 105 | - `Skip` — skip optimization of JPEG images. 106 | 107 | ### GIF optimization settings 108 | 109 | ![GIF](https://cloud.githubusercontent.com/assets/3890881/10802483/34d638a2-7dce-11e5-9b95-e39aa476c73d.PNG) 110 | 111 | - `Default` — uses settings of original images; 112 | - `Skip` — skip optimization of GIF images. 113 | 114 | ### Config.ini 115 | 116 | Open the file `Tools\config.ini` with any text editor and follow the instructions. 117 | 118 | ``` 119 | [options] 120 | ;Number of streams. If value is 0, the %NUMBER_OF_PROCESSORS% value is used 121 | thread=0 122 | 123 | ;Image saving options: 124 | ;true - open dialog box for saving images; 125 | ;false - replace original image with optimized; 126 | ;path - directory for output files. 127 | outdir=true 128 | 129 | ;Check update 130 | update=true 131 | 132 | [PNG] 133 | ;PNG optimization modes: 134 | ;/a# - PNG dirty transparency 0=Clean, 1=Optimize; 135 | ;/g# - PNG gamma 0=Remove, 1=Apply & Remove, 2=Keep; 136 | ;/na - PNG don't change RGB values for fully transparent pixels; 137 | ;/nc - PNG don't change ColorType and BitDepth; 138 | ;/np - PNG don't change Palette. 139 | xtreme=/a1 /g0 140 | advanced=/a0 /g0 141 | 142 | ;Remove PNG Metadata (Chunks) 143 | pngtags=true 144 | 145 | [JPEG] 146 | ;Remove JPEG Metadata 147 | jpegtags=true 148 | 149 | [GIF] 150 | ;Remove GIF Metadata 151 | giftags=true 152 | ``` 153 | 154 | ### Additionally 155 | - To pause optimization process click on right mouse button in the command prompt window and choose "Select all" in the context menu. To resume click right mouse button again. 156 | - By default optimization runs in multi-threading mode. It is not recommended to run in more than one copy of the application, as it will significantly reduce both the image optimization speed and system performance overall. To disable multi-threading mode, open the file `Tools\config.ini` with any text editor and follow the instructions. 157 | 158 | ### Thanks 159 | - Thanks to the authors of the applications that are used in the project; 160 | - Thanks to the participants of [encode.ru](http://encode.ru/), [forum.ru-board.com](http://forum.ru-board.com/), [forum.script-coding.com](http://script-coding.com/forum/), [forum.vingrad.ru](http://forum.vingrad.ru/) and [cyberforum.ru](http://www.cyberforum.ru/) for contribution to the development of the project; 161 | - Thanks [**X128**](http://x128.ho.ua/) for his huge contribution to the development of the project. 162 | 163 | ### Alpha version 164 | https://github.com/res2001/iCatalyst 165 | 166 | ### License 167 | This software is released under the terms of the [MIT](https://github.com/lorents17/iCatalyst/blob/master/LICENSE.md) license. 168 | 169 | ### Future plans 170 | - add support of optimization of SVG; 171 | - add support of optimization of PNG and JPEG lossy. 172 | -------------------------------------------------------------------------------- /README.RU.md: -------------------------------------------------------------------------------- 1 | # Image Catalyst 2 | 3 | Оптимизация / сжатие изображений PNG, JPEG и GIF без потери качества для Windows. 4 | 5 | |![Adobe Photoshop](https://cloud.githubusercontent.com/assets/3890881/12113971/831d0e22-b3b7-11e5-8f6d-a5cc8f993767.png)|![Image Catalyst](https://cloud.githubusercontent.com/assets/3890881/12110952/70ce4462-b3a2-11e5-8b29-a3822b246dfe.png)| 6 | |:----------|:----------| 7 | |Adobe Photoshop CC 2015 (Экспортировать как) — 56,10 КБ|Image Catalyst (Xtreme) — 51,25 КБ| 8 | 9 | Авторы — [**Lorents**](https://github.com/lorents17) & [**Res2001**](https://github.com/res2001) 10 | 11 | ### Инструменты 12 | 13 | ##### PNG: 14 | - AdvDef ([AdvanceComp](https://github.com/amadvance/advancecomp) 1.23) 15 | - DeflOpt 2.07 16 | - [PNGWolfZopfli](https://github.com/jibsen/pngwolf-zopfli) 1.0.1 17 | - [TruePNG](http://x128.ho.ua/pngutils.html) 0.6.2.2 18 | 19 | ##### JPEG: 20 | - [JPEGinfo](http://rtfreesoft.blogspot.ru/2014/03/jpginfo.html) от 16.03.2014 21 | - [JPEGstripper](http://rtfreesoft.blogspot.ru/2014/03/jpegstripper.html) от 16.03.2014 22 | - JPEGTran ([MozJPEG](https://github.com/mozilla/mozjpeg) 3.1) 23 | 24 | ##### GIF: 25 | - [GIFSicle](https://github.com/kohler/gifsicle) 1.88 26 | 27 | ### Системные требования 28 | 29 | Операционная система — Windows XP SP3 и выше. 30 | 31 | ### Параметры командной строки (cmd.exe) 32 | 33 | ``` 34 | call iCatalyst.bat [options] [add folders \ add files] 35 | 36 | Options: 37 | 38 | /png:# Параметры оптимизации PNG (Non-Interlaced): 39 | 1 - Уровень сжатия - Advanced 40 | 2 - Уровень сжатия - Xtreme 41 | 0 - пропустить оптимизацию 42 | 43 | /jpg:# Параметры оптимизации JPEG: 44 | 1 - Encoding Process - Baseline 45 | 2 - Encoding Process - Progressive 46 | 3 - параметры оптимизации оригинального изображения 47 | 0 - пропустить оптимизацию 48 | 49 | /gif:# Параметры оптимизации GIF: 50 | 1 - параметры оптимизации оригинального изображения 51 | 0 - пропустить оптимизацию 52 | 53 | "/outdir:#" Параметры сохранения изображений: 54 | true - открыть диалоговое окно для сохранения изображений 55 | false - заменить оригинальные изображения на оптимизированные 56 | "полный путь к папке" - папка сохранения изображений. Например: "/outdir:C:\temp", 57 | если папки назначения не существует, то она будет создана автоматически. 58 | 59 | Add folders \ Add files 60 | - Укажите полный путь к изображениям и\или к папкам с изображениями. 61 | Например: "C:\Images" "C:\logo.png". 62 | - В полных путях изображений не должно быть специальных символов. 63 | Например: &, %, (, ), ! и т.д. 64 | - Приложение оптимизирует изображения во вложенных подпапках. 65 | 66 | Примеры: 67 | call iCatalyst.bat /gif:1 "/outdir:C:\photos" "C:\images" 68 | call iCatalyst.bat /png:2 /jpg:2 "/outdir:true" "C:\images" 69 | ``` 70 | 71 | ### Drag and Drop 72 | 73 | ![Drag and Drop](https://cloud.githubusercontent.com/assets/3890881/7943598/28496fd4-096e-11e5-8df6-d6415e47caf8.png) 74 | 75 | - В полных путях изображений не должно быть специальных символов. Например: `&`, `%`, `(`, `)`, `!` и т.д. 76 | - Приложение оптимизирует изображения во вложенных подпапках. 77 | 78 | ### Параметры оптимизации PNG 79 | 80 | ![PNG](https://cloud.githubusercontent.com/assets/3890881/10802485/3504f4e4-7dce-11e5-85cf-a07fdb822c2b.PNG) 81 | 82 | |Advanced|Xtreme| 83 | |:-------|:----------| 84 | |![Advanced](https://cloud.githubusercontent.com/assets/3890881/7943713/f816fd26-096e-11e5-8a8d-036e9fd443bf.png)|![Xtreme](https://cloud.githubusercontent.com/assets/3890881/12110960/92a49db6-b3a2-11e5-9953-adde90844087.png)| 85 | |Размер — 55,57 КБ; Время оптимизации — 1,5 с|Размер — 54,67 КБ; Время оптимизации — 7,5 с| 86 | |`TruePNG` ([zlib](https://github.com/madler/zlib)) + `Advdef` ([libdeflate](https://github.com/ebiggers/libdeflate))|`TruePNG` ([zlib](https://github.com/madler/zlib)) + `PNGWolfZopfli` ([zopfli](https://github.com/google/zopfli))| 87 | |Степень сжатия на ~ 10% выше по сравнению с Adobe Photoshop CC 2015 (Экспортировать как)|Степень сжатия на ~ 2% выше по сравнению с режимом оптимизации Advanced, скорость сжатия ниже ~ 5 раз| 88 | 89 | - `Skip` — пропускает оптимизацию изображений PNG. 90 | 91 | Параметр "Чересстрочно": 92 | - `Нет` — отображает изображение в браузере только после окончания загрузки. 93 | - `Чересстрочно` — отображает версии изображения с низким разрешением в браузере по мере поступления данных во время загрузки файла. Использование этого параметра сокращает время загрузки, однако увеличивает размер файла (не поддерживается). 94 | 95 | ### Параметры оптимизации JPEG 96 | 97 | ![JPEG](https://cloud.githubusercontent.com/assets/3890881/10802484/34d79cec-7dce-11e5-886f-ea71fdc93214.PNG) 98 | 99 | |Baseline|Progressive| 100 | |:-------|:----------| 101 | |![Baseline](https://cloud.githubusercontent.com/assets/3890881/7943666/9c3c1324-096e-11e5-8cf1-bceade0ebd85.gif)|![Progressive](https://cloud.githubusercontent.com/assets/3890881/7943679/ace1271e-096e-11e5-9ca4-6f33f421ca52.gif)| 102 | |Для изображений < 10 КБ, рекомендуется использовать — `Baseline` ([подробнее](http://webo.in/articles/habrahabr/73-jpeg-baseline-progressive/))|Для изображений > 10 КБ, рекомендуется использовать — `Progressive` ([подробнее](http://webo.in/articles/habrahabr/73-jpeg-baseline-progressive/))| 103 | 104 | - `Default` — использует параметры оптимизации оригинального изображения; 105 | - `skip` — пропускает оптимизацию изображений JPEG. 106 | 107 | ### Параметры оптимизации GIF 108 | 109 | ![GIF](https://cloud.githubusercontent.com/assets/3890881/10802483/34d638a2-7dce-11e5-9b95-e39aa476c73d.PNG) 110 | 111 | - `Default` — использует параметры оптимизации по умолчанию; 112 | - `Skip` — пропускает оптимизацию изображений GIF. 113 | 114 | ### Config.ini 115 | 116 | Откройте файл `Tools\config.ini` любым текстовым редактором и следуйте инструкции. 117 | 118 | ``` 119 | [options] 120 | ;Количество потоков. 121 | ;Если указано значение 0, то выбирается значение равное системной переменной %NUMBER_OF_PROCESSORS%. 122 | thread=0 123 | 124 | ;Параметры сохранения изображений: 125 | ;true - открыть диалоговое окно для сохранения изображений; 126 | ;false - заменить оригинальные изображения на оптимизированные; 127 | ;path - путь к папке для сохранения исходящих изображений. 128 | outdir=true 129 | 130 | ;Проверить обновление. 131 | update=true 132 | 133 | [PNG] 134 | ;Параметры оптимизации PNG: 135 | ;/a# - PNG dirty transparency 0=Clean, 1=Optimize; 136 | ;/g# - PNG gamma 0=Remove, 1=Apply & Remove, 2=Keep; 137 | ;/na - PNG don't change RGB values for fully transparent pixels; 138 | ;/nc - PNG don't change ColorType and BitDepth; 139 | ;/np - PNG don't change Palette. 140 | xtreme=/a1 /g0 141 | advanced=/a0 /g0 142 | 143 | ;Удалить метаданные (chunks). 144 | pngtags=true 145 | 146 | [JPEG] 147 | ;Удалить метаданные. 148 | jpegtags=true 149 | 150 | [GIF] 151 | ;Удалить метаданные. 152 | giftags=true 153 | ``` 154 | 155 | ### Дополнительно 156 | - Поставить оптимизацию изображений на паузу. Для этого в окне командной строки приложения нажмите на правую кнопку мышки и выберите "Выделить все", для продолжения оптимизации изображения в окне командной строки приложения нажмите на правую кнопку мышки. 157 | - Многопоточный режим оптимизации изображений. По умолчанию, при оптимизации изображений приложение использует многопоточный режим. Настоятельно не рекомендуется запускать параллельно более одной копии приложения, т.к. это существенно снизит как скорость оптимизации изображений, так и быстродействие всей системы в целом. Для отключения многопоточного режима откройте файл `Tools\config.ini` любым текстовым редактором и следуйте инструкции. 158 | 159 | ### Благодарности 160 | - Благодарим авторов приложений, которые используются в проекте; 161 | - Благодарим участников форумов [encode.ru](http://encode.ru/), [forum.ru-board.com](http://forum.ru-board.com/), [forum.script-coding.com](http://script-coding.com/forum/), [forum.vingrad.ru](http://forum.vingrad.ru/) и [cyberforum.ru](http://www.cyberforum.ru/) за вклад в развитие проекта; 162 | - Отдельно благодарим [**X128**](http://x128.ho.ua/) за огромный вклад в развитие проекта. 163 | 164 | ### Альфа-версия 165 | https://github.com/res2001/iCatalyst 166 | 167 | ### Лицензия 168 | Данное программное обеспечение выпускается под лицензией [MIT](https://github.com/lorents17/iCatalyst/blob/master/LICENSE.RU.md). 169 | 170 | ### Планы на будущее 171 | - добавить поддержку оптимизации SVG; 172 | - добавить поддержку оптимизации PNG и JPEG с потерями. 173 | -------------------------------------------------------------------------------- /iCatalyst.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | ::Lorents & Res2001 2010-2016 4 | 5 | setlocal enabledelayedexpansion 6 | if #thrd# equ #%~1# call:threadwork %4 %5 "%~2" "%~3" & exit /b 7 | if #updateic# equ #%~1# call:icupdate & exit /b 8 | set "name=Image Catalyst" 9 | set "version=2.7" 10 | set "oldtitle=" 11 | set "consolepid=" 12 | call:getpid consolepid 13 | call:gettitle oldtitle 14 | title %name% 15 | set "spacebar=-------------------------------------------------------------------------------" 16 | if ## equ #%~1# call:helpmsg & exit /b 17 | set "fullname=%~0" 18 | set "scrpath=%~dp0" 19 | set "sconfig=%scrpath%Tools\" 20 | set "scripts=%scrpath%Tools\scripts\" 21 | set "tmppath=%TEMP%\iCatalyst\" 22 | set "errortimewait=3000" 23 | set "iclock=%TEMP%ic.lck" 24 | set "LOG=%scrpath%\iCatalyst" 25 | if exist "%systemroot%\system32\timeout.exe" (set "istimeout=yes") else set "istimeout=" 26 | ::call:runningcheck "%name% %version%" 27 | ::echo.This process is work&pause & title %oldtitle%&exit /b 28 | set "LOG=%LOG%%runic%" 29 | set "apps=%~dp0Tools\apps\" 30 | PATH %apps%;%PATH% 31 | set "nofile=" 32 | set "num=0" 33 | for %%a in ( 34 | "%sconfig%config.ini" 35 | "%apps%advdef.exe" 36 | "%apps%deflopt.exe" 37 | "%apps%browsefolder.exe" 38 | "%apps%gifsicle.exe" 39 | "%apps%jpegstripper.exe" 40 | "%apps%jpginfo.exe" 41 | "%apps%jpegtran.exe" 42 | "%apps%pngwolfzopfli.exe" 43 | "%apps%truepng.exe" 44 | "%scripts%pfilter.js" 45 | "%scripts%filter.js" 46 | "%scripts%update.js" 47 | ) do ( 48 | if not exist "%%~a" ( 49 | set /a "num+=1" 50 | if !num! gtr 20 set "nofile=!nofile!..." & goto:filelisterr 51 | set "nofile=!nofile!"%%~a" " 52 | ) 53 | ) 54 | 55 | :filelisterr 56 | if defined nofile ( 57 | call:clearscreen 58 | title [Error] %name% 59 | if exist "%tmppath%" 1>nul 2>&1 rd /s /q "%tmppath%" 60 | 1>&2 echo.%spacebar% 61 | 1>&2 echo. Application can not get access to the following files: 62 | 1>&2 echo. 63 | for %%j in (%nofile%) do 1>&2 echo. - %%~j 64 | 1>&2 echo. 65 | 1>&2 echo. Check permissions and try again. 66 | 1>&2 echo.%spacebar% 67 | call:dopause 68 | if defined oldtitle title %oldtitle% 69 | exit /b 70 | ) 71 | 72 | :settemp 73 | set "rnd=%random%" 74 | if not exist "%tmppath%%rnd%\" ( 75 | set "tmppath=%tmppath%%rnd%" 76 | 1>nul 2>&1 md "%tmppath%%rnd%" || ( 77 | call:errormsg "Can not create temporary directory:" "%tmppath%%rnd%!" 78 | exit /b 79 | ) 80 | ) else ( 81 | goto:settemp 82 | ) 83 | for %%a in (JPG PNG GIF) do ( 84 | set "ImageNum%%a=0" 85 | set "TotalNum%%a=0" 86 | set "TotalNumErr%%a=0" 87 | set "TotalSize%%a=0" 88 | set "STotalSize%%a=0" 89 | set "ImageSize%%a=0" 90 | set "SImageSize%%a=0" 91 | set "change%%a=0" 92 | set "perc%%a=0" 93 | set "step%%a=0" 94 | set "step10%%a=1000" 95 | set "stepB%%a=1" 96 | ) 97 | set "png=" 98 | set "jpeg=" 99 | set "gif=" 100 | set "perr=" 101 | set "stime=" 102 | set "ftime=" 103 | set "params=" 104 | set "updateurl=http://x128.ho.ua/update.ini" 105 | set "configpath=%~dp0\Tools\config.ini" 106 | set "logfile=%tmppath%\Images" 107 | set "iculog=%tmppath%\icu.log" 108 | set "iculck=%tmppath%\icu.lck" 109 | set "countPNG=%tmppath%\countpng" 110 | set "countJPG=%tmppath%\countjpg" 111 | set "countGIF=%tmppath%\countgif" 112 | set "filelist=%tmppath%\filelist" 113 | set "filelist1=%tmppath%\filelist1" 114 | set "paramfile=%tmppath%\param.txt" 115 | ::For Images with characters - %filelisterr% 116 | ::For Images are already optimized - %filelisterr%1 117 | ::For Images are not supported - %filelisterr%2 118 | ::For Images are not found - %filelisterr%3 119 | set "filelisterr=%tmppath%\filerr" 120 | ::Table size 121 | set "TFN=31" 122 | set "KB=1024" 123 | set /a "MB=KB*KB" 124 | set /a "GB=MB*KB" 125 | ::restrictions in bytes (default - 100Mb) 126 | set /a "BYTECONV=100*%MB%" 127 | 128 | set "thread=" & set "updatecheck=" & set "outdir=" & set "nooutfolder=" & set "perr=" 129 | set "jpegtags=" & set "xtreme=" & set "advanced=" & set "pngtags=" & set "giftags=" 130 | call:readini "%configpath%" 131 | call:sethread %thread% 132 | set "updatecheck=%update%" & set "update=" 133 | if /i "%giftags%" equ "true" (set "giftags=--no-comments --no-extensions --no-names") else (set "giftags=") 134 | call set "outdir=%outdir%" 135 | if defined outdir set oparam="/Outdir:%outdir%" 136 | cscript //nologo //E:JScript "%scripts%pfilter.js" %* %oparam% 1>"%paramfile%" 2>"%filelisterr%" 137 | call:readini "%paramfile%" 138 | if defined perr ( 139 | set "perr=%perr:~,-1%" 140 | set "perr=!perr:;=, !" 141 | call:errormsg "Unknown !perr! setting(s^) value." 142 | exit /b 143 | ) 144 | if not defined params for %%a in ("%filelisterr%") do if %%~za neq 0 ( 145 | 1>&2 ( 146 | echo.%spacebar% 147 | echo. Unknown parameters: 148 | type "%%~a" 149 | echo.%spacebar% 150 | ) 151 | call:errormsg 152 | exit /b 153 | ) 154 | 1>nul 2>&1 del /f/q "%paramfile%" 155 | set "oparam=" 156 | 157 | call:checkparams %params% 158 | if "%png%" equ "0" if "%jpeg%" equ "0" if "%gif%" equ "0" goto:endsetcounters 159 | if /i "%outdir%" equ "false" (set "outdir=" & set "nooutfolder=yes") else if /i "%outdir%" equ "true" set "outdir=" 160 | if not defined nooutfolder if not defined outdir ( 161 | call:clearscreen 162 | title [Loading] %name% 163 | for /f "tokens=* delims=" %%a in ('browsefolder.exe /CurPath:desktop /Title:"Image Catalyst" /Description:"Choose directory to save images to. Click 'Cancel' to replace original images with optimized versions." /block:window /center:window /flag:81') do set "outdir=%%~a" 164 | ) 165 | if defined outdir ( 166 | if "!outdir:~-1!" neq "\" set "outdir=!outdir!\" 167 | if not exist "!outdir!" ( 168 | 1>nul 2>&1 md "!outdir!" || ( 169 | call:errormsg "Can not create directory for optimized files:" "!outdir!" 170 | exit /b 171 | ))) 172 | 173 | title [Loading] %name% 174 | call:clearscreen 175 | echo.%spacebar% 176 | echo. Loading. Please wait... 177 | echo.%spacebar% 178 | 1>nul 2>&1 del /f /q "%filelist%" 179 | for %%a in (%params%) do ( 180 | call:makefilelist %%a 1>"%filelist1%" 2>>"%filelisterr%" 181 | for %%b in ("%filelist1%") do if "%%~zb" neq "0" ( 182 | cscript //nologo //E:JScript "%scripts%filter.js" "/BasePath:%%~a" <"%filelist1%" 1>>"%filelist%" 2>>"%filelisterr%" 183 | )) 184 | :setcounters 185 | if exist "%filelist%" ( 186 | if "%png%" neq "0" for /f "tokens=*" %%a in ('findstr /i /e ".png" "%filelist%" ^| find /i /c ".png" 2^>nul') do set /a "TotalNumPNG+=%%a" 187 | if "%jpeg%" neq "0" for /f "tokens=*" %%a in ('findstr /i /e ".jpg" "%filelist%" ^| find /i /c ".jpg" 2^>nul') do set /a "TotalNumJPG+=%%a" 188 | if "%jpeg%" neq "0" for /f "tokens=*" %%a in ('findstr /i /e ".jpe" "%filelist%" ^| find /i /c ".jpe" 2^>nul') do set /a "TotalNumJPG+=%%a" 189 | if "%jpeg%" neq "0" for /f "tokens=*" %%a in ('findstr /i /e ".jpeg" "%filelist%" ^| find /i /c ".jpeg" 2^>nul') do set /a "TotalNumJPG+=%%a" 190 | if "%gif%" neq "0" for /f "tokens=*" %%a in ('findstr /i /e ".gif" "%filelist%" ^| find /i /c ".gif" 2^>nul') do set /a "TotalNumGIF+=%%a" 191 | ) 192 | if %TotalNumPNG% gtr 0 (if not defined png call:png) else set "png=0" 193 | if %TotalNumJPG% gtr 0 (if not defined jpeg call:jpeg) else set "jpeg=0" 194 | if %TotalNumGIF% gtr 0 (if not defined gif call:gif) else set "gif=0" 195 | if exist "%filelisterr%" ( 196 | if defined png for /f "tokens=* delims=" %%a in ('findstr /i /e ".png" "%filelisterr%" ^| find /i /c ".png" 2^>nul') do set /a "TotalNumErrPNG+=%%a" 197 | if defined jpeg for /f "tokens=* delims=" %%a in ('findstr /i /e ".jpg" "%filelisterr%" ^| find /i /c ".jpg" 2^>nul') do set /a "TotalNumErrJPG+=%%a" 198 | if defined jpeg for /f "tokens=* delims=" %%a in ('findstr /i /e ".jpe" "%filelisterr%" ^| find /i /c ".jpe" 2^>nul') do set /a "TotalNumErrJPG+=%%a" 199 | if defined jpeg for /f "tokens=* delims=" %%a in ('findstr /i /e ".jpeg" "%filelisterr%" ^| find /i /c ".jpeg" 2^>nul') do set /a "TotalNumErrJPG+=%%a" 200 | if defined gif for /f "tokens=* delims=" %%a in ('findstr /i /e ".gif" "%filelisterr%" ^| find /i /c ".gif" 2^>nul') do set /a "TotalNumErrGIF+=%%a" 201 | ) 202 | 203 | :endsetcounters 204 | if %TotalNumPNG% equ 0 if %TotalNumJPG% equ 0 if %TotalNumGIF% equ 0 ( 205 | call:clearscreen 206 | call:errormsg "No images found. Please check input and try again." 207 | exit /b 208 | ) 209 | 210 | call:runningcheck "%name% %version%" 211 | ::echo.This process is work&pause & title %oldtitle%&exit /b 212 | 213 | for /l %%a in (1,1,%thread%) do ( 214 | if "%png%" neq "0" >"%logfile%png.%%a" echo. 215 | if "%jpeg%" neq "0" >"%logfile%jpg.%%a" echo. 216 | if "%gif%" neq "0" >"%logfile%gif.%%a" echo. 217 | ) 218 | 219 | call:clearscreen 220 | echo.%spacebar% 221 | echo. File Name ^| Original ^| Optimized ^| Savings ^| %% Savings 222 | echo. ^| Size ^| Size ^| ^| 223 | echo.%spacebar% 224 | if /i "%updatecheck%" equ "true" start "" /b cmd.exe /c ""%fullname%" updateic" 225 | call:setitle 226 | call:setvtime stime 227 | for /f "usebackq tokens=1,2 delims= " %%a in ("%filelist%") do ( 228 | call:initsource "%%~a" 229 | if defined ispng if "%png%" neq "0" call:filework "%%~fa" "%%~fb" png %thread% ImageNumPNG 230 | if defined isjpeg if "%jpeg%" neq "0" call:filework "%%~fa" "%%~fb" jpg %thread% ImageNumJPG 231 | if defined isgif if "%gif%" neq "0" call:filework "%%~fa" "%%~fb" gif %thread% ImageNumGIF 232 | ) 233 | 234 | :waithread 235 | call:waitflag "%tmppath%\thrt*.lck" 236 | for /l %%z in (1,1,%thread%) do ( 237 | call:typelog png %%z 238 | call:typelog jpg %%z 239 | call:typelog gif %%z 240 | ) 241 | echo.%spacebar% 242 | call:setitle "%name%" 243 | call:end 244 | call:dopause 245 | if defined oldtitle title %oldtitle% 246 | exit /b 247 | 248 | :checkparams 249 | set "ispng=%png%" & set "isjpeg=%jpeg%" & set "isgif=%gif%" 250 | :checkparams1 251 | if "%~1" equ "" ( 252 | if /i "%ispng%" equ "yes" (call:png) else if not defined png set "png=0" 253 | if /i "%isjpeg%" equ "yes" (call:jpeg) else if not defined jpeg set "jpeg=0" 254 | if /i "%isgif%" equ "yes" (call:gif) else if not defined gif set "gif=0" 255 | set "ispng=" & set "isjpeg=" & set "isgif=" 256 | exit /b 257 | ) 258 | set "p=%~1" 259 | if exist "%p:~1%" ( 260 | if /i "%p:~,1%" equ "f" call:checkfile "%p:~1%" 261 | if /i "%p:~,1%" equ "d" call:checkdir "%p:~1%" 262 | ) 263 | shift 264 | goto:checkparams1 265 | 266 | :checkfile 267 | if not defined ispng if /i "%~x1" equ ".png" set "ispng=yes" 268 | if not defined isjpeg ( 269 | if /i "%~x1" equ ".jpg" set "isjpeg=yes" 270 | if /i "%~x1" equ ".jpe" set "isjpeg=yes" 271 | if /i "%~x1" equ ".jpeg" set "isjpeg=yes" 272 | ) 273 | if not defined isgif if /i "%~x1" equ ".gif" set "isgif=yes" 274 | exit /b 275 | 276 | :checkdir 277 | if not defined ispng call:checkmask %1 "*.png" && set "ispng=yes" 278 | if not defined isjpeg call:checkmask %1 ""*.jpg" "*.jpe?"" && set "isjpeg=yes" 279 | if not defined isgif call:checkmask %1 "*.gif" && set "isgif=yes" 280 | exit /b 281 | 282 | :checkmask 283 | for /r "%~1" %%i in (%~2) do exit /b 0 284 | exit /b 1 285 | 286 | :makefilelist 287 | if "%~1" equ "" exit /b 288 | set "p=%~1" 289 | if exist "%p:~1%" ( 290 | if /i "%p:~,1%" equ "f" echo.%p:~1% 291 | if /i "%p:~,1%" equ "d" call:dir2list "%p:~1%" 292 | ) 293 | shift 294 | goto:checkparams 295 | 296 | :dir2list 297 | setlocal 298 | set "mask=" 299 | if "%jpeg%" neq "0" set mask="%~1\*.jpg" "%~1\*.jpe?" 300 | if "%png%" neq "0" set mask=%mask% "%~1\*.png" 301 | if "%gif%" neq "0" set mask=%mask% "%~1\*.gif" 302 | if not defined mask exit /b 303 | dir /a-d /b /s %mask% 304 | endlocal 305 | exit /b 306 | 307 | :runningcheck 308 | title [Waiting] %name% 309 | setlocal 310 | call:runic "%~1" 311 | if %runic% gtr 0 ( 312 | call:clearscreen 313 | echo.%spacebar% 314 | echo. Another process %name% is running. 315 | echo. 316 | echo. Waiting for it to shut down or press any key. 317 | echo.%spacebar% 318 | :: call:runningcheck2 "%~1" 319 | call:runic2 "%~1" 320 | ) 321 | endlocal 322 | title %name% 323 | exit /b 0 324 | 325 | :runningcheck2 326 | 2>nul (5>"%iclock%" call:runic2 "%~1" || ( 327 | call:waitpresskey %errortimewait% || exit /b 1 328 | goto:runningcheck2 329 | )) 330 | exit /b 0 331 | 332 | :runic2 333 | call:waitpresskey %errortimewait% || exit /b 0 334 | call:runic "%~1" 335 | if %runic% gtr 0 goto:runic2 336 | exit /b 0 337 | 338 | :runic 339 | for /f "tokens=* delims=" %%a in ('tasklist /fo csv /v /nh /fi "IMAGENAME eq cmd.exe" ^| find /i /c "%~1" ') do ( 340 | set "runic=%%a" 341 | ) 342 | exit /b 343 | 344 | :setvtime 345 | set "%1=%date% %time:~0,2%:%time:~3,2%:%time:~6,2%" 346 | exit /b 347 | 348 | :icupdate 349 | if not exist "%scripts%update.js" exit /b 350 | >"%iculck%" echo.Update IC 351 | cscript //nologo //E:JScript "%scripts%update.js" %updateurl% 2>nul 1>"%iculog%" || 1>nul 2>&1 del /f /q "%iculog%" 352 | 1>nul 2>&1 del /f /q "%iculck%" 353 | exit /b 354 | 355 | ::%1 - png | jpg | gif 356 | ::%2 - %thread% 357 | ::%3 - input file 358 | ::%4 - output file 359 | :createthread 360 | if %2 equ 1 call:threadwork %1 1 %3 %4 & call:typelog %1 1 & exit /b 361 | for /l %%z in (1,1,%2) do ( 362 | if not exist "%tmppath%\thrt%%z.lck" ( 363 | call:typelog %1 %%z 364 | >"%tmppath%\thrt%%z.lck" echo. Image processing: %3 365 | start /b /LOW /MIN cmd.exe /s /c ""%fullname%" thrd "%~3" "%~4" %1 %%z" 366 | exit /b 367 | ) 368 | ) 369 | call:waitrandom 500 370 | goto:createthread 371 | 372 | ::%1 - png | jpg | gif 373 | ::%2 - thread number 374 | :typelog 375 | if %thread% equ 1 exit /b 376 | if not defined typenum%~1%~2 set "typenum%~1%~2=1" 377 | if not exist "%logfile%%1.%2" exit /b 378 | set "tmpskip=!typenum%~1%~2!" 379 | for /f "usebackq skip=%tmpskip% tokens=1-5 delims=;" %%b in ("%logfile%%1.%2") do ( 380 | call:stepcalc %~1 %%c %%d 381 | call:printfileinfo "%%~b" %%c %%d %%e %%f %~1 382 | set /a "typenum%~1%~2+=1" 383 | ) 384 | exit /b 385 | 386 | ::%1 - file name 387 | ::%2 - original size in byte 388 | ::%3 - optimize size in byte 389 | ::%4 - change (%2 - %3) 390 | ::%5 - percent change (%4*100/%2) 391 | ::%6 - png | jpg | gif 392 | :printfileinfo 393 | setlocal 394 | set "fn=" 395 | call:cropfilename fn "%~1" %TFN% 396 | set "origsize=%~2" 397 | set "optsize=%~3" 398 | set "measure=" 399 | call:prepsize origsize measure 400 | call:prepsize2 optsize measure 401 | set "origsize= %origsize% %measure%" 402 | set "optsize= %optsize% %measure%" 403 | set "change=%~4" 404 | set "origsize2=%~2" 405 | call:prepsize change measure 406 | call:prepsize2 origsize2 measure 407 | call:perccalc %origsize2:.=% %change:.=% percent 408 | set "change= %change% %measure%" 409 | set "percent= %percent%%%" 410 | echo. !fn:~,%TFN%!^|%origsize:~-10%^|%optsize:~-11%^|%change:~-11%^|%percent:~-10% 411 | endlocal 412 | exit /b 413 | 414 | ::%1 - variable name for number (in/out) 415 | ::%2 - variable name for measure (out) 416 | :prepsize 417 | setlocal 418 | set "var=!%~1!" 419 | set "sign=" 420 | if "%var:~,1%" equ "-" (set "sign=-" & set "var=%var:~1%") 421 | set "meas=B" 422 | if %var% geq %GB% (set "meas=GB" & goto:GBprepsize) 423 | if %var% geq %MB% (set "meas=MB" & goto:MBprepsize) 424 | if %var% geq %KB% (set "meas=KB" & goto:KBprepsize) 425 | goto:finprepsize 426 | ::%1 - variable name for number (in/out) 427 | ::%2 - variable name for measure (in/out) 428 | :prepsize2 429 | if not defined %~2 exit /b 430 | setlocal 431 | set "var=!%~1!" 432 | set "sign=" 433 | if "%var:~,1%" equ "-" (set "sign=-" & set "var=%var:~1%") 434 | set "meas=!%~2!" 435 | if "%meas%" equ "KB" goto:KBprepsize 436 | if "%meas%" equ "B" goto:finprepsize 437 | if "%meas%" equ "MB" goto:MBprepsize 438 | if "%meas%" equ "GB" goto:GBprepsize 439 | goto:finprepsize 440 | :GBprepsize 441 | call:division var %GB% 100 & goto:finprepsize 442 | :MBprepsize 443 | call:division var %MB% 100 & goto:finprepsize 444 | :KBprepsize 445 | call:division var %KB% 100 & goto:finprepsize 446 | :Bprepsize 447 | call:division var 1 100 448 | :finprepsize 449 | endlocal & set "%~1=%sign%%var%" & set "%~2=%meas%" 450 | exit /b 451 | 452 | ::%1 - number of 100% 453 | ::%2 - number, which is necessary to calculate the percentage 454 | ::%3 - variable name for save result 455 | :perccalc 456 | setlocal 457 | ::echo.%~0: %* 458 | set "change=%~2" 459 | set "sign=" 460 | if "%change:~,1%" equ "-" (set "sign=-" & set "change=%change:~1%") 461 | set /a "perc=%change%*100/%~1" 2>nul 462 | set /a "fract=%change%*100%%%~1*100/%~1" 2>nul 463 | set /a "perc=%perc%*100+%fract%" 464 | call:division perc 100 100 465 | endlocal & set "%~3=%sign%%perc%" 466 | exit /b 467 | 468 | ::%1 - file name 469 | ::%2 - error message 470 | :printfileerr 471 | setlocal 472 | set "fn=%~nx1 " 473 | set "errmsg=%~2" 474 | call:centerstring errmsg 45 475 | 1>&2 echo. %fn:~,30%^|%errmsg% 476 | endlocal 477 | exit /b 478 | 479 | ::%1 - variable containing file name 480 | ::%2 - file name in %1 481 | ::%3 - max length file name 482 | :cropfilename 483 | setlocal 484 | set "xfn=%~nx2" 485 | set "xfnext=%~x2" 486 | set "xfnlen=0" 487 | set "xfnextlen=0" 488 | call:strlen xfn xfnlen 489 | call:strlen xfnext xfnextlen 490 | set /a "xfnextlen=%3-%xfnextlen%-2" 491 | if %xfnlen% gtr %3 ( 492 | call set "xfn=%%xfn:~,%xfnextlen%%%..%xfnext%" 493 | ) else ( 494 | set "xfn=%xfn% " 495 | set "xfn=!xfn:~,%3!" 496 | ) 497 | endlocal & set "%~1=%xfn%" 498 | exit /b 499 | 500 | :centerstring StrVar Length 501 | if "%~1" equ "" exit /b 502 | if not defined %~1 exit /b 503 | setlocal 504 | set "xstringlen=0" 505 | set "xstr=!%~1!" 506 | call:strlen xstr xstringlen 507 | set "xstradd= " 508 | set /a "xstraddlen=(%~2-%xstringlen%)/2" 509 | set "xstradd=!xstradd:~,%xstraddlen%!" 510 | if %xstringlen% geq %~2 ( 511 | set "xstr=!xstr:~,%~2!" 512 | ) else ( 513 | set "xstr=!xstradd!%xstr%!xstradd!" 514 | set /a "xstraddlen=xstringlen+xstraddlen*2" 515 | if !xstraddlen! lss %~2 set "xstr= !xstr!" 516 | ) 517 | endlocal & set "%~1=%xstr%" 518 | exit /b 519 | 520 | ::original: http://forum.script-coding.com/viewtopic.php?pid=71000#p71000 521 | :strlen StrVar RtnVar -- be sure to check if the returned errorlevel is 0 522 | setlocal 523 | set /a "}=0" 524 | if "%~1" neq "" if defined %~1 ( 525 | for %%# in (4096 2048 1024 512 256 128 64 32 16) do ( 526 | if "!%~1:~%%#,1!" neq "" set "%~1=!%~1:~%%#!" & set /a "}+=%%#" 527 | ) 528 | set "%~1=!%~1!0FEDCBA9876543211" & set /a "}+=0x!%~1:~32,1!!%~1:~16,1!" 529 | ) 530 | ) 531 | endlocal & set /a "%~2=%}%" 532 | exit /b 533 | 534 | ::%1 - png | jpg | gif 535 | ::%2 - thread number 536 | ::%3 - input file 537 | ::%4 - output file 538 | :threadwork 539 | 1>nul 2>&1 md "%~dp4" 540 | if /i "%1" equ "png" call:pngfilework %2 %3 %4 & if %thread% gtr 1 >>"%countPNG%.%2" echo.1 541 | if /i "%1" equ "jpg" call:jpegfilework %2 %3 %4 & if %thread% gtr 1 >>"%countJPG%.%2" echo.1 542 | if /i "%1" equ "gif" call:giffilework %2 %3 %4 & if %thread% gtr 1 >>"%countGIF%.%2" echo.1 543 | if exist "%tmppath%\thrt%2.lck" >nul 2>&1 del /f /q "%tmppath%\thrt%2.lck" 544 | exit /b 545 | 546 | :waitflag 547 | if not exist "%~1" exit /b 548 | call:waitrandom 2000 549 | goto:waitflag 550 | 551 | :waitrandom2 552 | setlocal 553 | if not defined istimeout (call:waitrandom %~1 & exit /b) 554 | set "ww=%~1" 555 | if %~1 lss 1000 set "ww=1000" 556 | set /a "ww=%random%%%(%ww%/1000)" 557 | 1>nul 2>&1 timeout /t %ww% 558 | endlocal & exit /b 559 | :waitrandom 560 | setlocal 561 | set /a "ww=%random%%%%1" 562 | 1>nul 2>&1 ping -n 1 -w %ww% 127.255.255.255 563 | endlocal & exit /b 564 | 565 | ::If press key return errorlevel=1. If timeout - errorlevel=0 566 | :waitpresskey 567 | setlocal 568 | set "ww=%~1" 569 | if defined istimeout ( 570 | if %ww% lss 1000 set "ww=1000" 571 | timeout /t !ww:~,-3! 2>nul | 1>nul 2>&1 findstr /e "0" || (endlocal & exit /b 1) 572 | ) else call:waitrandom %ww% 573 | endlocal & exit /b 0 574 | 575 | :initsource 576 | set "isjpeg=" 577 | set "ispng=" 578 | set "isgif=" 579 | if /i "%~x1" equ ".png" set "ispng=1" 580 | if /i "%~x1" equ ".jpg" set "isjpeg=1" 581 | if /i "%~x1" equ ".jpeg" set "isjpeg=1" 582 | if /i "%~x1" equ ".jpe" set "isjpeg=1" 583 | if /i "%~x1" equ ".gif" set "isgif=1" 584 | exit /b 585 | 586 | :sethread 587 | set /a "thread=%~1+1-1" 588 | if "%~1" neq "" if "%~1" neq "0" set "thread=%~1" & exit /b 589 | if %thread% equ 0 set "thread=%NUMBER_OF_PROCESSORS%" 590 | exit /b 591 | 592 | :png 593 | call:clearscreen 594 | set "png=" 595 | title [PNG] %name% 596 | echo. ---------------------- 597 | echo. PNG optimization mode: 598 | echo. ---------------------- 599 | echo. 600 | echo. [1] Advanced 601 | echo. 602 | echo. [2] Xtreme 603 | echo. 604 | echo. [0] Skip 605 | echo. 606 | echo. ------------------------------------ 607 | set /p png="#Select mode and press Enter [0-2]: " 608 | echo. ------------------------------------ 609 | echo. 610 | if "%png%" neq "0" if "%png%" neq "1" if "%png%" neq "2" goto:png 611 | exit /b 612 | 613 | :jpeg 614 | call:clearscreen 615 | set "jpeg=" 616 | title [JPEG] %name% 617 | echo. ---------------------- 618 | echo. JPEG otimization mode: 619 | echo. ---------------------- 620 | echo. 621 | echo. [1] Baseline 622 | echo. 623 | echo. [2] Progressive 624 | echo. 625 | echo. [3] Default 626 | echo. 627 | echo. [0] Skip 628 | echo. 629 | echo. ------------------------------------ 630 | set /p jpeg="#Select mode and press Enter [0-3]: " 631 | echo. ------------------------------------ 632 | echo. 633 | if "%jpeg%" neq "0" if "%jpeg%" neq "1" if "%jpeg%" neq "2" if "%jpeg%" neq "3" goto:jpeg 634 | exit /b 635 | 636 | :gif 637 | call:clearscreen 638 | set "gif=" 639 | title [GIF] %name% 640 | echo. ---------------------- 641 | echo. GIF optimization mode: 642 | echo. ---------------------- 643 | echo. 644 | echo. [1] Default 645 | echo. 646 | echo. [0] Skip 647 | echo. 648 | echo. ------------------------------------ 649 | set /p gif="#Select mode and press Enter [0-1]: " 650 | echo. 651 | echo. 652 | if "%gif%" neq "0" if "%gif%" neq "1" goto:gif 653 | exit /b 654 | 655 | :setitle 656 | if "%jpeg%" equ "0" if "%png%" equ "0" if "%gif%" equ "0" (title %~1%name% & exit /b) 657 | if %thread% gtr 1 ( 658 | set "ImageNumPNG=0" & set "ImageNumJPG=0" & set "ImageNumGIF=0" 659 | for /l %%c in (1,1,%thread%) do ( 660 | for %%b in ("%countPNG%.%%c") do set /a "ImageNumPNG+=%%~zb/3" 2>nul 661 | for %%b in ("%countJPG%.%%c") do set /a "ImageNumJPG+=%%~zb/3" 2>nul 662 | for %%b in ("%countGIF%.%%c") do set /a "ImageNumGIF+=%%~zb/3" 2>nul 663 | ) 664 | ) 665 | setlocal 666 | if "%~1" equ "" (set "fintitle=%name% %version%") else (set "fintitle=%~1") 667 | if %png% equ 1 (set "pngtitle=Advanced") 668 | if %png% equ 2 (set "pngtitle=Xtreme") 669 | if %jpeg% equ 1 (set "jpegtitle=Baseline") 670 | if %jpeg% equ 2 (set "jpegtitle=Progressive") 671 | if %jpeg% equ 3 (set "jpegtitle=Default") 672 | if %gif% equ 1 (set "giftitle=Default") 673 | set "titlestr=" 674 | set "tmpn=0" 675 | if %png% gtr 0 ( 676 | set /a "perc=%ImageNumPNG%*100/%TotalNumPNG%" 677 | set "titlestr=PNG %pngtitle%: !perc!%%" 678 | ) 679 | if %jpeg% gtr 0 ( 680 | set /a "perc=%ImageNumJPG%*100/%TotalNumJPG%" 681 | if %png% gtr 0 set "titlestr=%titlestr% ^| " 682 | set "titlestr=!titlestr!JPG %jpegtitle%: !perc!%%" 683 | ) 684 | if %gif% gtr 0 ( 685 | set /a "perc=%ImageNumGIF%*100/%TotalNumGIF%" 686 | set /a "tmpn=%jpeg%+%png%" 687 | if !tmpn! gtr 0 (set "titlestr=%titlestr% ^| ") 688 | set "titlestr=!titlestr!GIF %giftitle%: !perc!%%" 689 | ) 690 | title [%titlestr%] %fintitle% 691 | endlocal & exit /b 692 | 693 | ::%1 - input file 694 | ::%2 - output file 695 | ::%3 - png | jpg | gif 696 | ::%4 - %thread% 697 | ::%5 - ImageNum(PNG|JPG|GIF) 698 | :filework 699 | call:createthread %3 %4 "%~f1" "%~f2" 700 | set /a "%5+=1" 701 | call:setitle 702 | exit /b 703 | 704 | ::%1 - thread number 705 | ::%2 - input file 706 | ::%3 - output file 707 | :pngfilework 708 | set "zc=" 709 | set "zm=" 710 | set "zs=" 711 | set "iter=10" 712 | set "psize=%~z2" 713 | set "errbackup=0" 714 | set "logfile2=%logfile%png.%1" 715 | set "pnglog=%tmppath%\png%1.log" 716 | set "filework=%tmppath%\%~n2-ic%1%~x2" 717 | if not exist "%~2" ( 718 | call:saverrorlog "%~f2" 3 %~1 PNG 719 | exit /b 1 720 | ) 721 | if %png% equ 2 ( 722 | >"%pnglog%" 2>nul truepng -y -i0 -zw7 -zc7 -zm5-9 -zs0,1,3 -f0,5 -fs:1 %xtreme% -force -out "%filework%" "%~2" 723 | if errorlevel 1 (call:saverrorlog "%~f2" 2 %~1 PNG & goto:pngfwe) 724 | for /f "tokens=2,4,6,8,10 delims=: " %%a in ('findstr /r /i /b /c:"zc:..zm:..zs:" "%pnglog%" 2^>nul') do ( 725 | set "zc=%%a" 726 | set "zm=%%b" 727 | set "zs=%%c" 728 | ) 729 | if !zs! gtr 1 ( 730 | set "zs=1" 731 | set "iter=15" 732 | ) 733 | 1>nul 2>&1 pngwolfzopfli --zopfli-iter=!iter! --zopfli-maxsplit=0 --zlib-window=15 --zlib-level=!zc! --zlib-memlevel=!zm! --zlib-strategy=!zs! --max-stagnate-time=0 --max-evaluations=1 --in="%filework%" --out="%filework%" 734 | if errorlevel 1 (call:saverrorlog "%~f2" 2 %~1 PNG & goto:pngfwe) 735 | ) 736 | if %png% equ 1 ( 737 | 1>nul 2>&1 truepng -y -i0 -zw7 -zc7 -zm8 -zs0,1,3 -f0,5 -fs:1 %advanced% -force -out "%filework%" "%~2" 738 | if errorlevel 1 (call:saverrorlog "%~f2" 2 %~1 PNG & goto:pngfwe) 739 | 1>nul 2>&1 deflopt -k "%filework%" 740 | if errorlevel 1 (call:saverrorlog "%~f2" 2 %~1 PNG & goto:pngfwe) 741 | 1>nul 2>&1 advdef -z2 "%filework%" 742 | if errorlevel 1 (call:saverrorlog "%~f2" 2 %~1 PNG & goto:pngfwe) 743 | ) 744 | 1>nul 2>&1 deflopt -k "%filework%" 745 | if errorlevel 1 (call:saverrorlog "%~f2" 2 %~1 PNG & goto:pngfwe) 746 | call:backup2 "%~f2" "%filework%" "%~f3" || set "errbackup=1" 747 | if %errbackup% neq 0 (call:saverrorlog "%~f2" 2 %~1 PNG & goto:pngfwe) 748 | if /i "%pngtags%" equ "true" (1>nul 2>&1 truepng -nz -md remove all "%~3" || (call:saverrorlog "%~f2" 2 %~1 PNG & goto:pngfwe)) 749 | call:savelog "%~f3" %psize% 750 | if %thread% equ 1 for %%a in ("%~f3") do (set /a "ImageSizePNG+=%%~za" & set /a "TotalSizePNG+=%psize%") 751 | :pngfwe 752 | 1>nul 2>&1 del /f /q "%filework%" "%pnglog%" 753 | exit /b 754 | 755 | ::%1 - thread number 756 | ::%2 - input file 757 | ::%3 - output file 758 | :jpegfilework 759 | set "ep=" 760 | set "jsize=%~z2" 761 | set "errbackup=0" 762 | set "logfile2=%logfile%jpg.%1" 763 | set "jpglog=%tmppath%\jpg%1.log" 764 | if /i "%~f2" equ "%~f3" ( 765 | set "filework=%tmppath%\%~n2-ic%1%~x2" 766 | ) else ( 767 | set "filework=%~f3" 768 | ) 769 | if not exist "%~2" ( 770 | call:saverrorlog "%~f2" 3 %~1 JPG 771 | exit /b 1 772 | ) 773 | if %jpeg% equ 1 ( 774 | jpegtran -verbose -revert -optimize -copy all -outfile "%filework%" "%~2" 1>"%jpglog%" 2>&1 775 | if errorlevel 1 (call:saverrorlog "%~f2" 2 %~1 JPG & goto:jpegfwe) 776 | for /f "tokens=4,10 delims=:,= " %%a in ('findstr /C:"Start Of Frame" "%jpglog%" 2^>nul') do (set "ep=%%a") 777 | if "!ep!" equ "0xc0" goto:jpegfwb 778 | if "!ep!" equ "0xc2" ( 779 | if /i "%~f2" equ "%~f3" (1>nul 2>&1 move /y "%filework%" "%~f3" || set "errbackup=1") 780 | goto:jpegfwf 781 | ) else ( 782 | call:saverrorlog "%~f2" 2 %~1 JPG & goto:jpegfwe 783 | ) 784 | ) 785 | if %jpeg% equ 2 ( 786 | jpegtran -verbose -copy all -outfile "%filework%" "%~2" 1>"%jpglog%" 2>&1 787 | if errorlevel 1 (call:saverrorlog "%~f2" 2 %~1 JPG & goto:jpegfwe) 788 | for /f "tokens=4,10 delims=:,= " %%a in ('findstr /C:"Start Of Frame" "%jpglog%" 2^>nul') do (set "ep=%%a") 789 | if "!ep!" equ "0xc2" goto:jpegfwb 790 | if "!ep!" equ "0xc0" ( 791 | if /i "%~f2" equ "%~f3" (1>nul 2>&1 move /y "%filework%" "%~f3" || set "errbackup=1") 792 | goto:jpegfwf 793 | ) else ( 794 | call:saverrorlog "%~f2" 2 %~1 JPG & goto:jpegfwe 795 | ) 796 | ) 797 | if %jpeg% equ 3 ( 798 | jpginfo "%~2" 1>"%jpglog%" 2>&1 799 | if errorlevel 1 (call:saverrorlog "%~f2" 2 %~1 JPG & goto:jpegfwe) 800 | for /f "usebackq tokens=5" %%a in ("%jpglog%") do set "ep=%%~a" 801 | if /i "!ep!" equ "Baseline" ( 802 | jpegtran -verbose -revert -optimize -copy all -outfile "%filework%" "%~2" 1>nul 2>&1 && goto:jpegfwb 803 | ) 804 | if /i "!ep!" equ "Progressive" ( 805 | jpegtran -verbose -copy all -outfile "%filework%" "%~2" 1>nul 2>&1 && goto:jpegfwb 806 | ) 807 | call:saverrorlog "%~f2" 2 %~1 JPG & goto:jpegfwe 808 | ) 809 | :jpegfwb 810 | if /i "%~f2" neq "%~f3" ( 811 | call:backup "%filework%" "%~f2" >nul || set "errbackup=1" 812 | ) else ( 813 | call:backup "%~f2" "%filework%" true >nul || set "errbackup=1" 814 | ) 815 | :jpegfwf 816 | 1>nul 2>&1 del /f /q "%jpglog%" 817 | if %errbackup% neq 0 (call:saverrorlog "%~f2" 3 %~1 JPG & goto:jpegfwe) 818 | if /i "%jpegtags%" equ "true" (1>nul 2>&1 jpegstripper -y "%~f3" || (call:saverrorlog "%~f2" 2 %~1 JPG & exit /b)) 819 | call:savelog "%~f3" %jsize% 820 | if %thread% equ 1 for %%a in ("%~f3") do (set /a "ImageSizeJPG+=%%~za" & set /a "TotalSizeJPG+=%jsize%") 821 | exit /b 822 | :jpegfwe 823 | if /i "%~f2" neq "%~f3" (1>nul 2>&1 del /f /q "%filework%") 824 | 1>nul 2>&1 del /f /q "%jpglog%" 825 | exit /b 1 826 | 827 | ::%1 - thread number 828 | ::%2 - input file 829 | ::%3 - output file 830 | :giffilework 831 | set "gsize=%~z2" 832 | set "errbackup=0" 833 | set "logfile2=%logfile%gif.%1" 834 | set "filework=" 835 | if /i "%~f2" equ "%~f3" ( 836 | set "filework1=%tmppath%\%~n2%1%-gifsicle1~x1" 837 | set "filework=!filework1! " 838 | ) else ( 839 | set "filework1=%~f3" 840 | ) 841 | set "filework2=%tmppath%\%~n2%1%-gifsicle2~x1" 842 | set "filework=%filework%%filework2%" 843 | if not exist "%~2" ( 844 | call:saverrorlog "%~f2" 3 %~1 GIF 845 | exit /b 1 846 | ) 847 | gifsicle --batch %giftags% --optimize=0 --output "%filework1%" "%~2" 1>nul 2>&1 848 | if errorlevel 1 (call:saverrorlog "%~f2" 2 %~1 GIF & goto:giffwe) 849 | gifsicle --batch %giftags% --optimize=3 --output "%filework2%" "%~2" 1>nul 2>&1 850 | if errorlevel 1 (call:saverrorlog "%~f2" 2 %~1 GIF & goto:giffwe) 851 | if /i "%~f2" neq "%~f3" ( 852 | call:backup "%filework1%" "%~f2" >nul || set "errbackup=1" 853 | call:backup "%filework1%" "%filework2%" true >nul || set "errbackup=1" 854 | ) else ( 855 | call:backup "%~f3" "%filework1%" true >nul || set "errbackup=1" 856 | call:backup "%~f3" "%filework2%" true >nul || set "errbackup=1" 857 | ) 858 | if %errbackup% neq 0 (call:saverrorlog "%~f2" 3 %~1 GIF & goto:giffwe) 859 | call:savelog "%~f3" %gsize% 860 | if %thread% equ 1 for %%a in ("%~f3") do (set /a "ImageSizeGIF+=%%~za" & set /a "TotalSizeGIF+=%jsize%") 861 | exit /b 862 | :giffwe 863 | if /i "%~f2" neq "%~f3" if exist "%filework1%" del /f /q "%filework1%" 864 | if exist "%filework2%" del /f /q "%filework2%" 865 | exit /b 1 866 | 867 | :backup 868 | if not exist "%~1" exit /b 2 869 | if not exist "%~2" exit /b 3 870 | if %~z2 equ 0 (if "%3" neq "" (1>nul 2>&1 del /f /q "%~2") & exit /b 4) 871 | if %~z1 leq %~z2 ( 872 | if "%3" neq "" (1>nul 2>&1 del /f /q "%~2") 873 | ) else ( 874 | 1>nul 2>&1 copy /b /y "%~2" "%~1" || exit /b 1 875 | if "%3" neq "" 1>nul 2>&1 del /f /q "%~2" 876 | ) 877 | exit /b 878 | 879 | :backup2 880 | if not exist "%~1" exit /b 2 881 | if not exist "%~2" exit /b 3 882 | set "cone=" 883 | if %~z2 equ 0 set "cone=yes" 884 | if %~z1 leq %~z2 set "cone=yes" 885 | if defined cone ( 886 | if "%~1" neq "%~3" (1>nul 2>&1 copy /b /y "%~1" "%~3" || exit /b 1) 887 | ) else ( 888 | 1>nul 2>&1 copy /b /y "%~2" "%~3" || exit /b 1 889 | ) 890 | exit /b 0 891 | 892 | ::%1 - optimize file path 893 | ::%2 - original file size 894 | ::%3 - thread number 895 | :savelog 896 | setlocal 897 | ::echo.%~0[in]: %1 %~2 %~z1 898 | set /a "change=%~z1-%~2" 899 | ::call:perccalc %~2 %change% perc 900 | set /a "change=%~z1-%~2" 901 | >>"%logfile2%" echo.%~1;%~2;%~z1;%change%;0.00;ok 902 | if %thread% equ 1 ( 903 | call:printfileinfo "%~1" %2 %~z1 %change% 0.00 904 | ) 905 | endlocal 906 | exit /b 907 | 908 | ::%1 - file name 909 | ::%2 - 1 - Images are already optimized 910 | :: 2 - Images are not supported 911 | :: 3 - Images are not found 912 | ::%3 - thread number 913 | ::%4 - JPG|PNG|GIF 914 | :saverrorlog 915 | if exist "%filework%" 1>nul 2>&1 del /f /q "%filework%" 916 | if "%~2" equ "" exit /b 917 | >>"%filelisterr%%~2%~3" echo. %~f1 918 | if %thread% equ 1 (call:printfileerr "%~f1" %~2) 919 | exit /b 920 | 921 | ::%1 - variable name for division (dividend) 922 | ::%2 - divider 923 | ::%3 - 10^(number of decimal places) - (100 - 2 decimal places, 1000 - 3 decimal places, 1 - no decimals places) 924 | ::Return: float value with %3 decimal places: %1=!%1!/%2 925 | :division 926 | setlocal 927 | 1>nul 2>&1 set /a "int=!%1!/%2" 928 | if %~3 equ 1 ( 929 | endlocal & set "%1=%int%" & exit /b 930 | exit /b 931 | ) 932 | 1>nul 2>&1 set /a "fractd=!%1!%%%2*%3/%2" 933 | if "%fractd:~,1%" equ "-" (set "fractd=%fractd:~1%") 934 | 1>nul 2>&1 set /a "fractd=%3+%fractd%" 935 | endlocal & set "%1=%int%.%fractd:~1%" 936 | exit /b 937 | 938 | ::%1 - variable name for division (dividend) 939 | ::%2 - divider 940 | ::%3 - 10^(number of decimal places) - (100 - 2 decimal places, 1000 - 3 decimal places, 1 - no decimals places) 941 | ::Return: integer value: %1=!%1!/%2*%3 942 | :division2 943 | ::echo.%~0[in]: %~1=!%~1! %~2 %~3 944 | setlocal 945 | 1>nul 2>&1 set /a "int=!%~1!/%~2" 946 | if %~3 equ 1 ( 947 | endlocal & set "%~1=%int%" & exit /b 948 | exit /b 949 | ) 950 | 1>nul 2>&1 set /a "fractd=!%~1!%%%~2*%~3/%~2" 951 | endlocal & set /a "%~1=%int%*%~3+(%fractd%)" 952 | ::echo.%~0[out]: !%~1! 953 | exit /b 954 | 955 | :end 956 | call:setvtime ftime 957 | if %jpeg% equ 0 if %png% equ 0 if %gif% equ 0 1>nul 2>&1 ping -n 1 -w 500 127.255.255.255 & goto:finmessage 958 | set /a "TotalNumPNG+=TotalNumErrPNG" 959 | set /a "TotalNumJPG+=TotalNumErrJPG" 960 | set /a "TotalNumGIF+=TotalNumErrGIF" 961 | for %%b in ("%filelisterr%2" "%filelisterr%3") do ( 962 | for /f "tokens=1" %%a in ('findstr /e /i /c:".png" "%%~b*" 2^>nul ^| find /i /c ".png" 2^>nul') do ( 963 | set /a "TotalNumErrPNG+=%%a" 964 | ) 965 | for /f "tokens=1" %%a in ('findstr /e /i /c:".jpg" "%%~b*" 2^>nul ^| find /i /c ".jpg" 2^>nul') do ( 966 | set /a "TotalNumErrJPG+=%%a" 967 | ) 968 | for /f "tokens=1" %%a in ('findstr /e /i /c:".jpe" "%%~b*" 2^>nul ^| find /i /c ".jpe" 2^>nul') do ( 969 | set /a "TotalNumErrJPG+=%%a" 970 | ) 971 | for /f "tokens=1" %%a in ('findstr /e /i /c:".jpeg" "%%~b*" 2^>nul ^| find /i /c ".jpeg" 2^>nul') do ( 972 | set /a "TotalNumErrJPG+=%%a" 973 | ) 974 | for /f "tokens=1" %%a in ('findstr /e /i /c:".gif" "%%~b*" 2^>nul ^| find /i /c ".gif" 2^>nul') do ( 975 | set /a "TotalNumErrGIF+=%%a" 976 | ) 977 | ) 978 | set /a "TotalNumErr=%TotalNumErrPNG%+%TotalNumErrJPG%+%TotalNumErrGIF%" 979 | if %TotalNumErr% gtr 0 ( 980 | echo. 981 | echo. Error 982 | set "isfirst=" 983 | for %%a in ("%filelisterr%2*") do if %%~za gtr 0 ( 984 | if not defined isfirst ( 985 | echo.%spacebar% 986 | echo. 987 | echo. Images are not supported: 988 | set "isfirst=1" 989 | ) 990 | type "%%~a" 991 | ) 992 | set "isfirst=" 993 | for %%a in ("%filelisterr%3*") do if %%~za gtr 0 ( 994 | if not defined isfirst ( 995 | echo.%spacebar% 996 | echo. 997 | echo. Images are not found: 998 | set "isfirst=1" 999 | ) 1000 | type "%%~a" 1001 | ) 1002 | for %%a in ("%filelisterr%") do if %%~za gtr 0 ( 1003 | echo.%spacebar% 1004 | echo. 1005 | echo. Images with characters: 1006 | type "%%~a" 1007 | ) 1008 | set "isfirst=" 1009 | echo.%spacebar% 1010 | ) 1011 | call:fincalc PNG 1012 | call:fincalc JPG 1013 | call:fincalc GIF 1014 | :finmessage 1015 | call:totalmsg PNG %png% 1016 | call:totalmsg JPG %jpeg% 1017 | call:totalmsg GIF %gif% 1018 | echo. 1019 | if defined outdir (echo. Outdir: %outdir%) else echo. Outdir: overwrite original images 1020 | echo. 1021 | echo. Started at - %stime% 1022 | echo. Finished at - %ftime% 1023 | echo.%spacebar% 1024 | if /i "%updatecheck%" equ "true" ( 1025 | call:waitflag "%iculck%" 1026 | 1>nul 2>&1 del /f /q "%iculck%" 1027 | if exist "%iculog%" ( 1028 | set "ver=" & set "url=" 1029 | call:readini "%iculog%" 1030 | if defined ver ( if "%version%" neq "!ver!" ( 1031 | echo. 1032 | echo. New version available %name% !ver! 1033 | echo. 1034 | echo. !url! 1035 | echo.%spacebar% 1036 | )))) 1037 | 1>nul 2>&1 del /f /q "%logfile%*" "%countJPG%" "%countPNG%*" "%filelist%*" "%filelisterr%*" "%iclock%" 1038 | if exist "%tmppath%" 1>nul 2>&1 rd /s /q "%tmppath%" 1039 | exit /b 1040 | 1041 | ::%1 - JPG|PNG|GIF 1042 | ::%2 - Total Size 1043 | ::%3 - Image Size 1044 | :stepcalc 1045 | set /a "TotalSize%~1+=%~2" 1046 | set /a "ImageSize%~1+=%~3" 1047 | ::echo.!TotalSize%~1! !ImageSize%~1! 1048 | if !ImageSize%~1! lss %BYTECONV% if !TotalSize%~1! lss %BYTECONV% exit /b 1049 | if !stepB%~1! gtr 1 ( 1050 | call:division2 TotalSize%~1 !stepB%~1! !step10%~1! 1051 | call:division2 ImageSize%~1 !stepB%~1! !step10%~1! 1052 | ) 1053 | set /a "STotalSize%~1+=!TotalSize%~1!" 1054 | set /a "SImageSize%~1+=!ImageSize%~1!" 1055 | set "TotalSize%~1=0" 1056 | set "ImageSize%~1=0" 1057 | ::echo.%~0: !STotalSize%~1! !SImageSize%~1! !step%~1! !step10%~1! !stepB%~1! 1058 | if !SImageSize%~1! lss %BYTECONV% if !STotalSize%~1! lss %BYTECONV% exit /b 1059 | set /a "step%~1=(!step%~1!+1)%%3" 1060 | if !step%~1! equ 0 ( 1061 | set "step10%~1=100" 1062 | set /a "stepB%~1*=%KB%" 1063 | call:division2 STotalSize%~1 %KB% 100 1064 | call:division2 SImageSize%~1 %KB% 100 1065 | ) else if !stepB%~1! neq 1 ( 1066 | set /a "step10%~1/=10" 1067 | set /a "STotalSize%~1/=10" 1068 | set /a "SImageSize%~1/=10" 1069 | ) 1070 | ::echo.%~0: !STotalSize%~1! !SImageSize%~1! !step%~1! !step10%~1! !stepB%~1! 1071 | exit /b 1072 | 1073 | ::%1 - JPG|PNG|GIF 1074 | :fincalc 1075 | if !TotalSize%~1! equ 0 if !STotalSize%~1! equ 0 exit /b 1076 | if !stepB%~1! gtr 1 ( 1077 | call:division2 TotalSize%~1 !stepB%~1! !step10%~1! 1078 | call:division2 ImageSize%~1 !stepB%~1! !step10%~1! 1079 | ) 1080 | set /a "STotalSize%~1+=!TotalSize%~1!" 1081 | set /a "SImageSize%~1+=!ImageSize%~1!" 1082 | set "TotalSize%~1=0" 1083 | set "ImageSize%~1=0" 1084 | set /a "change%~1=(!SImageSize%~1!-!STotalSize%~1!)" 2>nul 1085 | set "TS=!STotalSize%~1!" 1086 | set "change=!change%~1!" 1087 | set "sign=" 1088 | if %change% lss 0 (set "sign=-" & set "change=%change:~1%") 1089 | set "divider=" & set "dp=" & set "measure=" 1090 | ::echo.%~0: !STotalSize%~1! !SImageSize%~1! !change%~1! !step%~1! !step10%~1! !stepB%~1! step10="%step10%" 1091 | call:finprepsize !stepB%~1! !STotalSize%~1! !step10%~1! divider dp measure 1092 | if %divider% gtr 1 ( 1093 | call:division STotalSize%~1 %divider% %dp% 1094 | call:division SImageSize%~1 %divider% %dp% 1095 | ) 1096 | set "STotalSize%~1=!STotalSize%~1! %measure%" 1097 | set "SImageSize%~1=!SImageSize%~1! %measure%" 1098 | set "divider=" & set "dp=" & set "measure=" 1099 | call:finprepsize !stepB%~1! %change% !step10%~1! divider dp measure 1100 | if %divider% gtr 1 ( 1101 | call:division2 TS %divider% %dp% 1102 | call:division2 change %divider% %dp% 1103 | call:division change%~1 %divider% %dp% 1104 | ) 1105 | set "change%~1=!change%~1! %measure%" 1106 | call:perccalc %TS% %sign%%change% perc%~1 1107 | ::echo.%~0: %TS% %change% 1108 | ::echo.%~0: !STotalSize%~1! !SImageSize%~1! !change%~1! !step%~1! !step10%~1! !stepB%~1! %divider% %dp% 1109 | set "divider=" & set "dp=" & set "measure=" & set "change=" & set "TS=" 1110 | exit /b 1111 | 1112 | ::%1 - stepB (in) 1113 | ::%2 - size (in) 1114 | ::%3 - step10 (in) 1115 | ::%4 - variable name for divider (out) 1116 | ::%5 - variable name for decimal places (out) 1117 | ::%6 - variable name for measure (out) 1118 | :finprepsize 1119 | ::echo.%~0: %~1 %~2 %~3 1120 | setlocal 1121 | set "divider=" & set "dp=100" & set "meas=" & set "step10=%~3" 1122 | if %~1 equ %GB% ( 1123 | if %~2 geq %KB%%step10:~1% ( 1124 | set "divider=%KB%%step10:~1%" 1125 | set "meas=TB" 1126 | ) else ( 1127 | set "divider=%step10%" 1128 | set "dp=%step10%" 1129 | set "meas=GB" 1130 | ) 1131 | ) else if %~1 equ %MB% ( 1132 | if %~2 geq %MB%%step10:~1% ( 1133 | set "divider=%MB%%step10:~1%" 1134 | set "meas=TB" 1135 | ) else if %~2 geq %KB%%step10:~1% ( 1136 | set "divider=%KB%%step10:~1%" 1137 | set "meas=GB" 1138 | ) else ( 1139 | set "divider=%step10%" 1140 | set "dp=%step10%" 1141 | set "meas=MB" 1142 | ) 1143 | ) else if %~1 equ %KB% ( 1144 | if %~2 geq %MB%%step10:~1% ( 1145 | set "divider=%MB%%step10:~1%" 1146 | set "meas=GB" 1147 | ) else if %~2 geq %KB%%step10:~1% ( 1148 | set "divider=%KB%%step10:~1%" 1149 | set "meas=MB" 1150 | ) else ( 1151 | set "divider=%step10%" 1152 | set "dp=%step10%" 1153 | set "meas=KB" 1154 | ) 1155 | ) else if %~1 equ 1 ( 1156 | if %~2 geq %GB% ( 1157 | set "divider=%GB%" 1158 | set "meas=GB" 1159 | ) else if %~2 geq %MB% ( 1160 | set "divider=%MB%" 1161 | set "meas=MB" 1162 | ) else if %~2 geq %KB% ( 1163 | set "divider=%KB%" 1164 | set "meas=KB" 1165 | ) else ( 1166 | set "divider=1" 1167 | set "dp=1" 1168 | set "meas=B" 1169 | ) 1170 | ) 1171 | ::echo.%~0: %divider% %dp% %meas% 1172 | endlocal & set "%~4=%divider%" & set "%~5=%dp%" & set "%~6=%meas%" 1173 | exit /b 1174 | 1175 | ::%1 - JPG|PNG|GIF 1176 | :totalmsg 1177 | if %~2 equ 0 exit /b 1178 | set /a "opt=!TotalNum%~1!-!TotalNumErr%~1!" 1179 | if %opt% equ 0 exit /b 1180 | if not defined isfirst ( 1181 | echo. 1182 | echo. Total 1183 | echo.%spacebar% 1184 | set "isfirst=1" 1185 | ) 1186 | setlocal 1187 | set "F1=%~1 [%opt%/!TotalNum%~1!]: " 1188 | set "F5= !perc%~1!" 1189 | set "F2= !STotalSize%~1!" 1190 | set "F3= !SImageSize%~1!" 1191 | set "F4= !change%~1!" 1192 | echo. !F1:~,%TFN%!^|!F2:~-10!^|!F3:~-11!^|!F4:~-11!^|%F5:~-9%%% 1193 | echo.%spacebar% 1194 | endlocal & exit /b 1195 | 1196 | :readini 1197 | for /f "usebackq tokens=1,* delims== " %%a in ("%~1") do ( 1198 | set param=%%a 1199 | if "!param:~,1!" neq ";" if "!param:~,1!" neq "[" set "%%a=%%b" 1200 | ) 1201 | exit /b 1202 | 1203 | :helpmsg 1204 | title [Manual] %name% 1205 | 1>&2 ( 1206 | echo.%spacebar% 1207 | echo. %name% - lossless PNG, JPEG and GIF image optimization / compression 1208 | echo. 1209 | echo. %name% version %version% by Lorents ^& Res2001 ^(2010-2016^) 1210 | echo. https://github.com/lorents17/iCatalyst 1211 | echo.%spacebar% 1212 | echo. 1213 | echo. Usage: call iCatalyst.bat [options] [add directories \ add files] 1214 | echo. 1215 | echo. Options: 1216 | echo. 1217 | echo. /png:# PNG optimization mode ^(Non-Interlaced^): 1218 | echo. 1 - Compression level - Advanced 1219 | echo. 2 - Compression level - Xtreme 1220 | echo. 0 - Skip ^(default^) 1221 | echo. 1222 | echo. /jpg:# JPEG optimization mode: 1223 | echo. 1 - Encoding Process - Baseline 1224 | echo. 2 - Encoding Process - Progressive 1225 | echo. 3 - use settings of original image 1226 | echo. 0 - Skip ^(default^) 1227 | echo. 1228 | echo. /gif:# GIF optimization mode: 1229 | echo. 1 - use settings of original image 1230 | echo. 0 - Skip ^(default^) 1231 | echo. 1232 | echo. "/outdir:#" image saving options: 1233 | echo. true - open dialog box for saving images ^(default^) 1234 | echo. false - replace original image with optimized 1235 | echo. "full path to directory" - specify directory to save images to. 1236 | echo. for example: "/outdir:C:\temp". If the destination directory 1237 | echo. does not exist, it will be created automatically. 1238 | echo. 1239 | echo. Add directories \ Add files: 1240 | echo. - Specify full image paths and / or paths to directories containing images. 1241 | echo. For example: "C:\Images" "C:\logo.png" 1242 | echo. - Full image paths should not contain any special characters such as 1243 | echo. "&", "%%", "(", ")" etc. 1244 | echo. - Images in sub-directories are optimized recursively. 1245 | echo. 1246 | echo. Examples: 1247 | echo. call iCatalyst.bat /gif:1 "/outdir:C:\photos" "C:\images" 1248 | echo. call iCatalyst.bat /png:2 /jpg:2 "/outdir:true" "C:\images" 1249 | echo.%spacebar% 1250 | ) 1251 | if exist "%tmppath%" 1>nul 2>&1 rd /s /q "%tmppath%" 1252 | call:dopause 1253 | if defined oldtitle title %oldtitle% 1254 | exit /b 1255 | 1256 | :errormsg 1257 | title [Error] %name% 1258 | if exist "%tmppath%" 1>nul 2>&1 rd /s /q "%tmppath%" 1259 | if "%~1" neq "" 1>&2 ( 1260 | echo.%spacebar% 1261 | for %%a in (%*) do echo. %%~a 1262 | echo.%spacebar% 1263 | ) 1264 | call:dopause 1265 | if defined oldtitle title %oldtitle% 1266 | exit /b 1267 | 1268 | :dopause 1269 | setlocal 1270 | set "x=%~f0" 1271 | 1>nul echo.%CMDCMDLINE% 2>nul && (echo.%CMDCMDLINE% 2>nul | 1>nul 2>&1 findstr /ilc:"%x%" && 1>nul 2>&1 pause) 1272 | set "x=" 1273 | endlocal & exit /b 1274 | 1275 | :clearscreen 1276 | setlocal 1277 | set "x=%~f0" 1278 | 1>nul echo.%CMDCMDLINE% 2>nul && (echo.%CMDCMDLINE% 2>nul | 1>nul 2>&1 findstr /ilc:"%x%" && cls) 1279 | set "x=" 1280 | endlocal & exit /b 1281 | 1282 | :gettitle 1283 | setlocal 1284 | if not defined consolepid exit /b 1 1285 | set "ctitle=" 1286 | set "titfile=%TEMP%\%RANDOM%%RANDOM%.tasklist.txt" 1287 | 1>"%titfile%" 2>nul tasklist /v /nh /fo csv /fi "pid eq %consolepid%" 1288 | ::For WinXP Rus 1289 | if errorlevel 1 1>"%titfile%" 2>nul tasklist /v /nh /fo csv /fi "ID à®æ¥áá  eq %consolepid%" 1290 | for /f "usebackq tokens=8,* delims=," %%a in ("%titfile%") do ( 1291 | for /f "tokens=1 delims=-" %%c in ("%%~b") do set "ctitle=%%~c" 1292 | ) 1293 | 1>nul 2>&1 del /f/q "%titfile%" 1294 | if not defined ctitle (endlocal & exit /b 2) 1295 | endlocal & set "%~1=%ctitle:~,-1%" 1296 | exit /b 0 1297 | 1298 | :getpid 1299 | setlocal 1300 | set "cpid=" 1301 | set "pidfile=%TEMP%\%RANDOM%%RANDOM%.ic.wmic.process.txt" 1302 | wmic process get CommandLine,Name,ParentProcessID,ProcessID /format:csv >"%pidfile%" 1303 | for /f "tokens=7,8 delims=," %%a in ('type "%pidfile%" ^| findstr "CommandLine,Name,ParentProcessID,ProcessID" ') do set "cpid=%%a" 1304 | 1>nul 2>&1 del /f/q "%pidfile%" 1305 | if not defined cpid endlocal & exit /b 1 1306 | endlocal & set "%~1=%cpid%" 1307 | exit /b 0 1308 | --------------------------------------------------------------------------------