Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for 'target_size' parameter #65

Merged
merged 1 commit into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions tests/test_webp.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,16 @@ def test_image_simple(self):
expected = np.asarray(img, dtype=np.uint8)
assert_array_equal(actual, expected)

def test_image_target_size(self):
rng = np.random.RandomState(42)
img = Image.fromarray(rng.randint(0, 256, size=(128, 128, 3), dtype=np.uint8))

with TemporaryDirectory() as tmpdir:
file_name = os.path.join(tmpdir, 'image.webp')

webp.save_image(img, file_name, target_size=5000, passes=6)
assert os.path.getsize(file_name) <= 5000

def test_image_palette(self, image_bars_palette):
with TemporaryDirectory() as tmpdir:
file_name = os.path.join(tmpdir, 'image.webp')
Expand Down
5 changes: 5 additions & 0 deletions tests/test_webp_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ def test_default(self):
assert config.method == 4
del config

def test_default_target_size_override(self):
config = webp.WebPConfig.new(target_size=1000)
assert config.target_size == 1000
del config

def test_default_lossless(self):
config = webp.WebPConfig.new(lossless=True)
assert config.lossless is True
Expand Down
28 changes: 27 additions & 1 deletion webp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@ def method(self) -> int:
def method(self, method: int) -> None:
self.ptr.method = method

@property
def target_size(self) -> int:
return self.ptr.target_size

@target_size.setter
def target_size(self, target_size: int) -> None:
self.ptr.target_size = target_size

@property
def passes(self) -> int:
return getattr(self.ptr, "pass")

@passes.setter
def passes(self, passes: int) -> None:
setattr(self.ptr, "pass", passes)

def validate(self) -> bool:
return lib.WebPValidateConfig(self.ptr) != 0

Expand All @@ -74,7 +90,10 @@ def new(preset: WebPPreset = WebPPreset.DEFAULT,
quality: Optional[float] = None,
lossless: bool = False,
lossless_preset: Optional[int] = None,
method: Optional[int] = None) -> "WebPConfig":
method: Optional[int] = None,
*,
target_size: Optional[int] = None,
passes: Optional[int] = None) -> "WebPConfig":
"""Create a new WebPConfig instance to describe encoder settings.

1. The preset is loaded, setting default values for quality factor (75.0) and compression
Expand All @@ -98,6 +117,9 @@ def new(preset: WebPPreset = WebPPreset.DEFAULT,
factor and compression method together. Effective default is 6.
method (int, optional): Compression method (0=fast but big, 6=small but slow).
Overrides presets. Effective default is 4.
target_size (int, optional): Desired target size in bytes. When setting this, you
will likely want to set passes to a value greater than 1 also.
passes (int, optional): Number of entropy-analysis passes (between 1 and 10 inclusive).

Returns:
WebPConfig: The new WebPConfig instance.
Expand All @@ -120,6 +142,10 @@ def new(preset: WebPPreset = WebPPreset.DEFAULT,
config.quality = quality
if method is not None:
config.method = method
if target_size is not None:
config.target_size = target_size
if passes is not None:
config.passes = passes

if not config.validate():
raise WebPError('config is not valid')
Expand Down
21 changes: 21 additions & 0 deletions webp_build/cdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ typedef enum WebPPreset {
WEBP_PRESET_TEXT
} WebPPreset;

typedef enum WebPImageHint {
WEBP_HINT_DEFAULT = 0,
WEBP_HINT_PICTURE,
WEBP_HINT_PHOTO,
WEBP_HINT_GRAPH,
WEBP_HINT_LAST
} WebPImageHint;

typedef enum WEBP_CSP_MODE {
MODE_RGB = 0, MODE_RGBA = 1,
MODE_BGR = 2, MODE_BGRA = 3,
Expand Down Expand Up @@ -110,6 +118,19 @@ struct WebPConfig {
int lossless;
float quality;
int method;
WebPImageHint image_hint;
int target_size;
float target_PSNR;
int segments;
int sns_strength;
int filter_strength;
int filter_sharpness;
int filter_type;
int autofilter;
int alpha_compression;
int alpha_filtering;
int alpha_quality;
int pass;
...;
};
typedef struct WebPConfig WebPConfig;
Expand Down
Loading