Skip to content

Commit

Permalink
feat: cursor re-canvasing by specifying sizes
Browse files Browse the repository at this point in the history
This can be specified using the `cursor_size:canvas_size` format.
  • Loading branch information
ful1e5 committed May 21, 2024
1 parent 5bc1a49 commit 0f6e9b8
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [unreleased]

### What's New?

- Clickgen now allows cursor bitmap re-canvasing by specifying size using the `cursor_size:canvas_size` format.

## [v2.2.2] - 24 April 2024

### Important Changes
Expand Down
46 changes: 41 additions & 5 deletions src/clickgen/parser/png.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-

import io
from typing import List, Optional, Tuple
from typing import List, Optional, Tuple, Union

from PIL import Image

Expand All @@ -24,14 +24,14 @@ def __init__(
self,
blob: bytes,
hotspot: Tuple[int, int],
sizes: Optional[List[int]] = None,
sizes: Optional[List[Union[int, str]]] = None,
delay: Optional[int] = None,
) -> None:
super().__init__(blob)
self._image = Image.open(io.BytesIO(self.blob))

# 'set' to prevent value duplication
if not sizes:
# 'set' to prevent value duplication
self.sizes = set(SIZES)
else:
self.sizes = set(sizes)
Expand All @@ -58,9 +58,45 @@ def _dim(i: int) -> int:
def _parse(self) -> List[CursorFrame]:
images: List[CursorImage] = []
for s in sorted(self.sizes):
res_img = self._image.resize((s, s), 1)
size: int = 0
canvas_size: int = 0

if isinstance(s, str):
try:
if ":" in s:
size_str, canvas_size_str = s.split(":")
size = int(size_str)
canvas_size = int(canvas_size_str)
else:
size = int(s)
canvas_size = size
except ValueError:
raise ValueError(
f"'sizes' input '{s}' must be an integer or integers separated by ':'."
)
except IndexError:
raise ValueError(
f"'sizes' input '{s}' must contain one ':' to separate sizes."
)
elif isinstance(s, int):
size = s
canvas_size = s
else:
raise TypeError(
"Input must be 'cursor_size:canvas_size' or an integer."
)

res_img = self._image.resize((size, size), 1)

if size != canvas_size:
canvas = Image.new("RGBA", (size, size), (0, 0, 0, 0))
canvas.paste(res_img, (0, 0))
res_img = canvas

res_hotspot = self._cal_hotspot(res_img)
images.append(CursorImage(image=res_img, hotspot=res_hotspot, nominal=s))
images.append(
CursorImage(image=res_img, hotspot=res_hotspot, nominal=canvas_size)
)

return [CursorFrame(images, delay=self.delay)]

Expand Down

0 comments on commit 0f6e9b8

Please sign in to comment.