sticker-convert 2.7.7__tar.gz → 2.7.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. {sticker-convert-2.7.7/src/sticker_convert.egg-info → sticker-convert-2.7.8}/PKG-INFO +4 -4
  2. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/README.md +1 -1
  3. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/requirements.txt +2 -2
  4. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/converter.py +68 -33
  5. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/job.py +3 -4
  6. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/resources/compression.json +11 -11
  7. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/resources/help.json +1 -1
  8. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/media/codec_info.py +8 -8
  9. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/version.py +1 -1
  10. {sticker-convert-2.7.7 → sticker-convert-2.7.8/src/sticker_convert.egg-info}/PKG-INFO +4 -4
  11. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert.egg-info/requires.txt +2 -2
  12. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/LICENSE +0 -0
  13. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/MANIFEST.in +0 -0
  14. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/pyproject.toml +0 -0
  15. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/setup.cfg +0 -0
  16. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/__init__.py +0 -0
  17. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/__main__.py +0 -0
  18. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/cli.py +0 -0
  19. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/definitions.py +0 -0
  20. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/downloaders/__init__.py +0 -0
  21. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/downloaders/download_base.py +0 -0
  22. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/downloaders/download_kakao.py +0 -0
  23. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/downloaders/download_line.py +0 -0
  24. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/downloaders/download_signal.py +0 -0
  25. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/downloaders/download_telegram.py +0 -0
  26. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui.py +0 -0
  27. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/__init__.py +0 -0
  28. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/frames/__init__.py +0 -0
  29. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/frames/comp_frame.py +0 -0
  30. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/frames/config_frame.py +0 -0
  31. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/frames/control_frame.py +0 -0
  32. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/frames/cred_frame.py +0 -0
  33. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/frames/input_frame.py +0 -0
  34. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/frames/output_frame.py +0 -0
  35. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/frames/progress_frame.py +0 -0
  36. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/frames/right_clicker.py +0 -0
  37. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/gui_utils.py +0 -0
  38. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/windows/__init__.py +0 -0
  39. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/windows/advanced_compression_window.py +0 -0
  40. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/windows/base_window.py +0 -0
  41. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/windows/kakao_get_auth_window.py +0 -0
  42. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/windows/line_get_auth_window.py +0 -0
  43. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/gui_components/windows/signal_get_auth_window.py +0 -0
  44. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/.github/FUNDING.yml +0 -0
  45. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/.gitignore +0 -0
  46. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/README.md +0 -0
  47. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers/Info.plist +0 -0
  48. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Info.plist +0 -0
  49. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Contents.json +0 -0
  50. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Contents.json +0 -0
  51. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 1.sticker/Contents.json +0 -0
  52. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 1.sticker/Sticker 1.png +0 -0
  53. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 2.sticker/Contents.json +0 -0
  54. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 2.sticker/Sticker 2.png +0 -0
  55. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 3.sticker/Contents.json +0 -0
  56. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 3.sticker/Sticker 3.png +0 -0
  57. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/App-Store-1024x1024pt.png +0 -0
  58. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json +0 -0
  59. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-App-Store-1024x768pt.png +0 -0
  60. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPad-67x50pt@2x.png +0 -0
  61. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPad-Pro-74x55pt@2x.png +0 -0
  62. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPhone-60x45pt@2x.png +0 -0
  63. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPhone-60x45pt@3x.png +0 -0
  64. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages27x20pt@2x.png +0 -0
  65. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages27x20pt@3x.png +0 -0
  66. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages32x24pt@2x.png +0 -0
  67. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages32x24pt@3x.png +0 -0
  68. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPad-Settings-29pt@2x.png +0 -0
  69. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPhone-Settings-29pt@3x.png +0 -0
  70. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPhone-settings-29pt@2x.png +0 -0
  71. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.pbxproj +0 -0
  72. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
  73. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -0
  74. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/xcuserdata/niklaspeterson.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  75. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/ios-message-stickers-template/stickers.xcodeproj/xcuserdata/niklaspeterson.xcuserdatad/xcschemes/xcschememanagement.plist +0 -0
  76. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/job_option.py +0 -0
  77. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/resources/NotoColorEmoji.ttf +0 -0
  78. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/resources/appicon.icns +0 -0
  79. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/resources/appicon.ico +0 -0
  80. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/resources/appicon.png +0 -0
  81. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/resources/emoji.json +0 -0
  82. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/resources/input.json +0 -0
  83. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/resources/output.json +0 -0
  84. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/uploaders/__init__.py +0 -0
  85. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/uploaders/compress_wastickers.py +0 -0
  86. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/uploaders/upload_base.py +0 -0
  87. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/uploaders/upload_signal.py +0 -0
  88. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/uploaders/upload_telegram.py +0 -0
  89. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/uploaders/xcode_imessage.py +0 -0
  90. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/auth/get_kakao_auth.py +0 -0
  91. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/auth/get_line_auth.py +0 -0
  92. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/auth/get_signal_auth.py +0 -0
  93. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/callback.py +0 -0
  94. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/files/cache_store.py +0 -0
  95. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/files/json_manager.py +0 -0
  96. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/files/json_resources_loader.py +0 -0
  97. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/files/metadata_handler.py +0 -0
  98. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/files/run_bin.py +0 -0
  99. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/files/sanitize_filename.py +0 -0
  100. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/media/apple_png_normalize.py +0 -0
  101. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/media/decrypt_kakao.py +0 -0
  102. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/media/format_verify.py +0 -0
  103. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert/utils/url_detect.py +0 -0
  104. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert.egg-info/SOURCES.txt +0 -0
  105. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert.egg-info/dependency_links.txt +0 -0
  106. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert.egg-info/entry_points.txt +0 -0
  107. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/src/sticker_convert.egg-info/top_level.txt +0 -0
  108. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/tests/test_compression.py +0 -0
  109. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/tests/test_download.py +0 -0
  110. {sticker-convert-2.7.7 → sticker-convert-2.7.8}/tests/test_export.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sticker-convert
3
- Version: 2.7.7
3
+ Version: 2.7.8
4
4
  Summary: Convert (animated) stickers to/from WhatsApp, Telegram, Signal, Line, Kakao, iMessage. Written in Python.
5
5
  Author-email: laggykiller <chaudominic2@gmail.com>
6
6
  Maintainer-email: laggykiller <chaudominic2@gmail.com>
@@ -367,13 +367,13 @@ License-File: LICENSE
367
367
  Requires-Dist: aiolimiter~=1.1.0
368
368
  Requires-Dist: anyio~=3.7.1
369
369
  Requires-Dist: apngasm_python~=1.2.3
370
- Requires-Dist: av~=11.0.0
370
+ Requires-Dist: av~=12.0.0
371
371
  Requires-Dist: beautifulsoup4~=4.12.3
372
372
  Requires-Dist: rookiepy~=0.3.6
373
373
  Requires-Dist: imagequant~=1.1.1
374
374
  Requires-Dist: memory-tempfile~=2.2.3
375
375
  Requires-Dist: numpy>=1.22.4
376
- Requires-Dist: Pillow~=10.2.0
376
+ Requires-Dist: Pillow==10.1.0
377
377
  Requires-Dist: pyoxipng~=9.0.0
378
378
  Requires-Dist: python-telegram-bot~=20.5
379
379
  Requires-Dist: requests~=2.31.0
@@ -592,7 +592,7 @@ Compression options:
592
592
  (1) Size limit for video is larger than image;
593
593
  (2) Mix image and video into same pack.
594
594
  --scale-filter SCALE_FILTER
595
- Set scale filter. Default as lanczos. Valid options are:
595
+ Set scale filter. Default as bicubic. Valid options are:
596
596
  - nearest = Use nearest neighbour (Suitable for pixel art)
597
597
  -box = Similar to nearest, but better downscaling
598
598
  - bilinear = Linear interpolation
@@ -206,7 +206,7 @@ Compression options:
206
206
  (1) Size limit for video is larger than image;
207
207
  (2) Mix image and video into same pack.
208
208
  --scale-filter SCALE_FILTER
209
- Set scale filter. Default as lanczos. Valid options are:
209
+ Set scale filter. Default as bicubic. Valid options are:
210
210
  - nearest = Use nearest neighbour (Suitable for pixel art)
211
211
  -box = Similar to nearest, but better downscaling
212
212
  - bilinear = Linear interpolation
@@ -1,13 +1,13 @@
1
1
  aiolimiter~=1.1.0
2
2
  anyio~=3.7.1
3
3
  apngasm_python~=1.2.3
4
- av~=11.0.0
4
+ av~=12.0.0
5
5
  beautifulsoup4~=4.12.3
6
6
  rookiepy~=0.3.6
7
7
  imagequant~=1.1.1
8
8
  memory-tempfile~=2.2.3
9
9
  numpy>=1.22.4
10
- Pillow~=10.2.0
10
+ Pillow==10.1.0
11
11
  pyoxipng~=9.0.0
12
12
  python-telegram-bot~=20.5
13
13
  requests~=2.31.0
@@ -6,10 +6,11 @@ from io import BytesIO
6
6
  from math import ceil, floor
7
7
  from pathlib import Path
8
8
  from queue import Queue
9
- from typing import TYPE_CHECKING, Any, List, Literal, Optional, Tuple, Union, cast
9
+ from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Tuple, Union, cast
10
10
 
11
11
  import numpy as np
12
12
  from PIL import Image
13
+ from PIL import __version__ as PillowVersion
13
14
 
14
15
  from sticker_convert.job_option import CompOption
15
16
  from sticker_convert.utils.callback import Callback, CallbackReturn, CbQueueItemType
@@ -378,10 +379,10 @@ class StickerConvert:
378
379
  self.frames_raw.append(np.asarray(im.convert("RGBA")))
379
380
 
380
381
  def _frames_import_pyav(self) -> None:
381
- import av # type: ignore
382
- from av.codec.context import CodecContext # type: ignore
383
- from av.container.input import InputContainer # type: ignore
384
- from av.video.codeccontext import VideoCodecContext # type: ignore
382
+ import av
383
+ from av.codec.context import CodecContext
384
+ from av.container.input import InputContainer
385
+ from av.video.codeccontext import VideoCodecContext
385
386
 
386
387
  # Crashes when handling some webm in yuv420p and convert to rgba
387
388
  # https://github.com/PyAV-Org/PyAV/issues/1166
@@ -390,16 +391,17 @@ class StickerConvert:
390
391
  file = self.in_f.as_posix()
391
392
  else:
392
393
  file = BytesIO(self.in_f)
393
- with av.open(file) as container: # type: ignore
394
+ with av.open(file) as container:
394
395
  container = cast(InputContainer, container)
395
396
  context = container.streams.video[0].codec_context
396
397
  if context.name == "vp8":
397
- context = CodecContext.create("libvpx", "r") # type: ignore
398
+ context = cast(VideoCodecContext, CodecContext.create("libvpx", "r"))
398
399
  elif context.name == "vp9":
399
- context = CodecContext.create("libvpx-vp9", "r") # type: ignore
400
- context = cast(VideoCodecContext, context)
400
+ context = cast(
401
+ VideoCodecContext, CodecContext.create("libvpx-vp9", "r")
402
+ )
401
403
 
402
- for packet in container.demux(container.streams.video): # type: ignore
404
+ for packet in container.demux(container.streams.video):
403
405
  for frame in context.decode(packet):
404
406
  if frame.width % 2 != 0:
405
407
  width = frame.width - 1
@@ -410,22 +412,22 @@ class StickerConvert:
410
412
  else:
411
413
  height = frame.height
412
414
  if frame.format.name == "yuv420p":
413
- rgb_array = frame.to_ndarray(format="rgb24") # type: ignore
415
+ rgb_array = frame.to_ndarray(format="rgb24")
414
416
  cast("np.ndarray[Any, Any]", rgb_array)
415
417
  rgba_array = np.dstack(
416
418
  (
417
419
  rgb_array,
418
420
  np.zeros(rgb_array.shape[:2], dtype=np.uint8) + 255,
419
- ) # type: ignore
421
+ )
420
422
  )
421
423
  else:
422
424
  # yuva420p may cause crash
423
425
  # https://github.com/laggykiller/sticker-convert/issues/114
424
- frame = frame.reformat( # type: ignore
426
+ frame = frame.reformat(
425
427
  width=width,
426
428
  height=height,
427
429
  format="yuva420p",
428
- dst_colorspace=1, # type: ignore
430
+ dst_colorspace=1,
429
431
  )
430
432
 
431
433
  # https://stackoverflow.com/questions/72308308/converting-yuv-to-rgb-in-python-coefficients-work-with-array-dont-work-with-n
@@ -522,7 +524,7 @@ class StickerConvert:
522
524
  elif self.opt_comp.scale_filter == "lanczos":
523
525
  resample = Image.LANCZOS
524
526
  else:
525
- resample = Image.LANCZOS
527
+ resample = Image.BICUBIC
526
528
 
527
529
  for frame in frames_in:
528
530
  with Image.fromarray(frame, "RGBA") as im: # type: ignore
@@ -615,6 +617,8 @@ class StickerConvert:
615
617
  self._frames_export_png()
616
618
  elif self.out_f.suffix == ".webp" and is_animated:
617
619
  self._frames_export_webp()
620
+ elif self.out_f.suffix == ".gif":
621
+ self._frames_export_gif()
618
622
  elif self.out_f.suffix in (".webm", ".mp4", ".mkv") or is_animated:
619
623
  self._frames_export_pyav()
620
624
  else:
@@ -629,22 +633,17 @@ class StickerConvert:
629
633
  )
630
634
 
631
635
  def _frames_export_pyav(self) -> None:
632
- import av # type: ignore
633
- from av.container import OutputContainer # type: ignore
634
- from av.video.stream import VideoStream # type: ignore
636
+ import av
637
+ from av.video.stream import VideoStream
635
638
 
636
- options = {}
639
+ options: Dict[str, str] = {}
637
640
 
638
641
  if isinstance(self.quality, int):
639
642
  # Seems not actually working
640
643
  options["quality"] = str(self.quality)
641
644
  options["lossless"] = "0"
642
645
 
643
- if self.out_f.suffix == ".gif":
644
- codec = "gif"
645
- pixel_format = "rgb8"
646
- options["loop"] = "0"
647
- elif self.out_f.suffix in (".apng", ".png"):
646
+ if self.out_f.suffix in (".apng", ".png"):
648
647
  codec = "apng"
649
648
  pixel_format = "rgba"
650
649
  options["plays"] = "0"
@@ -657,11 +656,10 @@ class StickerConvert:
657
656
  pixel_format = "yuv420p"
658
657
  options["loop"] = "0"
659
658
 
660
- with av.open( # type: ignore
659
+ with av.open(
661
660
  self.tmp_f, "w", format=self.out_f.suffix.replace(".", "")
662
661
  ) as output:
663
- output = cast(OutputContainer, output) # type: ignore
664
- out_stream = output.add_stream(codec, rate=self.fps, options=options) # type: ignore
662
+ out_stream = output.add_stream(codec, rate=self.fps, options=options)
665
663
  out_stream = cast(VideoStream, out_stream)
666
664
  assert isinstance(self.res_w, int) and isinstance(self.res_h, int)
667
665
  out_stream.width = self.res_w
@@ -669,12 +667,49 @@ class StickerConvert:
669
667
  out_stream.pix_fmt = pixel_format
670
668
 
671
669
  for frame in self.frames_processed:
672
- av_frame = av.VideoFrame.from_ndarray(frame, format="rgba") # type: ignore
673
- for packet in out_stream.encode(av_frame): # type: ignore
674
- output.mux(packet) # type: ignore
675
-
676
- for packet in out_stream.encode(): # type: ignore
677
- output.mux(packet) # type: ignore
670
+ av_frame = av.VideoFrame.from_ndarray(frame, format="rgba")
671
+ output.mux(out_stream.encode(av_frame))
672
+ output.mux(out_stream.encode())
673
+
674
+ def _frames_export_gif(self) -> None:
675
+ extra_kwargs: Dict[str, Any] = {}
676
+
677
+ # disposal=2 on gif cause flicker in image with transparency
678
+ # Occurs in Pillow == 10.2.0
679
+ # https://github.com/python-pillow/Pillow/issues/7787
680
+ if PillowVersion == "10.2.0":
681
+ extra_kwargs["optimize"] = False
682
+ else:
683
+ extra_kwargs["optimize"] = True
684
+
685
+ # Only enable transparency if all pixels have alpha channel
686
+ # with value of 0 or 255
687
+ alpha_channel_values = np.unique(np.array(self.frames_raw)[:, :, :, 3])
688
+ illegals = np.setxor1d(
689
+ alpha_channel_values, [0, 255]
690
+ ) # Find all values not 0 or 255
691
+ if illegals.size == 0:
692
+ extra_kwargs["transparency"] = 0
693
+ extra_kwargs["disposal"] = 2
694
+ im_out = [self.quantize(Image.fromarray(i)) for i in self.frames_processed]
695
+ else:
696
+ im_out = [
697
+ self.quantize(Image.fromarray(i).convert("RGB")).convert("RGB")
698
+ for i in self.frames_processed
699
+ ]
700
+
701
+ if self.fps:
702
+ extra_kwargs["save_all"] = True
703
+ extra_kwargs["append_images"] = im_out[1:]
704
+ extra_kwargs["duration"] = int(1000 / self.fps)
705
+ extra_kwargs["loop"] = 0
706
+
707
+ im_out[0].save(
708
+ self.tmp_f,
709
+ format="GIF",
710
+ quality=self.quality,
711
+ **extra_kwargs,
712
+ )
678
713
 
679
714
  def _frames_export_webp(self) -> None:
680
715
  import webp # type: ignore
@@ -29,7 +29,6 @@ from sticker_convert.utils.files.json_resources_loader import OUTPUT_JSON
29
29
  from sticker_convert.utils.files.metadata_handler import MetadataHandler
30
30
  from sticker_convert.utils.media.codec_info import CodecInfo
31
31
 
32
- CbQueueType = Queue[CbQueueItemType]
33
32
  WorkListItemType = Optional[Tuple[Callable[..., Any], Tuple[Any, ...]]]
34
33
  if TYPE_CHECKING:
35
34
  # mypy complains about this
@@ -59,7 +58,7 @@ class Executor:
59
58
  # Especially when using scale_filter=nearest
60
59
  self.work_list: WorkListType = self.manager.list()
61
60
  self.results_queue: Queue[Any] = self.manager.Queue()
62
- self.cb_queue: CbQueueType = self.manager.Queue()
61
+ self.cb_queue: Queue[CbQueueItemType] = self.manager.Queue()
63
62
  self.cb_return = CallbackReturn()
64
63
  self.processes: List[Process] = []
65
64
 
@@ -76,7 +75,7 @@ class Executor:
76
75
 
77
76
  def cb_thread(
78
77
  self,
79
- cb_queue: CbQueueType,
78
+ cb_queue: Queue[CbQueueItemType],
80
79
  cb_return: CallbackReturn,
81
80
  ) -> None:
82
81
  for i in iter(cb_queue.get, None):
@@ -113,7 +112,7 @@ class Executor:
113
112
  def worker(
114
113
  work_list: WorkListType,
115
114
  results_queue: Queue[Any],
116
- cb_queue: CbQueueType,
115
+ cb_queue: Queue[CbQueueItemType],
117
116
  cb_return: CallbackReturn,
118
117
  ) -> None:
119
118
  while True:
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "steps": 16,
42
42
  "fake_vid": false,
43
- "scale_filter": "lanczos",
43
+ "scale_filter": "bicubic",
44
44
  "quantize_method": "imagequant",
45
45
  "default_emoji": "😀"
46
46
  },
@@ -85,7 +85,7 @@
85
85
  },
86
86
  "steps": 16,
87
87
  "fake_vid": false,
88
- "scale_filter": "lanczos",
88
+ "scale_filter": "bicubic",
89
89
  "quantize_method": "imagequant",
90
90
  "default_emoji": "😀"
91
91
  },
@@ -130,7 +130,7 @@
130
130
  },
131
131
  "steps": 16,
132
132
  "fake_vid": false,
133
- "scale_filter": "lanczos",
133
+ "scale_filter": "bicubic",
134
134
  "quantize_method": "imagequant",
135
135
  "default_emoji": "😀"
136
136
  },
@@ -175,7 +175,7 @@
175
175
  },
176
176
  "steps": 16,
177
177
  "fake_vid": false,
178
- "scale_filter": "lanczos",
178
+ "scale_filter": "bicubic",
179
179
  "quantize_method": "imagequant",
180
180
  "default_emoji": "😀"
181
181
  },
@@ -220,7 +220,7 @@
220
220
  },
221
221
  "steps": 16,
222
222
  "fake_vid": true,
223
- "scale_filter": "lanczos",
223
+ "scale_filter": "bicubic",
224
224
  "quantize_method": "imagequant",
225
225
  "default_emoji": "😀"
226
226
  },
@@ -265,7 +265,7 @@
265
265
  },
266
266
  "steps": 16,
267
267
  "fake_vid": false,
268
- "scale_filter": "lanczos",
268
+ "scale_filter": "bicubic",
269
269
  "quantize_method": "imagequant",
270
270
  "default_emoji": "😀"
271
271
  },
@@ -310,7 +310,7 @@
310
310
  },
311
311
  "steps": 16,
312
312
  "fake_vid": false,
313
- "scale_filter": "lanczos",
313
+ "scale_filter": "bicubic",
314
314
  "quantize_method": "imagequant",
315
315
  "default_emoji": "😀"
316
316
  },
@@ -355,7 +355,7 @@
355
355
  },
356
356
  "steps": 16,
357
357
  "fake_vid": false,
358
- "scale_filter": "lanczos",
358
+ "scale_filter": "bicubic",
359
359
  "quantize_method": "imagequant",
360
360
  "default_emoji": "😀"
361
361
  },
@@ -400,7 +400,7 @@
400
400
  },
401
401
  "steps": 16,
402
402
  "fake_vid": false,
403
- "scale_filter": "lanczos",
403
+ "scale_filter": "bicubic",
404
404
  "quantize_method": "imagequant",
405
405
  "default_emoji": "😀"
406
406
  },
@@ -445,7 +445,7 @@
445
445
  },
446
446
  "steps": 16,
447
447
  "fake_vid": false,
448
- "scale_filter": "lanczos",
448
+ "scale_filter": "bicubic",
449
449
  "quantize_method": "imagequant",
450
450
  "default_emoji": "😀"
451
451
  },
@@ -490,7 +490,7 @@
490
490
  },
491
491
  "steps": 16,
492
492
  "fake_vid": false,
493
- "scale_filter": "lanczos",
493
+ "scale_filter": "bicubic",
494
494
  "quantize_method": "imagequant",
495
495
  "default_emoji": "😀"
496
496
  }
@@ -45,7 +45,7 @@
45
45
  "vid_format": "Set file format if input is animated.",
46
46
  "img_format": "Set file format if input is static.",
47
47
  "fake_vid": "Convert (faking) image to video.\nUseful if:\n(1) Size limit for video is larger than image;\n(2) Mix image and video into same pack.",
48
- "scale_filter": "Set scale filter. Default as lanczos. Valid options are:\n- nearest = Use nearest neighbour (Suitable for pixel art)\n-box = Similar to nearest, but better downscaling\n- bilinear = Linear interpolation\n- hamming = Similar to bilinear, but better downscaling\n- bicubic = Cubic spline interpolation\n- lanczos = A high-quality downsampling filter",
48
+ "scale_filter": "Set scale filter. Default as bicubic. Valid options are:\n- nearest = Use nearest neighbour (Suitable for pixel art)\n-box = Similar to nearest, but better downscaling\n- bilinear = Linear interpolation\n- hamming = Similar to bilinear, but better downscaling\n- bicubic = Cubic spline interpolation\n- lanczos = A high-quality downsampling filter",
49
49
  "quantize_method": "Set method for quantizing image. Default as imagequant. Valid options are:\n- imagequant = Best quality but slow\n- fastoctree = Fast but image looks chunky\n- none = No image quantizing, large image size as result",
50
50
  "cache_dir": "Set custom cache directory.\nUseful for debugging, or speed up conversion if cache_dir is on RAM disk.",
51
51
  "default_emoji": "Set the default emoji for uploading Signal and Telegram sticker packs."
@@ -230,8 +230,8 @@ class CodecInfo:
230
230
  frames_to_iterate: Optional[int] = None,
231
231
  frames_only: bool = False,
232
232
  ) -> Tuple[int, int]:
233
- import av # type: ignore
234
- from av.container.input import InputContainer # type: ignore
233
+ import av
234
+ from av.container.input import InputContainer
235
235
 
236
236
  # Getting fps and frame count from metadata is not reliable
237
237
  # Example: https://github.com/laggykiller/sticker-convert/issues/114
@@ -242,7 +242,7 @@ class CodecInfo:
242
242
  else:
243
243
  file_ref = BytesIO(file)
244
244
 
245
- with av.open(file_ref) as container: # type: ignore
245
+ with av.open(file_ref) as container:
246
246
  container = cast(InputContainer, container)
247
247
  stream = container.streams.video[0]
248
248
  if container.duration:
@@ -257,7 +257,7 @@ class CodecInfo:
257
257
 
258
258
  frame_count = 0
259
259
  last_frame = None
260
- for frame_count, frame in enumerate(container.decode(stream)): # type: ignore
260
+ for frame_count, frame in enumerate(container.decode(stream)):
261
261
  if frames_to_iterate is not None and frame_count == frames_to_iterate:
262
262
  break
263
263
  last_frame = frame
@@ -310,11 +310,11 @@ class CodecInfo:
310
310
  if codec is not None:
311
311
  return codec.lower()
312
312
 
313
- import av # type: ignore
314
- from av.error import InvalidDataError # type: ignore
313
+ import av
314
+ from av.error import InvalidDataError
315
315
 
316
316
  try:
317
- with av.open(file_ref) as container: # type: ignore
317
+ with av.open(file_ref) as container:
318
318
  return container.streams.video[0].codec_context.name.lower()
319
319
  except InvalidDataError:
320
320
  pass
@@ -354,7 +354,7 @@ class CodecInfo:
354
354
  else:
355
355
  file_ref = BytesIO(file)
356
356
 
357
- with av.open(file_ref) as container: # type: ignore
357
+ with av.open(file_ref) as container:
358
358
  stream = container.streams.video[0]
359
359
  width = stream.width
360
360
  height = stream.height
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
- __version__ = "2.7.7"
3
+ __version__ = "2.7.8"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sticker-convert
3
- Version: 2.7.7
3
+ Version: 2.7.8
4
4
  Summary: Convert (animated) stickers to/from WhatsApp, Telegram, Signal, Line, Kakao, iMessage. Written in Python.
5
5
  Author-email: laggykiller <chaudominic2@gmail.com>
6
6
  Maintainer-email: laggykiller <chaudominic2@gmail.com>
@@ -367,13 +367,13 @@ License-File: LICENSE
367
367
  Requires-Dist: aiolimiter~=1.1.0
368
368
  Requires-Dist: anyio~=3.7.1
369
369
  Requires-Dist: apngasm_python~=1.2.3
370
- Requires-Dist: av~=11.0.0
370
+ Requires-Dist: av~=12.0.0
371
371
  Requires-Dist: beautifulsoup4~=4.12.3
372
372
  Requires-Dist: rookiepy~=0.3.6
373
373
  Requires-Dist: imagequant~=1.1.1
374
374
  Requires-Dist: memory-tempfile~=2.2.3
375
375
  Requires-Dist: numpy>=1.22.4
376
- Requires-Dist: Pillow~=10.2.0
376
+ Requires-Dist: Pillow==10.1.0
377
377
  Requires-Dist: pyoxipng~=9.0.0
378
378
  Requires-Dist: python-telegram-bot~=20.5
379
379
  Requires-Dist: requests~=2.31.0
@@ -592,7 +592,7 @@ Compression options:
592
592
  (1) Size limit for video is larger than image;
593
593
  (2) Mix image and video into same pack.
594
594
  --scale-filter SCALE_FILTER
595
- Set scale filter. Default as lanczos. Valid options are:
595
+ Set scale filter. Default as bicubic. Valid options are:
596
596
  - nearest = Use nearest neighbour (Suitable for pixel art)
597
597
  -box = Similar to nearest, but better downscaling
598
598
  - bilinear = Linear interpolation
@@ -1,13 +1,13 @@
1
1
  aiolimiter~=1.1.0
2
2
  anyio~=3.7.1
3
3
  apngasm_python~=1.2.3
4
- av~=11.0.0
4
+ av~=12.0.0
5
5
  beautifulsoup4~=4.12.3
6
6
  rookiepy~=0.3.6
7
7
  imagequant~=1.1.1
8
8
  memory-tempfile~=2.2.3
9
9
  numpy>=1.22.4
10
- Pillow~=10.2.0
10
+ Pillow==10.1.0
11
11
  pyoxipng~=9.0.0
12
12
  python-telegram-bot~=20.5
13
13
  requests~=2.31.0
File without changes