From b4fc7812e43d6b3e745cad5981cdabb8e3ac2aa0 Mon Sep 17 00:00:00 2001 From: Quantum Date: Sun, 4 Oct 2020 03:57:39 -0400 Subject: [PATCH] Premultiply alpha when converting to Xcursor --- requirements.txt | 1 + setup.py | 2 +- win2xcur/utils.py | 10 ++++++++++ win2xcur/writer/x11.py | 7 ++++--- 4 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 win2xcur/utils.py diff --git a/requirements.txt b/requirements.txt index c7d00f5..c81de1e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ +numpy Wand diff --git a/setup.py b/setup.py index 0d68d49..71c79c2 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setup( name='win2xcur', version='0.0.3', packages=find_packages(), - install_requires=['Wand'], + install_requires=['numpy', 'Wand'], entry_points={ 'console_scripts': [ diff --git a/win2xcur/utils.py b/win2xcur/utils.py new file mode 100644 index 0000000..771288d --- /dev/null +++ b/win2xcur/utils.py @@ -0,0 +1,10 @@ +import numpy + + +def premultiply_alpha(source: bytes) -> bytes: + buffer = numpy.frombuffer(source, dtype=numpy.uint8).astype(numpy.double) + alpha = buffer[3::4] / 255.0 + buffer[0::4] *= alpha + buffer[1::4] *= alpha + buffer[2::4] *= alpha + return buffer.astype(numpy.uint8).tobytes() diff --git a/win2xcur/writer/x11.py b/win2xcur/writer/x11.py index 3e68fb1..377fd9f 100644 --- a/win2xcur/writer/x11.py +++ b/win2xcur/writer/x11.py @@ -4,6 +4,7 @@ from typing import List from win2xcur.cursor import CursorFrame from win2xcur.parser import XCursorParser +from win2xcur.utils import premultiply_alpha def to_x11(frames: List[CursorFrame]) -> bytes: @@ -15,7 +16,7 @@ def to_x11(frames: List[CursorFrame]) -> bytes: header = XCursorParser.IMAGE_HEADER.pack( XCursorParser.IMAGE_HEADER.size, XCursorParser.CHUNK_IMAGE, - cursor.image.width, + cursor.nominal, 1, cursor.image.width, cursor.image.height, @@ -25,8 +26,8 @@ def to_x11(frames: List[CursorFrame]) -> bytes: ) chunks.append(( XCursorParser.CHUNK_IMAGE, - cursor.image.width, - header + bytes(cursor.image.export_pixels(channel_map='BGRA')) + cursor.nominal, + header + premultiply_alpha(bytes(cursor.image.export_pixels(channel_map='BGRA'))) )) header = XCursorParser.FILE_HEADER.pack(