Beispiel #1
0
def _glitch_gif(img_in: BytesIO, glitch_amount: float, glitch_change: float,
                scan_lines: bool) -> BytesIO:
    imgfile = BytesIO()
    glitcher = ImageGlitcher()
    img_in = Image.open(img_in)
    img_out, dur, frame_count = glitcher.glitch_gif(
        img_in,
        glitch_amount,
        color_offset=True,
        glitch_change=glitch_change,
        scan_lines=scan_lines)
    img_out[0].save(imgfile,
                    format="gif",
                    save_all=True,
                    append_images=img_out[1:],
                    duration=dur,
                    loop=0,
                    disposal=2,
                    optimize=False)
    imgfile.name = "dank.gif"
    return imgfile
Beispiel #2
0
def main():
    glitch_min, glitch_max = 1, 10
    help_text = get_help(glitch_min, glitch_max)
    # Add commandline arguments parser
    argparser = argparse.ArgumentParser(description='Glitchify images to static images and GIFs!')
    argparser.add_argument('src_img_path', metavar='Image_Path', type=str,
                           help=help_text['path'])
    argparser.add_argument('glitch_level', metavar='Glitch_Level', type=int,
                           help=help_text['level'])
    argparser.add_argument('-c', '--color', dest='color', action='store_true',
                           help=help_text['color'])
    argparser.add_argument('-s', '--scan', dest='scan_lines', action='store_true',
                           help=help_text['scan'])
    argparser.add_argument('-g', '--gif', dest='gif', action='store_true',
                           help=help_text['gif'])
    argparser.add_argument('-fr', '--frames', dest='frames', metavar='Frames', type=int, default=23,
                           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,
                           help=help_text['increment'])
    argparser.add_argument('-cy', '--cycle', dest='cycle', action='store_true',
                           help=help_text['cycle'])
    argparser.add_argument('-d', '--duration', dest='duration', metavar='Duration', type=int, default=200,
                           help=help_text['duration'])
    argparser.add_argument('-rd', '--relative_duration', dest='rel_duration', metavar='Relative_Duration', type=float,
                           help=help_text['relative_duration'])
    argparser.add_argument('-l', '--loop', dest='loop', metavar='Loop_Count', type=int, default=0,
                           help=help_text['loop'])
    argparser.add_argument('-ig', '--inputgif', dest='input_gif', action='store_true',
                           help=help_text['inputgif'])
    argparser.add_argument('-f', '--force', dest='force', action='store_true',
                           help=help_text['force'])
    argparser.add_argument('-o', '--outfile', dest='outfile', metavar='Outfile_path', type=str,
                           help=help_text['out'])
    args = argparser.parse_args()

    # Sanity check inputs
    if not args.duration > 0:
        raise ValueError('Duration must be greater than 0')
    if not args.loop >= 0:
        raise ValueError('Loop must be greater than or equal to 0')
    if not args.frames > 0:
        raise ValueError('Frames must be greater than 0')
    if not os.path.isfile(args.src_img_path):
        raise FileNotFoundError('No image found at given path')

    # Set up full_path, for output saving location
    out_path, out_file = os.path.split(Path(args.src_img_path))
    out_filename, out_fileex = out_file.rsplit('.', 1)
    out_filename = 'glitched_' + out_filename
    # Output file extension should be '.gif' if output file is going to be a gif
    out_fileex = 'gif' if args.gif else out_fileex
    if args.outfile:
        # If output file path is already given
        # Overwrite the previous values
        out_path, out_file = os.path.split(Path(args.outfile))
        if out_path != '' and not os.path.exists(out_path):
            raise Exception('Given outfile path, ' + out_path + ', does not exist')
        # The extension in user provided outfile path is ignored
        out_filename = out_file.rsplit('.', 1)[0]
    # Now create the full path
    full_path = os.path.join(out_path, '{}.{}'.format(out_filename, out_fileex))
    if os.path.exists(full_path) and not args.force:
        raise Exception(full_path + ' already exists\nCannot overwrite '
                        'existing file unless -f or --force is included\nProgram Aborted')

    # Actual work begins here
    glitcher = ImageGlitcher()
    t0 = time()
    if not args.input_gif:
        # Get glitched image or GIF (from image)
        glitch_img = glitcher.glitch_image(args.src_img_path, args.glitch_level,
                                           glitch_change=args.increment,
                                           cycle=args.cycle,
                                           scan_lines=args.scan_lines,
                                           color_offset=args.color,
                                           gif=args.gif,
                                           frames=args.frames,
                                           step=args.step)
    else:
        # Get glitched image or GIF (from GIF)
        glitch_img, src_duration, args.frames = glitcher.glitch_gif(args.src_img_path, args.glitch_level,
                                                                    glitch_change=args.increment,
                                                                    cycle=args.cycle,
                                                                    scan_lines=args.scan_lines,
                                                                    color_offset=args.color,
                                                                    step=args.step)
        # Set args.gif to true if it isn't already in this case
        args.gif = True
        # Set args.duration to src_duration * relative duration, if one was given
        args.duration = args.duration if not args.rel_duration else int(args.rel_duration * src_duration)
    t1 = time()
    # End of glitching
    t2 = time()
    # Save the image
    if not args.gif:
        glitch_img.save(full_path, compress_level=3)
        t3 = time()
        print('Glitched Image saved in "{}"'.format(full_path))
    else:
        glitch_img[0].save(full_path,
                    format='GIF',
                    append_images=glitch_img[1:],
                    save_all=True,
                    duration=args.duration,
                    loop=args.loop,
                    compress_level=3)
        t3 = time()
        print('Glitched GIF saved in "{}"\nFrames = {}, Duration = {}, Loop = {}'.format(full_path, args.frames, args.duration, args.loop))
    print('Time taken to glitch: ' + str(t1 - t0))
    print('Time taken to save: ' + str(t3 - t2))
    print('Total Time taken: ' + str(t3 - t0))

    # Let the user know if new version is available
    if not islatest(ImageGlitcher.__version__):
        print('A new version of "glitch-this" is available. Please consider upgrading via `pip install --upgrade glitch-this`')
Beispiel #3
0
class Glitcher:
    def __init__(self, url):
        self.image = Image(url)

    @property
    def __glitcherWithParams(self):
        self.imGltch = ImageGlitcher()
        amount = round(random.uniform(6.0, 10.0), 2)
        scanlines = bool(random.getrandbits(1))
        colorOffset = bool(random.getrandbits(1))

        return amount, scanlines, colorOffset

    def __glitchGIF(self, src, dest):
        amount, scanlines, colorOffset = self.__glitcherWithParams
        # cycle = bool(random.getrandbits(1))
        change = round(random.uniform(1.0, 3.0), 2)

        # Account for potential glitch_amount overflow
        while (amount + change) >= 10.0:
            change -= 0.1
        while (amount - change) <= 0.1:
            change += 0.1

        glitch, duration_, _ = self.imGltch.glitch_gif(
            src_gif=src.name,
            glitch_amount=amount,
            glitch_change=change,
            cycle=False,
            color_offset=colorOffset,
            scan_lines=scanlines)

        try:
            glitch[0].save(dest.name,
                           format='GIF',
                           append_images=glitch[1:],
                           save_all=True,
                           duration=duration_,
                           loop=0)
        except:
            print(f'ERROR: Failed to save GIF glitch [{dest.name}]')

    def __glitchStatic(self, src, dest):
        amount, scanlines, colorOffset = self.__glitcherWithParams

        glitch = self.imGltch.glitch_image(src_img=src.name,
                                           glitch_amount=amount,
                                           color_offset=colorOffset,
                                           scan_lines=scanlines)

        # Save file
        try:
            glitch.save(dest.name)
        except:
            print(f'ERROR: Failed to save static glitch [{dest.name}]')

    def glitch(self):
        imgFile = self.image.asFile
        suffix = self.image.type
        glitchFile = tempfile.NamedTemporaryFile(suffix=f'.{suffix}')

        if suffix == 'gif':
            self.__glitchGIF(imgFile, glitchFile)
        else:
            self.__glitchStatic(imgFile, glitchFile)

        imgFile.close()
        return glitchFile
Beispiel #4
0
def main():
    # Add commandline arguments parser
    argparser = argparse.ArgumentParser(
        description='Glitchify images to static images and GIFs!')
    argparser.add_argument(
        'src_img_path',
        metavar='Image_Path',
        type=str,
        help='Relative or Absolute string path to source image')
    argparser.add_argument(
        'glitch_level',
        metavar='Glitch_Level',
        type=int,
        help=
        'Integer between 1 and 10, inclusive, representing amount of glitchiness'
    )
    argparser.add_argument(
        '-c',
        '--color',
        dest='color',
        action='store_true',
        help='Whether or not to add color offset, defaults to False')
    argparser.add_argument(
        '-s',
        '--scan',
        dest='scan_lines',
        action='store_true',
        help='Whether or not to add scan lines effect, defaults to False')
    argparser.add_argument(
        '-g',
        '--gif',
        dest='gif',
        action='store_true',
        help='Include if you want a GIF instead of static image'
        '\nNOTE: Does nothing if input image is GIF, i.e when using `-ig`')
    argparser.add_argument(
        '-fr',
        '--frames',
        dest='frames',
        metavar='Frames',
        type=int,
        default=23,
        help='How many frames to include in GIF, defaults to 23'
        '\nNOTE: Does nothing if input image is GIF, i.e when using `-ig`')
    argparser.add_argument(
        '-d',
        '--duration',
        dest='duration',
        metavar='Duration',
        type=int,
        default=200,
        help='How long to display each frame (in centiseconds), defaults to 200'
    )
    argparser.add_argument(
        '-l',
        '--loop',
        dest='loop',
        metavar='Loop_Count',
        type=int,
        default=0,
        help='How many times the glitched GIF should loop, defaults to 0 '
        '(i.e infinite loop)')
    argparser.add_argument(
        '-ig',
        '--inputgif',
        dest='input_gif',
        action='store_true',
        help='If input image is GIF, use for glitching GIFs to GIFs! '
        'Defaults to False\nNOTE: This is a slow process')
    argparser.add_argument(
        '-f',
        '--force',
        dest='force',
        action='store_true',
        help=
        'If included, overwrites existing output file of same name (if found)'
        '\nDefaults to False')
    argparser.add_argument(
        '-o',
        '--outfile',
        dest='outfile',
        metavar='Outfile_path',
        type=str,
        help='Explictly supply the full or relative `path/filename`\
                           \nDefaults to ./glitched_src_image_path')
    args = argparser.parse_args()

    # Sanity check inputs
    if not args.duration > 0:
        raise ValueError('Duration must be greater than 0')
    if not args.loop >= 0:
        raise ValueError('Loop must be greater than or equal to 0')
    if not args.frames > 0:
        raise ValueError('Frames must be greater than 0')
    if not os.path.isfile(args.src_img_path):
        raise FileNotFoundError('No image found at given path')

    # Set up full_path, for output saving location
    out_path, out_file = os.path.split(Path(args.src_img_path))
    out_filename, out_fileex = out_file.rsplit('.', 1)
    out_filename = 'glitched_' + out_filename
    # Output file extension should be '.gif' if output file is going to be a gif
    out_fileex = 'gif' if args.gif else out_fileex
    if args.outfile:
        # If output file path is already given
        # Overwrite the previous values
        out_path, out_file = os.path.split(Path(args.outfile))
        if out_path != '' and not os.path.exists(out_path):
            raise Exception('Given outfile path, ' + out_path +
                            ', does not exist')
        # The extension in user provided outfile path is ignored
        out_filename = out_file.rsplit('.', 1)[0]
    # Now create the full path
    full_path = os.path.join(out_path, '{}.{}'.format(out_filename,
                                                      out_fileex))
    if os.path.exists(full_path) and not args.force:
        raise Exception(
            full_path + ' already exists\nCannot overwrite '
            'existing file unless -f or --force is included\nProgram Aborted')

    # Actual work begins here
    glitcher = ImageGlitcher()
    t0 = time()
    if not args.input_gif:
        # Get glitched image or GIF (from image)
        glitch_img = glitcher.glitch_image(args.src_img_path,
                                           args.glitch_level,
                                           scan_lines=args.scan_lines,
                                           color_offset=args.color,
                                           gif=args.gif,
                                           frames=args.frames)
    else:
        # Get glitched image or GIF (from GIF)
        glitch_img, src_duration, args.frames = glitcher.glitch_gif(
            args.src_img_path,
            args.glitch_level,
            scan_lines=args.scan_lines,
            color_offset=args.color)
        args.gif = True  # Set args.gif to true if it isn't already in this case
    t1 = time()
    # End of glitching
    t2 = time()
    # Save the image
    if not args.gif:
        glitch_img.save(full_path, compress_level=3)
        t3 = time()
        print('Glitched Image saved in "{}"'.format(full_path))
    else:
        glitch_img[0].save(full_path,
                           format='GIF',
                           append_images=glitch_img[1:],
                           save_all=True,
                           duration=args.duration,
                           loop=args.loop,
                           compress_level=3)
        t3 = time()
        print(
            'Glitched GIF saved in "{}"\nFrames = {}, Duration = {}, Loop = {}'
            .format(full_path, args.frames, args.duration, args.loop))
    print('Time taken to glitch: ' + str(t1 - t0))
    print('Time taken to save: ' + str(t3 - t2))
    print('Total Time taken: ' + str(t3 - t0))

    # Let the user know if new version is available
    if not islatest(ImageGlitcher.__version__):
        print(
            'A new version of "glitch-this" is available. Please consider upgrading via `pip install --upgrade glitch-this`'
        )