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): 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_file(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/fixtures").iterdir(): with self.subTest("dir: {}".format(dir_.name)): try: options = json.loads(dir_.joinpath("property.json").read_text()) except IOError: options = {} im = APNG(**options) for file, ctrl in iter_frames(dir_): im.append_file(file, **ctrl) filename = "{}-animated.png".format(dir_.stem) im.save(pathlib.Path("build").joinpath(filename)) subprocess.run( "pngcheck {}".format(filename), cwd="build", shell=True, check=True )
def test_assemble(tmp_path, fixture): try: options = json.loads((fixture / "property.json").read_text()) except IOError: options = {} im = APNG(**options) def iter_frames(): frames = {} for file in fixture.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 file, ctrl in iter_frames(): im.append_file(file, **ctrl) if not im.frames: return filename = "{}-animated.png".format(fixture.stem) im.save(tmp_path / filename) subprocess.check_call( subprocess.list2cmdline(["pngcheck", filename]), cwd=str(tmp_path), shell=True)
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 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 cov2apng(self, uri, plist, dlist): try: im = APNG() for i in range(len(plist)): im.append_file(plist[i], delay=dlist[i]) im.save(uri) except: return False return True
def _modify_apng(apng_path: Path, out_path: Path, metadata: AnimatedImageMetadata, crbundle: CriteriaBundle) -> Path: stdio.message("Modifying APNG...") mod_criteria = crbundle.modify_aimg_criteria aopt_criteria = crbundle.apng_opt_criteria apng_im: APNG = APNG.open(apng_path) stdio.debug({"crbundle": crbundle}) # Reiterate through the frames if matching certain conditions, or per-frame lossy compression is required if mod_criteria.apng_must_reiterate(metadata) or aopt_criteria.is_reduced_color or aopt_criteria.is_unoptimized: stdio.debug(f"REITERATE APNG") new_apng: APNG = APNG() orig_width, orig_height = metadata.width["value"], metadata.height["value"] alpha_base = Image.new("RGBA", size=(orig_width, orig_height)) unoptimized_apng_frames = InternalImageAPI.get_apng_frames(apng_im, unoptimize=True) if mod_criteria.reverse: unoptimized_apng_frames = reversed(list(unoptimized_apng_frames)) for index, (im, control) in enumerate(unoptimized_apng_frames): # logger.debug(png.chunks) delay_fraction = Fraction(1/mod_criteria.fps).limit_denominator() # delay = int(mod_criteria.delay * 1000) control.delay = delay_fraction.numerator control.delay_den = delay_fraction.denominator stdio.debug({"fr_control": control}) if mod_criteria.must_transform(metadata) or aopt_criteria.is_reduced_color or aopt_criteria.convert_color_mode\ or aopt_criteria.is_unoptimized: # with io.BytesIO() as img_buf: # png.save(img_buf) # with Image.open(img_buf) as im: # im.show() stdio.debug({"fr_orig_size": im.size}) has_transparency = im.info.get("transparency") is not None or im.mode == "RGBA" im = im.resize(mod_criteria.size, resample=getattr(Image, mod_criteria.resize_method)) im = im.transpose(Image.FLIP_LEFT_RIGHT) if mod_criteria.flip_x else im im = im.transpose(Image.FLIP_TOP_BOTTOM) if mod_criteria.flip_y else im if im.mode == "P": if has_transparency: im = im.convert("RGBA") else: im = im.convert("RGB") quant_method = Image.FASTOCTREE if has_transparency else Image.MEDIANCUT if aopt_criteria.is_reduced_color: im = im.quantize( aopt_criteria.color_count, method=quant_method, dither=1).convert("RGBA") if aopt_criteria.convert_color_mode: im = im.convert(aopt_criteria.new_color_mode) with io.BytesIO() as new_buf: im.save(new_buf, "PNG") new_apng.append(PNG.from_bytes(new_buf.getvalue()), delay=delay_fraction.numerator, delay_den=delay_fraction.denominator) stdio.debug(f"NEW FRAMES COUNT: {len(new_apng.frames)}") if len(new_apng.frames) > 0: apng_im = new_apng apng_im.num_plays = mod_criteria.loop_count apng_im.save(out_path) if aopt_criteria.is_optimized: stdio.message(f"Optimizing APNG...") APNGOptAPI.optimize_apng(out_path, out_path, aopt_criteria) return out_path
def export_apng(animation, fp): start = int(animation.in_point) end = int(animation.out_point) apng = APNG() for i in range(start, end + 1): file = io.BytesIO() export_png(animation, file, i) file.seek(0) apng.append_file(file, delay=int(round(1000 / animation.frame_rate))) apng.save(fp)
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 save_images_as_animation(image_list, animation_file_name, fps=5): delay = int(1.0 / fps * 1000) type = os.path.splitext(animation_file_name)[1][1:] if type == "gif": image_list[0].save(animation_file_name, format="GIF", append_images=image_list[1:], save_all=True, duration=delay, loop=0) elif type == "png": file = APNG() for img in image_list: tmp_file_name = "/tmp/temp_file.png" img.save(tmp_file_name, format="png") file.append_file(tmp_file_name, delay=delay) file.save(animation_file_name)
def frames_to_gif(save_path='./message.png'): """ Merges frames into an animated png (APNG) Parameters ---------- save_path : str Path describing the location to save the APNG Returns ------- """ n_frames = len(os.listdir('./container_gif')) im = APNG() for idx in range(n_frames): im.append_file('./container_gif/frame{0:05d}.png'.format(idx), delay=50) im.save(save_path)
def _build_apng(image_paths: List[Path], out_full_path: Path, crbundle: CriteriaBundle) -> Path: criteria = crbundle.create_aimg_criteria aopt_criteria = crbundle.apng_opt_criteria # temp_dirs = [] # if aopt_criteria.is_lossy: # qtemp_dir = mk_cache_dir(prefix_name="quant_temp") # temp_dirs.append(qtemp_dir) # image_paths = PNGQuantAPI.quantize_png_images(aopt_criteria, image_paths) # qsequence_info = {} # for index, ip in enumerate(image_paths): # with Image.open(ip) as im: # palette = im.getpalette() # if palette: # qimg_info = { # 'colors': np.array(im.getcolors()), # 'palette': imageutils.reshape_palette(palette), # 'transparency': im.info.get('transparency') # } # qsequence_info[index] = qimg_info # logger.debug(qimg_info) # im.resize((256, 256), Image.NEAREST).show() if criteria.reverse: image_paths.reverse() apng = APNG() img_sizes = set(Image.open(i).size for i in image_paths) stdio.message(str([f"({i[0]}, {i[1]})" for i in img_sizes])) uneven_sizes = len(img_sizes) > 1 or (criteria.width, criteria.height) not in img_sizes shout_nums = imageutils.shout_indices(len(image_paths), 1) # if criteria.flip_x or criteria.flip_y or uneven_sizes or aopt_criteria.is_lossy\ # or aopt_criteria.convert_color_mode: out_dir = filehandler.mk_cache_dir(prefix_name="tmp_apngfrags") preprocessed_paths = [] # logger.debug(crbundle.create_aimg_criteria.__dict__) for index, ipath in enumerate(image_paths): fragment_name = str(ipath.name) if criteria.reverse: reverse_index = len(image_paths) - (index + 1) fragment_name = f"rev_{str.zfill(str(reverse_index), 6)}_{fragment_name}" else: fragment_name = f"{str.zfill(str(index), 6)}_{fragment_name}" save_path = out_dir.joinpath(f"{fragment_name}.png") if shout_nums.get(index): stdio.message(f"Processing frames... ({shout_nums.get(index)})") # with io.BytesIO() as bytebox: with Image.open(ipath) as im: im: Image.Image orig_width, orig_height = im.size has_transparency = im.info.get("transparency") is not None or im.mode == "RGBA" stdio.debug(f"Color mode im: {im.mode}") if criteria.must_resize(width=orig_width, height=orig_height): resize_method_enum = getattr(Image, criteria.resize_method) # yield {"resize_method_enum": resize_method_enum} im = im.resize( (round(criteria.width), round(criteria.height)), resize_method_enum, ) im = im.transpose(Image.FLIP_LEFT_RIGHT) if criteria.flip_x else im im = im.transpose(Image.FLIP_TOP_BOTTOM) if criteria.flip_y else im if im.mode == "P": if has_transparency: im = im.convert("RGBA") else: im = im.convert("RGB") # if criteria.rotation: # im = im.rotate(criteria.rotation, expand=True) # logger.debug(f"Modes comparison: {im.mode}, {aopt_criteria.new_color_mode}") quant_method = Image.FASTOCTREE if has_transparency else Image.MEDIANCUT if aopt_criteria.is_reduced_color: stdio.debug(f"Frame #{index}, has transparency: {has_transparency}, transparency: " f"{im.info.get('transparency')}, quantization method: {quant_method}") im = im.quantize(aopt_criteria.color_count, method=quant_method).convert("RGBA") if aopt_criteria.convert_color_mode: im = im.convert(aopt_criteria.new_color_mode) # logger.debug(f"SAVE PATH IS: {save_path}") im.save(save_path, "PNG") if aopt_criteria.quantization_enabled: save_path = PNGQuantAPI.quantize_png_image(aopt_criteria, save_path) preprocessed_paths.append(save_path) # apng.append(PNG.from_bytes(bytebox.getvalue()), delay=int(criteria.delay * 1000)) stdio.message("Saving APNG....") if criteria.start_frame: preprocessed_paths = imageutils.shift_image_sequence(preprocessed_paths, criteria.start_frame) delay_fraction = Fraction(1/criteria.fps).limit_denominator() apng = APNG.from_files(preprocessed_paths, delay=delay_fraction.numerator, delay_den=delay_fraction.denominator) apng.num_plays = criteria.loop_count apng.save(out_full_path) # else: # logger.message("Saving APNG....") # apng = APNG.from_files(image_paths, delay=int(criteria.delay * 1000)) # apng.num_plays = criteria.loop_count # apng.save(out_full_path) if aopt_criteria.is_optimized: out_full_path = APNGOptAPI.optimize_apng(out_full_path, out_full_path, aopt_criteria) # for td in temp_dirs: # shutil.rmtree(td) stdio.preview_path(out_full_path) # logger.control("CRT_FINISH") shutil.rmtree(out_dir) return out_full_path
def crear_gif(imagenes, path_guardado): animacion = APNG() for imagen in imagenes: animacion.append_file(imagen, delay=20) animacion.save('./test.png')
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 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)
interval=100) anim.save("rocs.gif", writer=PillowWriter(fps=10)) pbar.close() else: import matplotlib.pyplot as plt from apng import APNG from DylSort import treeMergeSort from DylComp import Comparator from DylData import continuousScale from DylMath import genROC, avROC seed = 15 data, D0, D1 = continuousScale(128, 128) comp = Comparator(data, level=0, rand=True, seed=seed) comp.genRand(len(D0), len(D1), 7.72, 'exponential') np.random.seed(seed) im = APNG() fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2) fig.suptitle("Pass number, MSE true, MSE empirical") x = np.linspace(0, 1, num=200) y = x**(1 / 7.72) ax1.set_aspect('equal', 'box') ax2.set_aspect('equal', 'box') elo = simulation_ELO_targetAUC(True) merge = treeMergeSort(data, comp, statParams=[(D0, D1)], combGroups=False) plt.tight_layout() for i in trange(8): roc, mseTheo, mseEmp, empiricROC = next(elo) ax1.plot(x, y, linestyle='--', label='true', lw=3)
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))