Merge pull request 'fix(agent): flatten transparency onto white before RGB' (#148) from dev into main
Build images / sign-extension (push) Successful in 3s
CI / lint (push) Successful in 2s
Build images / build-ml (push) Successful in 6s
Build images / build-agent (push) Successful in 7s
Build images / build-web (push) Successful in 6s
CI / frontend-build (push) Successful in 18s
CI / backend-lint-and-test (push) Successful in 26s
CI / integration (push) Successful in 3m27s
Build images / sign-extension (push) Successful in 3s
CI / lint (push) Successful in 2s
Build images / build-ml (push) Successful in 6s
Build images / build-agent (push) Successful in 7s
Build images / build-web (push) Successful in 6s
CI / frontend-build (push) Successful in 18s
CI / backend-lint-and-test (push) Successful in 26s
CI / integration (push) Successful in 3m27s
This commit was merged in pull request #148.
This commit is contained in:
+17
-2
@@ -13,8 +13,23 @@ def is_video(mime: str) -> bool:
|
|||||||
return bool(mime) and (mime.startswith("video/") or mime in {"image/gif"})
|
return bool(mime) and (mime.startswith("video/") or mime in {"image/gif"})
|
||||||
|
|
||||||
|
|
||||||
|
def to_rgb(img: Image.Image) -> Image.Image:
|
||||||
|
"""RGB, flattening any transparency onto white first. A naive convert('RGB')
|
||||||
|
on a palette-with-transparency image (common for character PNGs on a clear
|
||||||
|
background) lets PIL guess the transparent pixels — usually black artifacts
|
||||||
|
that bleed into the crop + the embedding (and the "should be converted to
|
||||||
|
RGBA" warning). Compositing over white gives a clean, consistent background."""
|
||||||
|
if img.mode in ("RGBA", "LA", "PA") or (
|
||||||
|
img.mode == "P" and "transparency" in img.info
|
||||||
|
):
|
||||||
|
img = img.convert("RGBA")
|
||||||
|
bg = Image.new("RGBA", img.size, (255, 255, 255, 255))
|
||||||
|
return Image.alpha_composite(bg, img).convert("RGB")
|
||||||
|
return img.convert("RGB")
|
||||||
|
|
||||||
|
|
||||||
def load_image(data: bytes) -> Image.Image:
|
def load_image(data: bytes) -> Image.Image:
|
||||||
return Image.open(io.BytesIO(data)).convert("RGB")
|
return to_rgb(Image.open(io.BytesIO(data)))
|
||||||
|
|
||||||
|
|
||||||
def sample_frames(
|
def sample_frames(
|
||||||
@@ -44,5 +59,5 @@ def sample_frames(
|
|||||||
names = sorted(n for n in os.listdir(tmp) if n.startswith("f_"))
|
names = sorted(n for n in os.listdir(tmp) if n.startswith("f_"))
|
||||||
for i, name in enumerate(names[:cap]):
|
for i, name in enumerate(names[:cap]):
|
||||||
with Image.open(os.path.join(tmp, name)) as im:
|
with Image.open(os.path.join(tmp, name)) as im:
|
||||||
out.append((round(i * interval, 2), im.convert("RGB")))
|
out.append((round(i * interval, 2), to_rgb(im)))
|
||||||
return out
|
return out
|
||||||
|
|||||||
Reference in New Issue
Block a user