From 736c32cd4e8347507a00b00ab053c70e503cdd37 Mon Sep 17 00:00:00 2001 From: Chase <44284917+TotallyNotChase@users.noreply.github.com> Date: Sun, 22 Mar 2020 12:40:33 +0530 Subject: [PATCH] Update to 0.1.4 --- CHANGELOG.md | 7 ++++++ README.md | 4 ++-- glitch_this/commandline.py | 5 +++-- glitch_this/glitch_this.py | 44 +++++++++++++++++++++++++++----------- setup.py | 2 +- test_script.py | 24 ++++++++++----------- 6 files changed, 55 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94b0d67..9a65adc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -112,3 +112,10 @@ ## Version 0.1.3.1 - Patch * Fix help text formatting in `commandline.py` + +## Version 0.1.4 - **MAJOR** +* Add support for floats as Increment/Decrement (`glitch_change`) + + You can now use a value between +-0.0 and +-10.0 (inclusive) + +* Glitching intensity can now be in range 0.1 to 10.0 (inclusive) diff --git a/README.md b/README.md index 05cc8ca..6b57b80 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

A commandline tool + `python` library to glitchify images and **even make GIFs** out of them! -Featuring *Many different levels of glitching intensity*! The algorithm used to create glitched images is a slightly modifed version of the popular [ImageGlitcher](https://www.airtightinteractive.com/demos/js/imageglitcher/) tool's algorithm, so you can expect the glitched images to look really cool! +Featuring *100 gradually different levels of glitching intensity*! The algorithm used to create glitched images is a slightly modifed version of the popular [ImageGlitcher](https://www.airtightinteractive.com/demos/js/imageglitcher/) tool's algorithm, so you can expect the glitched images to look really cool! **NOW WITH GIF TO GLITCHED GIF SUPPORT! Check out the [docs](https://github.com/TotallyNotChase/glitch-this/wiki/Home)!** @@ -32,7 +32,7 @@ Checkout a web demo right [here](https://github.com/pahefu/web-glitch-this), cou * [#4 product of the day in producthunt](https://www.producthunt.com/posts/glitch-this) ## FEATURES! -* Choose any **glitching intensity** between 1.0 and 10.0, yes those are floats! +* Choose any **glitching intensity** between 0.1 and 10.0, yes those are floats! *Each level is gradually different*! diff --git a/glitch_this/commandline.py b/glitch_this/commandline.py index ea59d8b..a6e53af 100644 --- a/glitch_this/commandline.py +++ b/glitch_this/commandline.py @@ -17,6 +17,7 @@ def islatest(version): data = json.loads(contents) latest_version = data['info']['version'] + print('Current version: {} | Latest version: {}'.format(version, latest_version)) return version == latest_version def get_help(glitch_min, glitch_max): @@ -43,7 +44,7 @@ def get_help(glitch_min, glitch_max): return help_text def main(): - glitch_min, glitch_max = 1.0, 10.0 + glitch_min, glitch_max = 0.1, 10.0 help_text = get_help(glitch_min, glitch_max) # Add commandline arguments parser argparser = argparse.ArgumentParser(description= @@ -66,7 +67,7 @@ def main(): help=help_text['frames']) argparser.add_argument('-st', '--step', dest='step', metavar='Step', type=int, default=1, help=help_text['step']) - argparser.add_argument('-i', '--increment', dest='increment', metavar='Increment', type=int, default=0, + argparser.add_argument('-i', '--increment', dest='increment', metavar='Increment', type=float, default=0.0, help=help_text['increment']) argparser.add_argument('-cy', '--cycle', dest='cycle', action='store_true', help=help_text['cycle']) diff --git a/glitch_this/glitch_this.py b/glitch_this/glitch_this.py index 7adbd8f..7cff63b 100644 --- a/glitch_this/glitch_this.py +++ b/glitch_this/glitch_this.py @@ -1,12 +1,13 @@ import os, shutil import numpy as np from random import randint +from decimal import getcontext, Decimal from PIL import Image, ImageSequence class ImageGlitcher: # Handles Image/GIF Glitching Operations - __version__ = '0.1.3.1' + __version__ = '0.1.4' def __init__(self): # Setting up global variables needed for glitching @@ -24,7 +25,7 @@ def __init__(self): # Setting glitch_amount max and min self.glitch_max = 10.0 - self.glitch_min = 1.0 + self.glitch_min = 0.1 def __isgif(self, img): # Returns true if input image is a GIF and/or animated @@ -100,7 +101,7 @@ def __fetch_image(self, src_img, gif_allowed): raise Exception('Wrong format') return img - def glitch_image(self, src_img, glitch_amount, glitch_change=0, cycle=False, color_offset=False, scan_lines=False, gif=False, frames=23, step=1): + def glitch_image(self, src_img, glitch_amount, glitch_change=0.0, cycle=False, color_offset=False, scan_lines=False, gif=False, frames=23, step=1): """ Sets up values needed for glitching the image Returns created Image object if gif=False @@ -108,7 +109,7 @@ def glitch_image(self, src_img, glitch_amount, glitch_change=0, cycle=False, col PARAMETERS:- src_img: Either the path to input Image or an Image object itself - glitch_amount: Level of glitch intensity, [glitch_min, glitch_max] (inclusive) + glitch_amount: Level of glitch intensity, [0.1, 10.0] (inclusive) glitch_change: Increment/Decrement in glitch_amount after every glitch cycle: Whether or not to cycle glitch_amount back to glitch_min or glitch_max @@ -126,8 +127,10 @@ def glitch_image(self, src_img, glitch_amount, glitch_change=0, cycle=False, col raise ValueError('glitch_amount parameter must be a positive number ' 'in range {} to {}, inclusive'.format(self.glitch_min, self.glitch_max)) - if not isinstance(glitch_change, int): - raise ValueError('glitch_change parameter must be an integer') + if not ((isinstance(glitch_change, float) + or isinstance(glitch_change, int)) + and -self.glitch_max <= glitch_change <= self.glitch_max): + raise ValueError('glitch_change parameter must be a number between 0.0 and 10.0 or -0.0 and -10.0') if not isinstance(cycle, bool): raise ValueError('cycle param must be a boolean') if not isinstance(color_offset, bool): @@ -172,6 +175,10 @@ def glitch_image(self, src_img, glitch_amount, glitch_change=0, cycle=False, col shutil.rmtree(self.gif_dirpath) os.mkdir(self.gif_dirpath) + # Set up decimal precision for glitch_change + original_prec = getcontext().prec + getcontext().prec = 4 + glitched_imgs = [] for i in range(frames): """ @@ -192,11 +199,13 @@ def glitch_image(self, src_img, glitch_amount, glitch_change=0, cycle=False, col # Change glitch_amount by given value glitch_amount = self.__change_glitch(glitch_amount, glitch_change, cycle) + # Set decimal precision back to original value + getcontext().prec = original_prec # Cleanup shutil.rmtree(self.gif_dirpath) return glitched_imgs - def glitch_gif(self, src_gif, glitch_amount, glitch_change=0, cycle=False, color_offset=False, scan_lines=False, step=1): + def glitch_gif(self, src_gif, glitch_amount, glitch_change=0.0, cycle=False, color_offset=False, scan_lines=False, step=1): """ Glitch each frame of input GIF Returns the following: @@ -209,7 +218,7 @@ def glitch_gif(self, src_gif, glitch_amount, glitch_change=0, cycle=False, color with many frames PARAMETERS:- src_img: Either the path to input Image or an Image object itself - glitch_amount: Level of glitch intensity, [1, 10] (inclusive) + glitch_amount: Level of glitch intensity, [0.1, 10.0] (inclusive) glitch_change: Increment/Decrement in glitch_amount after every glitch cycle: Whether or not to cycle glitch_amount back to glitch_min or glitch_max @@ -225,8 +234,10 @@ def glitch_gif(self, src_gif, glitch_amount, glitch_change=0, cycle=False, color raise ValueError('glitch_amount parameter must be a positive number '\ 'in range {} to {}, inclusive'.format(self.glitch_min, self.glitch_max)) - if not isinstance(glitch_change, int): - raise ValueError('glitch_change parameter must be an integer') + if not ((isinstance(glitch_change, float) + or isinstance(glitch_change, int)) + and -self.glitch_max <= glitch_change <= self.glitch_max): + raise ValueError('glitch_change parameter must be a number between 0.0 and 10.0 or -0.0 and -10.0') if not isinstance(cycle, bool): raise ValueError('cycle param must be a boolean') if not isinstance(color_offset, bool): @@ -254,6 +265,10 @@ def glitch_gif(self, src_gif, glitch_amount, glitch_change=0, cycle=False, color shutil.rmtree(self.gif_dirpath) os.mkdir(self.gif_dirpath) + # Set up decimal precision for glitch_change + original_prec = getcontext().prec + getcontext().prec = 4 + i = 0 duration = 0 glitched_imgs = [] @@ -280,22 +295,25 @@ def glitch_gif(self, src_gif, glitch_amount, glitch_change=0, cycle=False, color # Change glitch_amount by given value glitch_amount = self.__change_glitch(glitch_amount, glitch_change, cycle) i += 1 + + # Set decimal precision back to original value + getcontext().prec = original_prec # Cleanup shutil.rmtree(self.gif_dirpath) return glitched_imgs, duration / i, i def __change_glitch(self, glitch_amount, glitch_change, cycle): # A function to change glitch_amount by given increment/decrement - glitch_amount += glitch_change + glitch_amount = float(Decimal(glitch_amount) + Decimal(glitch_change)) # glitch_amount must be between glith_min and glitch_max if glitch_amount < self.glitch_min: # If it's less, it will be cycled back to max when cycle=True # Otherwise, it'll stay at the least possible value -> glitch_min - glitch_amount = self.glitch_max + glitch_amount if cycle else self.glitch_min + glitch_amount = float(Decimal(self.glitch_max) + Decimal(glitch_amount)) if cycle else self.glitch_min if glitch_amount > self.glitch_max: # If it's more, it will be cycled back to min when cycle=True # Otherwise, it'll stay at the max possible value -> glitch_max - glitch_amount = glitch_amount % self.glitch_max if cycle else self.glitch_max + glitch_amount = float(Decimal(glitch_amount) % Decimal(self.glitch_max)) if cycle else self.glitch_max return glitch_amount def __get_glitched_img(self, glitch_amount, color_offset, scan_lines): diff --git a/setup.py b/setup.py index ab2b8bd..448261d 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='glitch_this', - version='0.1.3.1', + version='0.1.4', author='TotallyNotChase', author_email='44284917+TotallyNotChase@users.noreply.github.com', description='A package to glitch images and GIFs, with highly customizable options!', diff --git a/test_script.py b/test_script.py index 1db9d18..741ef0b 100644 --- a/test_script.py +++ b/test_script.py @@ -17,16 +17,14 @@ # Float numbers from 1 to 10, upto a single decimal precision from decimal import getcontext, Decimal # Setting floating point precision to 1 (after decimal point) + getcontext().prec = 2 amount_list = [] -start = Decimal(1.0) -for i in range(91): +start = Decimal(0.1) +for i in range(100): amount_list.append(float(start)) start += Decimal(0.1) -def get_random_glitch_amount(): - return choice(amount_list) - def test_loop(): # A method to stress test count = 0 @@ -35,7 +33,7 @@ def test_loop(): with open('Collections/imglog.txt', 'w') as logtxt: while(1): t0 = time() - level = get_random_glitch_amount() + level = choice(amount_list) """ Example of getting a glitched image and saving it, with all default params @@ -154,7 +152,7 @@ def test_image_to_gif(): # Now try with increasing the glitch_amount by 1 every time, with cycle set to True # glitch_amount will reach glitch_max after (glitch_max - glitch_amount)/glitch_change glitches # in this case that's 8 - # It'll cycle back to 1 after that and keep incrementing by glitch_change again + # It'll cycle back to glitch_min after that and keep incrementing by glitch_change again glitch_imgs = glitcher.glitch_image('test.{}'.format(fmt), 2, glitch_change=1, cycle=True, gif=True) glitch_imgs[0].save('Collections/glitched_test_increment_cycle.gif', format='GIF', @@ -166,7 +164,7 @@ def test_image_to_gif(): # Now try with increasing the glitch_amount by -1 every time, with cycle set to True # glitch_amount will reach glitch_min after (glitch_min - glitch_amount)/glitch_change glitches # in this case that's 1 - # It'll cycle back to 10 after that and keep incrementing (actually decrementing, in this case) + # It'll cycle back to glitch_max after that and keep incrementing (actually decrementing, in this case) # by glitch_change again glitch_imgs = glitcher.glitch_image('test.{}'.format(fmt), 2, glitch_change=-1, cycle=True, gif=True) glitch_imgs[0].save('Collections/glitched_test_decrement_cycle.gif', @@ -212,9 +210,9 @@ def test_gif_to_gif(): Example of getting a glitched GIF (from another GIF) and saving it - **`glitch_gif` also returns the duration (of each frame) + `glitch_gif` also returns the duration (of each frame) in centiseconds and the number of frames in the given GIF, you may - use these when saving your GIF too!** + use these when saving your GIF too! We use glitch_level = 2 in this example We also are making infinitely looping GIFs @@ -267,7 +265,7 @@ def test_gif_to_gif(): # Now try with increasing the glitch_amount by 1 every time, with cycle set to True # glitch_amount will reach glitch_max after (glitch_max - glitch_amount)/glitch_change glitches # in this case that's 8 - # It'll cycle back to 1 after that and keep incrementing by glitch_change again + # It'll cycle back to glitch_min after that and keep incrementing by glitch_change again glitch_imgs, src_duration, src_frames = glitcher.glitch_gif('test.gif', 2, glitch_change=1, cycle=True) glitch_imgs[0].save('Collections/glitched_gif_increment_cycle.gif', format='GIF', @@ -279,7 +277,7 @@ def test_gif_to_gif(): # Now try with increasing the glitch_amount by -1 every time, with cycle set to True # glitch_amount will reach glitch_min after (glitch_min - glitch_amount)/glitch_change glitches # in this case that's 1 - # It'll cycle back to 10 after that and keep incrementing (actually decrementing, in this case) + # It'll cycle back to glitch_max after that and keep incrementing (actually decrementing, in this case) # by glitch_change again glitch_imgs, src_duration, src_frames = glitcher.glitch_gif('test.gif', 2, glitch_change=-1, cycle=True) glitch_imgs[0].save('Collections/glitched_gif_decrement_cycle.gif', @@ -319,7 +317,7 @@ def test_gif_to_gif(): save_all=True, duration=DURATION, loop=LOOP) - + if __name__=='__main__': # Create the ImageGlitcher object glitcher = ImageGlitcher()