def make_apng( dest: str, blob: bytes, frames: FRAME_DATA_TYPE, speed: float = 1.0, ): """Make APNG file from given file data and frame data. This function must need apng library dependency. :param dest: path of output file :type dest: :class:`str` :param blob: blob of zip file from :func:`ugoira.lib.download_ugoira_zip` :type blob: :class:`bytes` :param frames: mapping object of each frame's filename and interval :param speed: frame interval control value :type speed: :class:`float` """ from apng import APNG, PNG with open_zip_blob(blob) as zf: files = zf.namelist() container = APNG() for fname in files: with Image(blob=zf.read(fname)) as frame: container.append( PNG.from_bytes(frame.make_blob('png')), delay=int(frames[fname] // speed), ) container.save(dest)
def ugoira2apng(ugoira_file, exportname, delete_ugoira, image=None): print_and_log('info', 'processing ugoira to apng...') temp_folder = tempfile.mkdtemp() temp_name = temp_folder + os.sep + "temp.png" with zipfile.ZipFile(ugoira_file) as f: f.extractall(temp_folder) filenames = os.listdir(temp_folder) filenames.remove('animation.json') anim_info = json.load(open(temp_folder + '/animation.json')) files = [] for info in anim_info["frames"]: fImage = temp_folder + os.sep + info["file"] delay = info["delay"] files.append((fImage, delay)) im = APNG() for fImage, delay in files: im.append(fImage, delay=delay) im.save(temp_name) shutil.move(temp_name, exportname) print_and_log('info', 'ugoira exported to: ' + exportname) shutil.rmtree(temp_folder) if delete_ugoira: print_and_log('info', 'deleting ugoira {0}'.format(ugoira_file)) os.remove(ugoira_file) # set last-modified and last-accessed timestamp if image is not None and _config.setLastModified and exportname is not None and os.path.isfile( exportname): ts = time.mktime(image.worksDateDateTime.timetuple()) os.utime(exportname, (ts, ts))
def test_assemble(self): def iter_frames(dir): frames = {} for file in dir.glob("frame-*"): if file.stem not in frames: frames[file.stem] = {"name": file.stem} frames[file.stem][file.suffix] = file for frame in sorted(frames.values(), key=lambda i: int(i["name"].partition("-")[-1])): if ".json" in frame: ctrl = json.loads(frame[".json"].read_text()) else: ctrl = {} yield frame[".png"], ctrl for dir in pathlib.Path("test").iterdir(): with self.subTest("dir: {}".format(dir.name)): im = APNG() for png, ctrl in iter_frames(dir): im.append(png, **ctrl) filename = "{}-animated.png".format(dir.stem) im.save(pathlib.Path("build").joinpath(filename)) subprocess.run( ["pngcheck", filename], cwd="build", shell=True, check=True )
def ugoira2apng(ugoira_file, exportname, delete_ugoira): print_and_log('info', 'processing ugoira to apng...') temp_folder = tempfile.mkdtemp() temp_name = temp_folder + os.sep + "temp.png" with zipfile.ZipFile(ugoira_file) as f: f.extractall(temp_folder) filenames = os.listdir(temp_folder) filenames.remove('animation.json') anim_info = json.load(open(temp_folder + '/animation.json')) files = [] for info in anim_info["frames"]: fImage = temp_folder + os.sep + info["file"] delay = info["delay"] files.append((fImage, delay)) im = APNG() for fImage, delay in files: im.append(fImage, delay=delay) im.save(temp_name) shutil.move(temp_name, exportname) print_and_log('info', 'ugoira exported to: ' + exportname) shutil.rmtree(temp_folder) if delete_ugoira: print_and_log('info', 'deleting ugoira {0}'.format(ugoira_file)) os.remove(ugoira_file)
def ugoira2apng(ugoira_file, exportname, delete_ugoira, image=None): print_and_log('info', 'processing ugoira to apng...') temp_folder = tempfile.mkdtemp() temp_name = temp_folder + os.sep + "temp.png" with zipfile.ZipFile(ugoira_file) as f: f.extractall(temp_folder) filenames = os.listdir(temp_folder) filenames.remove('animation.json') anim_info = json.load(open(temp_folder + '/animation.json')) files = [] for info in anim_info["frames"]: fImage = temp_folder + os.sep + info["file"] delay = info["delay"] files.append((fImage, delay)) im = APNG() for fImage, delay in files: im.append(fImage, delay=delay) im.save(temp_name) shutil.move(temp_name, exportname) print_and_log('info', 'ugoira exported to: ' + exportname) shutil.rmtree(temp_folder) if delete_ugoira: print_and_log('info', 'deleting ugoira {0}'.format(ugoira_file)) os.remove(ugoira_file) # set last-modified and last-accessed timestamp if image is not None and _config.setLastModified and exportname is not None and os.path.isfile(exportname): ts = time.mktime(image.worksDateDateTime.timetuple()) os.utime(exportname, (ts, ts))
def ugoira2apng(ugoira_file, exportname): printAndLog('info', 'processing ugoira to apng...') temp_folder = tempfile.mkdtemp() temp_name = temp_folder + os.sep + "temp.png" z = zipfile.ZipFile(ugoira_file) z.extractall(temp_folder) filenames = os.listdir(temp_folder) filenames.remove('animation.json') anim_info = json.load(open(temp_folder + '/animation.json')) files = [] for info in anim_info["frames"]: fImage = temp_folder + os.sep + info["file"] delay = info["delay"] files.append((fImage, delay)) im = APNG() for fImage, delay in files: im.append(fImage, delay=delay) im.save(temp_name) shutil.move(temp_name, exportname) printAndLog('info', 'ugoira exported to: ' + exportname) shutil.rmtree(temp_folder)
def convert_apng( blob: bytes, frames: FRAME_DATA_TYPE, speed: float = 1.0, ): """Make APNG file from given file data and frame data. This function must need apng library dependency. :param blob: blob of zip file from :func:`ugoira.lib.download_ugoira_zip` :type blob: :class:`bytes` :param frames: mapping object of each frame's filename and interval :param speed: frame interval control value :type speed: :class:`float` :return: Binary string containing generated APNG file """ from apng import APNG, PNG with open_zip_blob(blob) as zf: files = zf.namelist() container = APNG() for file in files: f = io.BytesIO(zf.read(file)) container.append( PNG.open_any(f), delay=int(frames[file]//speed), ) return container.to_bytes()
def create_b64_apng(frames, fps): pngs = [ PNG.from_bytes(cv2.imencode('.png', img)[1].tobytes()) for img in frames ] apng = APNG() for i in pngs: apng.append(i, delay=1000 // fps) return base64.b64encode(apng.to_bytes()).decode('utf-8')
def make_apng(fmt, fps, outname, frames): def pil_to_apng(pil_frame): with io.BytesIO() as buf: pil_frame.save(buf, 'PNG', optimize=True) return PNG.from_bytes(buf.getvalue()) interval_ms = 1000 // fps img = APNG() for frame in map(pil_to_apng, frames): img.append(frame, delay=interval_ms) img.save(outname)
def draw_images(model, name, systematic=True, gan=''): # Solver if gan == 'WGan': print("WGan Solver") solver = AaeWGanSolver(model=model) gan = 'WGan_' elif gan == 'Gan': print("Gan Solver") solver = AaeGanSolver(model=model) gan = 'Gan_' else: solver = AaeSolver(model=model) sess = tf.Session() sess.run(tf.global_variables_initializer()) saver = tf.train.Saver() # To restore previous print("Restoring model") saver.restore(sess, 'models/model_%s%s.ckpt' % (gan, name)) print("Model restored") z = [] # If systematic then all animations pass through origin # If random then they pass through respective axis if systematic: name += 'sys' a = np.zeros([50, 50]) else: name += 'rand' a = np.random.uniform(-1, 1, [50, 50]) # We use sinus so that we can see edge images for longer for v in np.linspace(-np.pi / 2, np.pi / 2, frames): for i in range(model.z_dim): b = np.reshape(np.copy(a[i, :]), [1, 50]) b[0][i] = 2.5 * np.sin(v) z.append(b) z = np.concatenate(z) y = np.zeros([model.z_dim * frames, 1]) img = sess.run(solver.x_from_z, feed_dict={ solver.z_provided: z, solver.y_labels: y }) files = [] w = 64 * 10 h = 64 * 5 b_i_apng = Image.new('L', (w, h), color=1) b_i_canv = Image.new('L', (w, h * frames), color=1) for f in range(frames): for x in range(10): for y in range(5): index = f * 50 + x + y * 10 im = Cell.transform2display(img[index]) cimg = Image.fromarray(np.uint8(1 + im * 254)) b_i_apng.paste(cimg, (x * 64, y * 64)) b_i_canv.paste(cimg, (x * 64, y * 64 + f * 64 * 5)) file = "output/celeb/Res_%d.png" % f files.append(file) # blank_image = blank_image.resize((128*10, 128*5)) b_i_apng.save(file) ap = APNG() # Create animated png for file in files: ap.append(file, delay=100) for file in files[::-1]: ap.append(file, delay=100) if not os.path.exists('output/cell'): os.makedirs('output/cell') ap.save("output/cell/%s.apng" % name) b_i_canv.save("output/cell/%s.png" % name)
def manifold_images(model, name, gan, y=False): # Solver if gan == 'WGan': print("WGan Solver") solver = AaeWGanSolver(model=model) gan = 'WGan_' elif gan == 'Gan': print("Gan Solver") solver = AaeGanSolver(model=model) gan = 'Gan_' else: solver = AaeSolver(model=model) sess = tf.Session() sess.run(tf.global_variables_initializer()) saver = tf.train.Saver() # To restore previous print("Restoring model") saver.restore(sess, 'models/model_%s%s.ckpt' % (gan, name)) print("Model restored") r = 1.8 # Generate grid of z ls = np.linspace(-r, r, samples) lf = np.linspace(-3, 3, frames) z = np.array(list(product(lf, ls, ls, ls, ls))) if not os.path.exists('output/z_tmp'): os.makedirs('output/z_tmp') if y: rng = 10 else: rng = 1 for z_i in range(5): z_t = np.roll(z, z_i, axis=1) for code_v in range(rng): code = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] code[0][code_v] = 1 size = (samples**4 * frames) y_lab = np.reshape(code * size, [size, 10]) img = sess.run(solver.x_from_z, feed_dict={ solver.z_provided: z_t, solver.y_labels: y_lab }) files = [] w = 28 * samples**2 + (samples - 1) * 10 h = (28 * samples**2 + (samples - 1) * 10) * frames b_i_canv = Image.new('L', (w, h), color=1) b_i_apng = Image.new('L', (w, w), color=1) ls = range(samples) lf = range(frames) prod = list(product(lf, ls, ls, ls, ls)) for i, p in enumerate(prod): index = samples ** 4 * p[0] + samples ** 3 * p[1] + \ samples ** 2 * p[2] + samples * p[3] + p[4] im = img[index].reshape([28, 28]) cimg = Image.fromarray(np.uint8(im * 255)) x = p[4] * 28 + p[2] * (10 + 28 * samples) y = p[3] * 28 + p[1] * (10 + 28 * samples) b_i_apng.paste(cimg, (x, y)) y_p = y + p[0] * (28 * samples**2 + (samples - 1) * 10) b_i_canv.paste(cimg, (x, y_p)) if (i + 1) % samples**4 == 0: file = "output/z_tmp/Res_%d.png" % (i // samples**4) files.append(file) b_i_apng.save(file) ap = APNG() # Create animated png for file in files: ap.append(file, delay=100) for file in files[::-1]: ap.append(file, delay=100) if not os.path.exists('output/z_%d' % z_i): os.makedirs('output/z_%d' % z_i) ap.save("output/z_%d/%s_%d.apng" % (z_i, name, code_v)) b_i_canv.save("output/z_%d/%s_%d.png" % (z_i, name, code_v))
def compare_style(model, name, gan, y=False): # Solver if gan == 'WGan': print("WGan Solver") solver = AaeWGanSolver(model=model) gan = 'WGan_' elif gan == 'Gan': print("Gan Solver") solver = AaeGanSolver(model=model) gan = 'Gan_' else: solver = AaeSolver(model=model) sess = tf.Session() sess.run(tf.global_variables_initializer()) saver = tf.train.Saver() # To restore previous print("Restoring model") saver.restore(sess, 'models/model_%s%s.ckpt' % (gan, name)) print("Model restored") b_i = [] for i in range(91): b_i.append(Image.new('L', (28 * 5, 28 * 5))) ys = [] for i in range(9): y = [0] * 10 y[i] = 1.0 ys.append(np.array(y).reshape([1, 10])) for j in range(1, 10): y = [0] * 10 y[i] = 1 - np.sin(np.pi / 20 * j) y[i + 1] = np.sin(np.pi / 20 * j) ys.append(np.array(y).reshape([1, 10])) y = [0] * 10 y[9] = 1.0 ys.append(np.array(y).reshape([1, 10])) y = np.concatenate(ys, axis=0) for i in range(25): z = np.random.uniform(-1.5, 1.5, size=[1, 5]) z = np.tile(z, [91, 1]) img = sess.run(solver.x_from_z, feed_dict={ solver.z_provided: z, solver.y_labels: y }) for j in range(91): im = img[j].reshape([28, 28]) cimg = Image.fromarray(np.uint8(im * 255)) x = 28 * (i % 5) x2 = 28 * (i // 5) b_i[j].paste(cimg, (x, x2)) if not os.path.exists('output/z_tmp'): os.makedirs('output/z_tmp') if not os.path.exists('output/style'): os.makedirs('output/style') ap = APNG() files = [] for i in range(91): file = "output/z_tmp/Res_%d.png" % i b_i[i].save(file) files.append(file) # Create animated png for file in files: ap.append(file, delay=200) ap.save("output/style/%s.apng" % name)