File: README.md

package info (click to toggle)
rust-libheif-rs 2.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,268 kB
  • sloc: makefile: 2
file content (172 lines) | stat: -rw-r--r-- 4,740 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# libheif-rs

Safe wrapper around the [libheif-sys](https://github.com/Cykooz/libheif-sys)
crate for parsing heif/heic files.

[CHANGELOG](https://github.com/Cykooz/libheif-rs/blob/master/CHANGELOG.md)

## System dependencies

- `libheif-dev` >= 1.17.0

## Minimal supported libheif version

Minimal supported version of `libheif` library is 1.17.
But there are some functions in the crate that require a newer version of
`libheif` library.

You may specify a minimal version of `libheif` library that is required for you.
To do this, enable the corresponding feature `v1_17`, `v1_18`, `v1_19` or `v1_20`.

Example:

```toml
[dependencies]
libheif-rs = { version = "2.1", default-features = false, features = ["v1_17"] }
```

There is also the `latest` feature. It always corresponds to
the maximal supported by the crate version of `libheif` API.
This feature is enabled by default.

### Linux

Crate `libheif-sys` uses `pkg-confing` command to find installed `libheif`.

You can also enable `embedded-libheif` feature to compile `libheif` from
embedded into `libheif-sys` crate sources and then link it statically.

<div class="warning">

Note: Static linked version of `libheif` doesn't have statically linked
it dependencies, such as `libde256`, `libaom` and other.

</div>

### Windows

Crate `libheif-sys` uses [vcpkg crate](https://crates.io/crates/vcpkg)
to find `libheif` installed with help of `vcpkg`.

You can use [cargo-vcpkg](https://crates.io/crates/cargo-vcpkg)
to install `libheif` with help of `cargo` command:

```shell
cargo vcpkg -v build
```

`cargo-vcpkg` can fetch and build a `vcpkg` installation of required
packages from scratch. It merges package requirements specified in
the `Cargo.toml` of crates in the dependency tree.

## Examples

### Read HEIF file

```rust
use libheif_rs::{
    Channel, RgbChroma, ColorSpace, HeifContext, Result,
    ItemId, LibHeif
};

fn main() -> Result<()> {
    let lib_heif = LibHeif::new();
    let ctx = HeifContext::read_from_file("./data/test.heif")?;
    let handle = ctx.primary_image_handle()?;
    assert_eq!(handle.width(), 1652);
    assert_eq!(handle.height(), 1791);

    // Get Exif
    let mut meta_ids: Vec<ItemId> = vec![0; 1];
    let count = handle.metadata_block_ids(&mut meta_ids, b"Exif");
    assert_eq!(count, 1);
    let exif: Vec<u8> = handle.metadata(meta_ids[0])?;

    // Decode the image
    let image = lib_heif.decode(
        &handle,
        ColorSpace::Rgb(RgbChroma::Rgb),
        None,
    )?;
    assert_eq!(
        image.color_space(), 
        Some(ColorSpace::Rgb(RgbChroma::Rgb)),
    );
    assert_eq!(image.width(), 1652);
    assert_eq!(image.height(), 1791);

    // Scale the image
    let small_img = image.scale(1024, 800, None)?;
    assert_eq!(small_img.width(), 1024);
    assert_eq!(small_img.height(), 800);

    // Get "pixels"
    let planes = small_img.planes();
    let interleaved_plane = planes.interleaved.unwrap();
    assert_eq!(interleaved_plane.width, 1024);
    assert_eq!(interleaved_plane.height, 800);
    assert!(!interleaved_plane.data.is_empty());
    assert!(interleaved_plane.stride > 0);

    Ok(())
}
```

### Write HEIF file

```rust
use tempfile::NamedTempFile;
use libheif_rs::{
    Channel, RgbChroma, ColorSpace, CompressionFormat,
    EncoderQuality, HeifContext, Image, Result, LibHeif
};

fn main() -> Result<()> {
    let width = 640;
    let height = 480;

    let mut image = Image::new(
        width,
        height,
        ColorSpace::Rgb(RgbChroma::C444)
    )?;

    image.create_plane(Channel::R, width, height, 8)?;
    image.create_plane(Channel::G, width, height, 8)?;
    image.create_plane(Channel::B, width, height, 8)?;

    let planes = image.planes_mut();
    let plane_r = planes.r.unwrap();
    let stride = plane_r.stride;

    let data_r = plane_r.data;
    let data_g = planes.g.unwrap().data;
    let data_b = planes.b.unwrap().data;

    // Fill data of planes by some "pixels"
    for y in 0..height {
        let mut pixel_index = stride * y as usize;
        for x in 0..width {
            let color = ((x * y) as u32).to_le_bytes();
            data_r[pixel_index] = color[0];
            data_g[pixel_index] = color[1];
            data_b[pixel_index] = color[2];
            pixel_index += 1;
        }
    }

    // Encode image and save it into file.
    let lib_heif = LibHeif::new();
    let mut context = HeifContext::new()?;
    let mut encoder = lib_heif.encoder_for_format(
        CompressionFormat::Av1,
    )?;
    encoder.set_quality(EncoderQuality::LossLess)?;
    context.encode_image(&image, &mut encoder, None)?;

    let tmp_file = NamedTempFile::new().unwrap();
    context.write_to_file(tmp_file.path().to_str().unwrap())?;

    Ok(())
}
```