Image: [Suggestion] WebP Encoding Support

Created on 25 Oct 2016  路  1Comment  路  Source: image-rs/image

The crate currently supports WebP decoding but it would be nice if it also supported encoding as well. I'd definitely take advantage of it in one of my forthcoming projects.

enhancement hard help wanted

Most helpful comment

For reference purposes (in case anyone wants to know how to encode WebP in the mean time), here's how to encode an ImageBuffer to WebP via libwebp/libc:

extern crate libc;
use libc::{c_int, c_float, size_t};
use std::io::{Write, BufWriter};
use std::fs::File;
use std::path::Path;

#[link(name = "webp")]
extern {
// Here's the C lib's function def:
//     size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output);
//     size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height, int stride, uint8_t** output);

    fn WebPEncodeRGB(rgb: *const u8, width: c_int, height: c_int, stride: c_int, quality_factor: c_float, output: *mut *mut u8) -> size_t;
    fn WebPEncodeLosslessRGB(rgb: *const u8, width: c_int, height: c_int, stride: c_int, output: *mut *mut u8) -> size_t;
    fn WebPFree(ptr: *const u8);
}

let filetype = "webp";
let ref path_str = format!("/tmp/test.{}", filetype);
let path = &Path::new(path_str);
// Pretend this screenshot() function returns ImageBuffer<Rgb<u8>, Vec<u8>>:
let img = screenshot();
let stride = width * 3;
let lossless = false; // Set to true for lossless (Warning: CPU intensive/slow)
let quality: c_float = 75.0; // Quality level of the WebP image
let mut output: *mut u8 = std::ptr::null_mut();
let raw = img.clone().into_raw();
unsafe {
    let length: usize;
    if lossless {
        length = WebPEncodeLosslessRGB(raw.as_ptr(), width as c_int, height as c_int, stride as c_int, &mut output);
    } else {
        length = WebPEncodeRGB(raw.as_ptr(), width as c_int, height as c_int, stride as c_int, quality, &mut output);
    }
    let mut fout = BufWriter::new(File::create(&path).unwrap());
    let slice = std::slice::from_raw_parts(output, length);
    let _ = fout.write_all(slice).unwrap();
    let _ = fout.flush();
    let _ = WebPFree(output); // IMPORTANT: Make sure we free that memory
}

>All comments

For reference purposes (in case anyone wants to know how to encode WebP in the mean time), here's how to encode an ImageBuffer to WebP via libwebp/libc:

extern crate libc;
use libc::{c_int, c_float, size_t};
use std::io::{Write, BufWriter};
use std::fs::File;
use std::path::Path;

#[link(name = "webp")]
extern {
// Here's the C lib's function def:
//     size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output);
//     size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height, int stride, uint8_t** output);

    fn WebPEncodeRGB(rgb: *const u8, width: c_int, height: c_int, stride: c_int, quality_factor: c_float, output: *mut *mut u8) -> size_t;
    fn WebPEncodeLosslessRGB(rgb: *const u8, width: c_int, height: c_int, stride: c_int, output: *mut *mut u8) -> size_t;
    fn WebPFree(ptr: *const u8);
}

let filetype = "webp";
let ref path_str = format!("/tmp/test.{}", filetype);
let path = &Path::new(path_str);
// Pretend this screenshot() function returns ImageBuffer<Rgb<u8>, Vec<u8>>:
let img = screenshot();
let stride = width * 3;
let lossless = false; // Set to true for lossless (Warning: CPU intensive/slow)
let quality: c_float = 75.0; // Quality level of the WebP image
let mut output: *mut u8 = std::ptr::null_mut();
let raw = img.clone().into_raw();
unsafe {
    let length: usize;
    if lossless {
        length = WebPEncodeLosslessRGB(raw.as_ptr(), width as c_int, height as c_int, stride as c_int, &mut output);
    } else {
        length = WebPEncodeRGB(raw.as_ptr(), width as c_int, height as c_int, stride as c_int, quality, &mut output);
    }
    let mut fout = BufWriter::new(File::create(&path).unwrap());
    let slice = std::slice::from_raw_parts(output, length);
    let _ = fout.write_all(slice).unwrap();
    let _ = fout.flush();
    let _ = WebPFree(output); // IMPORTANT: Make sure we free that memory
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

martinlindhe picture martinlindhe  路  6Comments

Horki picture Horki  路  7Comments

theotherphil picture theotherphil  路  3Comments

newpavlov picture newpavlov  路  7Comments

aschampion picture aschampion  路  3Comments