Add borders to avoid cropping cursor shadow

This commit is contained in:
Quantum 2020-10-04 03:07:34 -04:00
parent de7534243d
commit b383486d67
4 changed files with 21 additions and 9 deletions

View file

@ -6,13 +6,15 @@ from wand.sequence import SingleImage
class CursorImage:
image: SingleImage
hotspot: Tuple[int, int]
nominal: int
def __init__(self, image: SingleImage, hotspot: Tuple[int, int]) -> None:
def __init__(self, image: SingleImage, hotspot: Tuple[int, int], nominal: int) -> None:
self.image = image
self.hotspot = hotspot
self.nominal = nominal
def __repr__(self) -> str:
return 'CursorImage(image=%r, hotspot=%r)' % (self.image, self.hotspot)
return 'CursorImage(image=%r, hotspot=%r, nominal=%r)' % (self.image, self.hotspot, self.nominal)
class CursorFrame:

View file

@ -22,7 +22,7 @@ class CURParser(BaseParser):
self._image = Image(blob=blob, format='cur')
self._hotspots = self._parse_header()
self.frames = [CursorFrame([
CursorImage(image, hotspot) for image, hotspot in zip(self._image.sequence, self._hotspots)
CursorImage(image, hotspot, image.width) for image, hotspot in zip(self._image.sequence, self._hotspots)
])]
def _parse_header(self) -> List[Tuple[int, int]]:

View file

@ -81,7 +81,7 @@ class XCursorParser(BaseParser):
image = Image(width=width, height=height)
image.import_pixels(channel_map='BGRA', data=blob)
images_by_size[nominal_size].append(
(CursorImage(image.sequence[0], (x_offset, y_offset)), delay)
(CursorImage(image.sequence[0], (x_offset, y_offset), nominal_size), delay)
)
if len(set(map(len, images_by_size.values()))) != 1:

View file

@ -1,5 +1,6 @@
from typing import List
from wand.color import Color
from wand.image import BaseImage, Image
from win2xcur.cursor import CursorFrame
@ -7,18 +8,27 @@ from win2xcur.cursor import CursorFrame
def apply_to_image(image: BaseImage, *, color: str, radius: float, sigma: float, xoffset: float,
yoffset: float) -> Image:
opacity = Image(width=image.width, height=image.height, pseudo='xc:white')
opacity.composite(image.channel_images['opacity'], left=round(xoffset * image.width),
top=round(yoffset * image.height))
xoffset = round(xoffset * image.width)
yoffset = round(yoffset * image.height)
new_width = image.width + 3 * xoffset
new_height = image.height + 3 * yoffset
opacity = Image(width=new_width, height=new_height, pseudo='xc:white')
opacity.composite(image.channel_images['opacity'], left=xoffset, top=yoffset)
opacity.gaussian_blur(radius * image.width, sigma * image.width)
opacity.negate()
opacity.modulate(50)
shadow = Image(width=image.width, height=image.height, pseudo='xc:' + color)
shadow = Image(width=new_width, height=new_height, pseudo='xc:' + color)
shadow.composite(opacity, operator='copy_opacity')
result = image.clone()
result = Image(width=new_width, height=new_height, pseudo='xc:transparent')
result.composite(image)
result.composite(shadow, operator='difference')
trimmed = result.clone()
trimmed.trim(color=Color('transparent'))
result.crop(width=max(image.width, trimmed.width), height=max(image.height, trimmed.height))
return result