RFTSystems commited on
Commit
5bbf1d0
·
verified ·
1 Parent(s): d90b4e9

Create replayproof_media.py

Browse files
Files changed (1) hide show
  1. replayproof_media.py +59 -0
replayproof_media.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import hashlib
5
+ from typing import List, Optional
6
+
7
+ import imageio.v2 as imageio
8
+ import numpy as np
9
+ from PIL import Image, ImageDraw
10
+
11
+
12
+ def sha256_file(path: str) -> str:
13
+ h = hashlib.sha256()
14
+ with open(path, "rb") as f:
15
+ for chunk in iter(lambda: f.read(1024 * 1024), b""):
16
+ h.update(chunk)
17
+ return h.hexdigest()
18
+
19
+
20
+ def watermark_image(img: Image.Image, text: str) -> Image.Image:
21
+ """
22
+ Simple bottom-right watermark.
23
+ Keeps dependencies minimal (no fonts required).
24
+ """
25
+ out = img.copy()
26
+ d = ImageDraw.Draw(out)
27
+
28
+ pad = 8
29
+ w, h = out.size
30
+ # textlength exists on modern Pillow; if missing, approximate
31
+ try:
32
+ tw = d.textlength(text)
33
+ except Exception:
34
+ tw = 8 * len(text)
35
+
36
+ x = max(pad, int(w - tw - pad))
37
+ y = h - 20
38
+
39
+ d.rectangle([x - 6, y - 2, w - pad + 2, y + 16], fill=(0, 0, 0))
40
+ d.text((x, y), text, fill=(235, 235, 235))
41
+ return out
42
+
43
+
44
+ def export_gif(
45
+ frames: List[Image.Image],
46
+ out_path: str,
47
+ fps: int = 10,
48
+ watermark: Optional[str] = None,
49
+ ) -> str:
50
+ os.makedirs(os.path.dirname(out_path), exist_ok=True)
51
+
52
+ imgs = []
53
+ for im in frames:
54
+ if watermark:
55
+ im = watermark_image(im, watermark)
56
+ imgs.append(np.array(im.convert("RGB")))
57
+
58
+ imageio.mimsave(out_path, imgs, duration=1.0 / max(1, int(fps)))
59
+ return out_path