diff --git a/README.md b/README.md index a9b6290..d169378 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,38 @@ Convert your animated png files to animated webp files. ## External dependencies: +- cmake - libpng - zlib +- jsoncpp - pip (a python package used during installation) - The `cwebp` program must be in your path - The `webpmux` program must be in your path +## Prepare + +###macOS + +Use [Homebrew](https://brew.sh/) to install all the dependencies. Use `easy_install` to install pip + +```bash +brew install webp +brew install cmake +brew install jsoncpp +sudo easy_install pip +``` + +###Linux + +```bash +sudo apt-get install libwebp-dev +sudo apt-get install cmake +sudo apt-get install libpng-dev +sudo apt-get install zlib1g-dev +sudo apt-get install libjsoncpp-dev +sudo apt-get install python-pip +``` + ## Compiling and installation: In `apng2webp_dependencies/` execute: @@ -32,7 +58,16 @@ sudo python ./setup.py install ## Running: +The default loop is `0`(infinity) and bgcolor is `255,255,255,255`. + +You can also specify a temp dir to save the webp fram and optimized original apng. + ```bash apng2webp './input.png' './output.webp' +apng2webp './input.png' [-loop LOOP_COUNT] [-bgcolor BACKGROUND_COLOR] [-tmpdir TEMP_WEBP_DIR] './output.webp' ``` +## Thanks + +[APNG Disassembler](http://apngdis.sourceforge.net/) +[APNG Optimizer](https://sourceforge.net/projects/apng/files/APNG_Optimizer/) \ No newline at end of file diff --git a/apng2webp/apng2webp b/apng2webp/apng2webp index 41d0998..b38c7e3 100755 --- a/apng2webp/apng2webp +++ b/apng2webp/apng2webp @@ -11,58 +11,97 @@ import shutil from sh import apng2webp_apngopt, apngdisraw, cwebp, webpmux -def apng2webp(input_file, output_file, tmpdir): - +def apng2webp(input_file, output_file, tmpdir, loop, bgcolor): + de_optimised_file = path.join(tmpdir, "de-optimised.png") animation_json_file = path.join(tmpdir, "animation_metadata.json") - + # apng2webp_apngopt does only optimization which can be applied to webp. # apng2webp_apngopt does not return a error code if things go wrong at time of writing. (like can't write/read file) apng2webp_apngopt(input_file, de_optimised_file ) - + apngdisraw( de_optimised_file, 'animation' ) - + with open(animation_json_file, 'r') as f: animation = json.load(f) - + webpmux_args = [] for frame in animation['frames']: png_frame_file = path.join(tmpdir, frame['src']) webp_frame_file = path.join(tmpdir, frame['src']+".webp") - + cwebp('-lossless', '-q', '100', png_frame_file, '-o', webp_frame_file) - + delay = int(round(float(frame['delay_num']) / float(frame['delay_den']) * 1000)) - + if delay == 0: # The specs say zero is allowed, but should be treated as 10 ms. delay = 10; - + if frame['blend_op'] == 0: blend_mode = '-b' elif frame['blend_op'] == 1: blend_mode = '+b' else: raise ValueError("Webp can't handle this blend operation") - + webpmux_args.append('-frame') webpmux_args.append(webp_frame_file) webpmux_args.append('+' + str(delay) + '+' + str(frame['x']) + '+' + str(frame['y']) + '+' + str(frame['dispose_op']) + blend_mode ) + webpmux_args = webpmux_args + ['-loop', loop] + webpmux_args = webpmux_args + ['-bgcolor', bgcolor] webpmux_args = webpmux_args + ['-o', output_file] webpmux(*webpmux_args) - + def main(): - if(len(sys.argv) != 3): - print("Usage: "+sys.argv[0]+" input.png output.webp") + argc = len(sys.argv) + if (argc < 3): + print("Usage: apng2webp input.png [-loop LOOP_COUNT] [-bgcolor BACKGROUND_COLOR] [-tmpdir TEMP_WEBP_DIR] output.webp") sys.exit(errno.EINVAL) else: input_file = sys.argv[1] - output_file = sys.argv[2] - tmpdir = mkdtemp(prefix='apng2webp_') - try: - apng2webp(input_file, output_file, tmpdir) - finally: - shutil.rmtree(tmpdir) + output_file = sys.argv[argc-1] + loop = '0' + bgcolor = '255,255,255,255' + tmpdir = None + if (argc == 3): + tmpdir = mkdtemp(prefix='apng2webp_') + try: + apng2webp(input_file, output_file, tmpdir, loop, bgcolor) + print('finished') + finally: + shutil.rmtree(tmpdir) + elif (argc == 5 or argc == 7 or argc == 9): + argc_list = [2,4,6] + for argc_index in argc_list: + if (argc < argc_index+2): + break + op = sys.argv[argc_index] + if (op == '-loop'): + loop = sys.argv[argc_index+1] + elif (op == '-bgcolor'): + bgcolor = sys.argv[argc_index+1] + elif (op == '-tmpdir'): + tmpdir = sys.argv[argc_index+1] + + if (tmpdir): + if not os.path.exists(tmpdir): + os.makedirs(tmpdir) + try: + apng2webp(input_file, output_file, tmpdir, loop, bgcolor) + print('finished') + finally: + print('Outputed temp webp to '+tmpdir) + else: + tmpdir = mkdtemp(prefix='apng2webp_') + try: + apng2webp(input_file, output_file, tmpdir, loop, bgcolor) + print('finished') + finally: + shutil.rmtree(tmpdir) + else: + print("Usage: apng2webp input.png [-loop LOOP_COUNT] [-bgcolor BACKGROUND_COLOR] [-tmpdir TEMP_WEBP_DIR] output.webp") + sys.exit(errno.EINVAL) + if __name__ == "__main__": main(); -