The load_from_memory and load_from_memory_with_format functions are failing with bytes returned from DynamicImage#to_bytes().
There are two tests that show this:
Test one:
#[test]
fn from_load_from_memory() {
let img = open("features/fixtures/img01.jpg")
.expect("File should load");
let img = load_from_memory(&img.to_bytes())
.expect("File should load from its own data");
assert!(true);
}
Fails with this:
---- from_load_from_memory stdout ----
thread 'from_load_from_memory' panicked at 'File should load from its own data: Unsupported(UnsupportedError { format: Unknown, kind: Format(Unknown) })', tests/transformers_test.rs:50:15
Test two:
#[test]
fn from_load_from_memory_with_format() {
let img = open("features/fixtures/img01.jpg")
.expect("File should load");
let img = load_from_memory_with_format(&img.to_bytes(), ImageFormat::Jpeg)
.expect("File should load from its own data and format hint");
assert!(true);
}
Fails with this:
---- from_load_from_memory_with_format stdout ----
thread 'from_load_from_memory_with_format' panicked at 'File should load from its own data and format hint: Decoding(DecodingError { format: Exact(Jpeg), underlying: Some(Format("first two bytes is not a SOI marker")) })', tests/transformers_test.rs:61:15
As best as I can tell, I'm reading Vec<u8> data from a successfully opened DynamicImage back into two functions that take a Vec<u8> and return a DynamicImage. But it's failing.
There's obviously some nuance I'm missing!
If anybody could point me in the right direction to accomplish what I'm trying to achieve, here, it would be really appreciated.
Thanks,
Doug.
The to_bytes method does not encode the image, it returns to you the bytes making up the pixels. You shouldn't decode those bytes but you can use ImageBuffer::from_raw to restore an image. This requires you to save all the metadata separately. If you don't want to do that manually, i.e. for process-to-process communication or very temporary storage, then you may consider using one of the pnm formats which takes care of prepending the the image size and color type to the (basically) raw bytes with without any of the computation overhead (compression, quantization, ..) of jpeg and png.
Thanks @HeroicKatora !
What I need to do is:
DynamicImage (no problem with that)Vec<u8> of bytes of processed image in correct Jpeg formatThe resulting Vec<u8> should be readable by clients as an image -- this is for an image service that modifies images on-the-fly.
It's the third step there I'm struggling with. I'll keep digging but if you could point me at the method I need to get the Jpeg-formatted Vec<u8> I'd be really grateful!
Thanks again,
Doug.
In that case, you're going to want to use JPEGEncoder. The resulting code should be something like:
let mut output = Vec::new();
JPEGEncoder::new(&mut output).encode_image(&img).unwrap();
@fintelia thank you!
That would have taken me ages to trip over!
Thanks so much!