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): 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 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 main(shtfileName: str) -> None: with open(shtfileName, 'rb') as f: data = f.read() (bits, rle, _mode, _direction, nFrames, _start, _reserved) = unpack(HEADER_FORMAT, data[:HEADER_LENGTH]) nBits = int(bits[0]) isRLE = bool(rle[0]) print( f"{shtfileName}: {nBits}-bit {'RLE' if isRLE else 'Uncompressed'} {nFrames} frames" ) assert nBits in (8, 24) assert not isRLE, "RLE format is not supported, use -n when generating .sht file" startPosition = HEADER_LENGTH + (VGA_PALETTE_SIZE if nBits == 8 else 0) pixelSize = 1 if nBits == 8 else 3 frameSize = WIDTH * HEIGHT * pixelSize assert len(data) == startPosition + frameSize * nFrames fileNamePrefix = shtfileName[:shtfileName.rindex('.')] with TemporaryDirectory(prefix='rtr') as tempDir: fileNameTemplate = join(tempDir, f'{fileNamePrefix}-%08d.png') fileNames: List[str] = [] index = startPosition for nFrame in range(1, nFrames + 1): newIndex = index + frameSize frame = data[index:newIndex] index = newIndex if nBits == 8: frame = bytes(chain.from_iterable(zip(frame, frame, frame))) surface = frombuffer(frame, (WIDTH, HEIGHT), 'RGB') fileName = fileNameTemplate % nFrame save(surface, fileName) fileNames.append(fileName) print(nFrame) apngFileName = f'{fileNamePrefix}.png' print(f"Creating APNG {apngFileName}...") APNG.from_files(fileNames, delay=int(1000.0 / FPS)).save(apngFileName)
def save_frames(frame_list, scale=None): size = tuple([L + 1 for L in max(frame_list[0])]) filename_list = [] for f in range(len(frame_list)): frame = frame_list[f] img = Image.new('RGB', size) for x in range(img.size[0]): for y in range(img.size[1]): img.load()[x, y] = frame[x, y] if scale: img = img.resize(scale) filename = 'output/frame' + str(f) + '.png' img.save(filename) filename_list.append(filename) try: APNG.from_files(filename_list, delay=100).save("output/result.png") except: pass
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 creacion(dir_result,dir_data): imgs = os.listdir(dir_data) imgs.sort() lista = [] for i in imgs: lista.append(dir_data + i) ap.from_files(lista,delay=100).save('prueba.png') print(lista)
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 handle_video(video_url, event, device): temp_dir = tempfile.mkdtemp() img_full_dir = os.path.join(temp_dir, "full") img_thumb_dir = os.path.join(temp_dir, "thumb") result_thumb_png = os.path.join(img_thumb_dir, "result.png") os.mkdir(img_full_dir) os.mkdir(img_thumb_dir) logger.info("Processing video for device {}...".format(device)) try: video_file = fetch_video(video_url, temp_dir) video = cv2.VideoCapture(video_file) except Exception as e: logger.exception(e) return try: process_motion(video, img_full_dir) image_full_files = [os.path.join(img_full_dir, f) for f in os.listdir(img_full_dir)] image_full_files.sort() if not image_full_files: logger.warning("Found no motion in video {}...".format(video_url)) return # Now, resize the captured frames image_thumb_files = [] for f in image_full_files: thumb_file = os.path.join(img_thumb_dir, os.path.basename(f)) image = Image.open(f) image.thumbnail((350, 350), Image.ANTIALIAS) image.save(thumb_file, 'PNG') image_thumb_files.append(thumb_file) # Build some animated Gifs APNG.from_files(image_thumb_files, delay=500).save(result_thumb_png) # Upload to S3 key = uuid.uuid4().hex thumb_url = upload_thumb_to_s3(result_thumb_png, "thumb", key, "image/png") video_url = upload_thumb_to_s3(video_file, "vid", key, "video/mp4") # Now, post to slack created_at_local = utc_to_local(event['created_at']) post_to_slack("Motion detected by *{}* at *{}*".format( device.name, created_at_local.ctime()), "Full Video", video_url, thumb_url) except Exception as e: logger.exception(e) finally: shutil.rmtree(temp_dir) video.release()
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 renderer(box): image = images[box.children[0].value] frame_num = box.children[1].value fraction = [[],[],[]] k = 2 for j in range(3): for qubit in range(n): fraction[j].append( box.children[k].value) k += 1 state = image2state(image,grid) bar = widgets.IntProgress(value=0,max=frame_num,step=1,description='Rendering:') display(bar) backend = Aer.get_backend('statevector_simulator') q = QuantumRegister(n) filenames = [] for f in range(frame_num): circuits = [] for j in range(3): qc = QuantumCircuit(q) qc.initialize(state[j],q) for qubit in range(n): qc.ry(2*np.pi*fraction[j][qubit]*f/frame_num,q[qubit]) circuits.append( qc ) job = execute(circuits, backend, shots=1) counts = [] for j in range(3): counts.append( ket2counts( job.result().get_statevector(circuits[j]) ) ) frame = counts2image(counts,grid) bar.value = f+1 filename = 'outputs/temp_'+str(f)+'.png' save_image( counts2image(counts,grid), scale=[300,300], filename=filename) filenames.append( filename ) bar.close() t = time.localtime() animation = 'outputs/'+box.children[0].value.replace(' ','_')+'_'+str(t.tm_year)+'_'+str(t.tm_mon)+'_'+str(t.tm_mday)+'@'+str(t.tm_hour)+':'+str(t.tm_min)+':'+str(t.tm_sec)+'.png' APNG.from_files(filenames,delay=250).save( animation ) for filename in filenames: os.remove(filename) return animation
def crear(entrada, retardo, salida): try: with open(entrada) as archivo: lista = [] for linea in archivo: lista.append(linea[:-1]) except IndexError: sys.stdout.write("No se encuentra el archivo:\n") retarto = retardo * 100 APNG.from_files(lista, delay=retardo).save(salida + ".png")
def _split_apng(apng_path: Path, out_dir: Path, name: str, criteria: SplitCriteria) -> List[Path]: """Extracts all of the frames of an animated PNG into a folder Args: apng_path (Path): Path to the APNG. out_dir (Path): Path to the output directory. name (str): New prefix name of the sequence. criteria (SplitCriteria): Splitting criteria to follow. Returns: List[Path]: List of paths for every split image. """ frame_paths = [] apng = APNG.open(apng_path) apng_frames = InternalImageAPI.get_apng_frames(apng, criteria.is_unoptimized) # frames = _fragment_apng_frames(apng_path, criteria) pad_count = criteria.pad_count shout_nums = imageutils.shout_indices(len(apng.frames), 5) save_name = criteria.new_name or name for index, (fr, control) in enumerate(apng_frames): if shout_nums.get(index): stdio.message(f"Saving split frames... ({shout_nums.get(index)})") save_path = out_dir.joinpath( f"{save_name}_{str.zfill(str(index), pad_count)}.png") fr.save(save_path, format="PNG") frame_paths.append(save_path) if criteria.extract_delay_info: stdio.message("Generating delay information file...") imageutils.generate_delay_file(apng_path, "PNG", out_dir) return frame_paths
def extraer(imagen): anim = APNG.open(imagen) cont = 1 for png, control in anim.frames: png.save('img-{cont}.png'.format(cont=cont)) cont += 1
def upload_image_aws(data, uuidOverwrite='none'): """ Uploads data to aws """ fileData = data['file'] fps = data['grid']['fps'] uni = str(uuid.uuid4()) if uuidOverwrite != 'none': uni = uuidOverwrite unique_filename = uni + '.png' unique_filename_gif = uni + '.gif' dirpath = tempfile.mkdtemp() path_to_data = dirpath filenames = [] for i in range(0, len(fileData)): abs_file_path = os.path.join(path_to_data, 'img' + str(i) + '.png') filenames.append(abs_file_path) imgdata = base64.b64decode(fileData[i]) with open(abs_file_path, 'wb') as f: f.write(imgdata) images = [] for filename in filenames: images.append(imageio.imread(filename)) filePlace = os.path.join(path_to_data, unique_filename) APNG.from_files(filenames, delay=math.floor(1000./fps)).save(filePlace) s3.upload_file( Bucket = BUCKET_NAME, Filename=filePlace, Key = 'app-content/'+unique_filename ) imageio.mimsave(filePlace, images, 'GIF', duration = (1./fps)) s3.upload_file( Bucket = BUCKET_NAME, Filename=filePlace, Key = 'app-content/'+unique_filename_gif ) shutil.rmtree(dirpath) return uni
def apng_png(s=''): x = APNG.open(s) for i in range(len(x.frames)): tmp = x.frames[i][0].to_bytes() fn = s[:-4] + '_%3d.png' % i w = open(fn, 'wb') w.write(tmp) w.close()
def save_animation(func, params, canvas, filename='animation.png', duration=0.2): path = tempfile.mkdtemp() images = [] for k, p in enumerate(params): func(p) image = canvas.canvas.bitmap.ConvertToImage() fname = os.path.join(path, 'frame_' + str(k) + '.png') image.SaveFile(fname, wx.BITMAP_TYPE_PNG) images.append(fname) from apng import APNG APNG.from_files(images, delay=int(duration)).save(filename) shutil.rmtree(path)
def get_apng_duration(file): img = APNG.open(file) dur = 0 for frame, frame_info in img.frames: if frame_info: dur += frame_info.delay * 10 # convert delay from centiseconds to milliseconds return dur
def loop_apng(filename): if 'noloop' in filename: return image = apng.open(filename) # open if len(image.frames) < 2: # check that it is an apng return image.num_plays = 0 # make it loop and hold the last frame longer image.frames[-1][1].delay = 8 * image.frames[0][1].delay image.save(filename)
def load_apng( file ): # this one was hell to implement compared to the three funcs below img = APNG.open(file) frames = [] pilframes = [] dispose_op = 0 width, height = img.frames[0][0].width, img.frames[0][0].height outputbuf = Image.new("RGBA", (width, height), (255, 255, 255, 0)) prev_frame = None for frame, frame_info in img.frames: i = img.frames.index((frame, frame_info)) pilframe = Image.open(io.BytesIO(frame.to_bytes())).convert("RGBA") #print str(i)+"\t"+disposes[dispose_op]+"\t\t"+blends[frame_info.blend_op] if dispose_op == APNG_DISPOSE_OP_BACKGROUND or ( i == 0 and dispose_op == APNG_DISPOSE_OP_PREVIOUS): prev_frame = outputbuf.copy() emptyrect = Image.new( "RGBA", (img.frames[i - 1][0].width, img.frames[i - 1][0].height), (255, 255, 255, 0)) outputbuf.paste( emptyrect, (img.frames[i - 1][1].x_offset, img.frames[i - 1][1].y_offset)) elif dispose_op == APNG_DISPOSE_OP_PREVIOUS: outputbuf = prev_frame.copy() else: prev_frame = outputbuf.copy() if frame_info: outputbuf.paste( pilframe, (frame_info.x_offset, frame_info.y_offset), pilframe.convert("RGBA") if frame_info.blend_op == APNG_BLEND_OP_OVER else None) else: outputbuf.paste(pilframe, (0, 0)) final_frame = outputbuf.copy() pilframes.append(final_frame) if frame_info: frames.append([ final_frame.toqimage(), frame_info.delay * 10 ]) # convert delay from centiseconds to milliseconds dispose_op = frame_info.depose_op else: frames.append([final_frame.toqimage(), 0]) for frame in pilframes: frame.close() return frames
def test_disassemble(self): for dir in pathlib.Path("test").iterdir(): with self.subTest(dir.stem): im = APNG.open(dir.joinpath("animated.png")) for i, (png, ctrl) in enumerate(im.frames): filename = "{}-{}.png".format(dir.stem, i + 1) png.save(pathlib.Path("build").joinpath(filename)) subprocess.run( ["pngcheck", filename], cwd="build", shell=True, check=True)
def save_images(train=True): im = APNG.open( f"../results/baseline/{'anim_train' if train else 'anim_test'}.png") for offset in range(2): im1 = np.concatenate(( np.array( Image.open(io.BytesIO( im.frames[0 + offset * 21][0].to_bytes())))[:68, :68, :], np.array( Image.open(io.BytesIO( im.frames[6 + offset * 21][0].to_bytes())))[:68, :68, :], np.array( Image.open( io.BytesIO( im.frames[12 + offset * 21][0].to_bytes())))[:68, :68, :], np.array( Image.open( io.BytesIO( im.frames[18 + offset * 21][0].to_bytes())))[:68, :68, :], ), axis=1) im2 = np.concatenate(( np.array( Image.open(io.BytesIO( im.frames[0 + offset * 21][0].to_bytes())))[:68, 68:136, :], np.array( Image.open(io.BytesIO( im.frames[6 + offset * 21][0].to_bytes())))[:68, 68:136, :], np.array( Image.open( io.BytesIO( im.frames[12 + offset * 21][0].to_bytes())))[:68, 68:136, :], np.array( Image.open( io.BytesIO( im.frames[18 + offset * 21][0].to_bytes())))[:68, 68:136, :], ), axis=1) imageio.imsave( f"../results/baseline/{'train' if train else 'test'}_x_{offset}.png", im1) imageio.imsave( f"../results/baseline/{'train' if train else 'test'}_g_{offset}.png", im2)
def deapng(self, apngfile): pngs = [] #圖片陣列變數 apng = APNG.open(os.path.abspath(apngfile)) #開啟 APNG 圖片,用APNG套件開啟 self.tf = tempfile.mkdtemp('_APNG2GIF_images') for i, (png, control) in enumerate(apng.frames): png.save(f"{self.tf}/{i}.png") #保存 png 檔 if self.filesize(f'{self.tf}/{i}.png') < 1024: pngs.append(pngs[-2:]) else: pngs.append(f'{self.tf}/{i}.png') pngs = list(self.flat(pngs)) return pngs
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 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").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 process_apng(path=''): """ Processes apng and saves individual frames to png Parameters ---------- path : str Path to input apng to process Returns ------- """ im = APNG.open(path) for i, (png, control) in enumerate(im.frames): png.save('./gif/frame{:05d}.png'.format(i))
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 test_disassemble(tmp_path, fixture): im = APNG.open(fixture / "animated.png") options_file = fixture / "property.json" if options_file.exists(): options = json.loads(options_file.read_text()) for key, value in options.items(): assert getattr(im, key) == value for i, (png, _ctrl) in enumerate(im.frames): filename = "{}-{}.png".format(fixture.stem, i + 1) png.save(tmp_path / filename) subprocess.check_call( subprocess.list2cmdline(["pngcheck", filename]), cwd=str(tmp_path), shell=True)
def test_disassemble(self): for dir_ in pathlib.Path("test/fixtures").iterdir(): with self.subTest(dir_.stem): im = APNG.open(dir_.joinpath("animated.png")) options_file = dir_.joinpath("property.json") if options_file.exists(): options = json.loads(options_file.read_text()) for key, value in options.items(): assert getattr(im, key) == value for i, (png, _ctrl) in enumerate(im.frames): filename = "{}-{}.png".format(dir_.stem, i + 1) png.save(pathlib.Path("build").joinpath(filename)) subprocess.run( "pngcheck {}".format(filename), cwd="build", shell=True, check=True)