Metadata-Version: 2.1
Name: cykooz.resizer
Version: 2.1.2
Classifier: Development Status :: 5 - Production/Stable
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Rust
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
Classifier: License :: OSI Approved :: MIT License
Classifier: License :: OSI Approved :: Apache Software License
Requires-Dist: wheel; extra == 'dev'
Requires-Dist: maturin; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-benchmark; extra == 'dev'
Requires-Dist: Pillow; extra == 'dev'
Requires-Dist: tabulate; extra == 'dev'
Requires-Dist: Pillow; extra == 'pillow'
Provides-Extra: dev
Provides-Extra: pillow
License-File: LICENSE-APACHE
License-File: LICENSE-MIT
Summary: A fast image resizer
Keywords: image,resize,simd
Author: Kirill Kuzminykh <cykooz@gmail.com>
Author-email: Kirill Kuzminykh <cykooz@gmail.com>
Requires-Python: >=3.7
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# cykooz.resizer

```cykooz.resizer``` is package with optimized version of image resizing
based on Rust's crate [fast_image_resize](https://crates.io/crates/fast_image_resize).

[CHANGELOG](https://github.com/Cykooz/cykooz.resizer/blob/main/CHANGES.md)

## Installation

```shell
python3 -m pip install cykooz.resizer
```

Or with automatically installing Pillow:

```shell
python3 -m pip install cykooz.resizer[pillow]
```

## Information

Supported pixel types and available optimisations:

| Format | Description                                                   | Native Rust | SSE4.1  | AVX2 |
|:------:|:--------------------------------------------------------------|:-----------:|:-------:|:----:|
|   U8   | One `u8` component per pixel (e.g. L)                         |      +      | partial |  +   |
|  U8x2  | Two `u8` components per pixel (e.g. LA)                       |      +      |    +    |  +   |
|  U8x3  | Three `u8` components per pixel (e.g. RGB)                    |      +      | partial |  +   |
|  U8x4  | Four `u8` components per pixel (e.g. RGBA, RGBx, CMYK)        |      +      |    +    |  +   |
|  U16   | One `u16` components per pixel (e.g. L16)                     |      +      |    +    |  +   |
| U16x2  | Two `u16` components per pixel (e.g. LA16)                    |      +      |    +    |  +   |
| U16x3  | Three `u16` components per pixel (e.g. RGB16)                 |      +      |    +    |  +   |
| U16x4  | Four `u16` components per pixel (e.g. RGBA16, RGBx16, CMYK16) |      +      |    +    |  +   |
|  I32   | One `i32` component per pixel                                 |      +      |    -    |  -   |
|  F32   | One `f32` component per pixel                                 |      +      |    -    |  -   |

Implemented resize algorithms:
- Nearest - is nearest-neighbor interpolation, replacing every pixel with the 
  nearest pixel in the output; for upscaling this means multiple pixels of the
  same color will be present.
- Convolution with different filters:
  - box
  - bilinear
  - catmull_rom
  - mitchell
  - lanczos3
- Super sampling - resizing an image in two steps.
  First step uses the "nearest" algorithm. Second step uses "convolution" 
  with configurable filter.


## Usage Examples

### Resize Pillow's image

```python
from PIL import Image

from cykooz.resizer import FilterType, ResizeAlg, Resizer


resizer = Resizer(ResizeAlg.convolution(FilterType.lanczos3))
dst_size = (255, 170)
dst_image = Image.new('RGBA', dst_size)

for i in range(1, 10):
    image = Image.open('nasa_%d-4928x3279.png' % i)
    resizer.resize_pil(image, dst_image)
    dst_image.save('nasa_%d-255x170.png' % i)
```

### Resize raw image with alpha channel

```python
from cykooz.resizer import AlphaMulDiv, FilterType, ImageData, PixelType, ResizeAlg, Resizer

def resize_raw(width: int, height: int, pixels: bytes):
    src_image = ImageData(
        width,
        height,
        PixelType.U8x4,
        pixels,
    )
    alpha_mul_div = AlphaMulDiv()
    resizer = Resizer(ResizeAlg.convolution(FilterType.lanczos3))
    dst_image = ImageData(255, 170, PixelType.U8x4)
    alpha_mul_div.multiply_alpha_inplace(src_image)
    resizer.resize(src_image, dst_image)
    alpha_mul_div.divide_alpha_inplace(dst_image)    
    return dst_image
```

### Change used CPU-extensions

```python
from cykooz.resizer import FilterType, ResizeAlg, Resizer, CpuExtensions


resizer = Resizer(ResizeAlg.convolution(FilterType.lanczos3))
resizer.cpu_extensions = CpuExtensions.sse4_1
...
```

## Benchmarks

Environment:
- CPU: AMD Ryzen 9 5950X
- RAM: DDR4 3800 MHz
- Ubuntu 22.04 (linux 5.15.0)
- Python 3.9
- Rust 1.62.0
- cykooz.resizer = "2.1"

Other Python libraries used to compare of resizing speed:
- Pillow = "9.2.0" (https://pypi.org/project/Pillow/)

Resize algorithms:
- Nearest
- Convolution with Bilinear filter
- Convolution with Lanczos3 filter

### Resize RGBA image 4928x3279 => 852x567

- Source image [nasa-4928x3279.png](https://github.com/Cykooz/cykooz.resizer/blob/main/tests/data/nasa-4928x3279.png)

| Package (time in ms)    |   nearest |   bilinear |   lanczos3 |
|:------------------------|----------:|-----------:|-----------:|
| Pillow                  |      0.66 |      93.16 |     179.96 |
| cykooz.resizer          |      0.20 |      39.19 |      76.71 |
| cykooz.resizer - sse4_1 |      0.20 |      15.60 |      25.16 |
| cykooz.resizer - avx2   |      0.20 |      11.95 |      18.54 |


### Resize grayscale (U8) image 4928x3279 => 852x567

- Source image [nasa-4928x3279.png](https://github.com/Cykooz/cykooz.resizer/blob/main/tests/data/nasa-4928x3279.png)
  has converted into grayscale image with one byte per pixel.

| Package (time in ms) |   nearest |   bilinear |   lanczos3 |
|:---------------------|----------:|-----------:|-----------:|
| Pillow               |      0.28 |      20.73 |      51.07 |
| cykooz.resizer       |      0.19 |      14.31 |      23.84 |

