extern crate png;
use png::{Decoder, Encoder};
use std::fs::File;
use std::io::{BufReader, BufWriter};
fn main() {
let file = File::open("interview.png").unwrap();
let buff_reader = BufReader::new(file);
let decoder = Decoder::new(buff_reader);
let (info, mut reader) = decoder.read_info().unwrap();
let mut data_image = vec![0; info.buffer_size()];
// do somthing ...
reader.next_frame(&mut data_image).unwrap();
let file = File::create("interview2.png").unwrap();
let ref mut buff_writer = BufWriter::new(file);
let mut encoder = Encoder::new(buff_writer, info.width, info.height);
encoder.set_color(png::ColorType::RGBA);
encoder.set_depth(png::BitDepth::Eight);
let mut header = encoder.write_header().unwrap();
header.write_image_data(&data_image).unwrap();
}
i got error messageResult::unwrap()
on an Err
value: Format("wrong data size, expected 3714816 got 2786112")'data_image
actually has rgba color type and bit depth of eight?write_image_data
does not do the transformation of adding an alpha channel internally.
let rgb_image :RgbImage ; // ...
let img_data = rgb_image.clone().to_vec();
let w = rgb_image.width();
let h = rgb_image.height();
let png_image = vec![0;img_data.len()]; // <- how calculate len png_image ?
let ref mut buff_writer = BufWriter::new(img_data);
let mut encoder = png::Encoder::new(buff_writer, w, h);
encoder.set_color(png::ColorType::RGBA);
encoder.set_depth(png::BitDepth::Eight);
let mut header = encoder.write_header().unwrap();
header.write_image_data(&png_image).unwrap();
i use crate image and pngDynamicImage
for the conversion.let rgb_image: RgbImage = /* */
let rgba_image: RgbaImage = DynamicImage::ImageRgb8(rgb_image).into_rgba();
// .. same as you create the encoder.
png.write_image_data(&rgba_image.into_vec())?;
fn nuke_seamline_h(&self, buf: &mut Vec<u8>, image: &mut Vec<u8>, width: usize) {
let mut min_idx: usize = 0;
let mut min: u8 = 255;
let mut seam = BTreeSet::<usize>::new();
for i in (0..(buf.len()-width+1)).step_by(width) {
if buf[i] <= min {
min_idx = i;
min = buf[i];
}
}
seam.insert(min_idx);
while (min_idx + 1) % width != 0 {
let tedge = min_idx < width;
let bedge = min_idx + width >= buf.len();
let midi = min_idx+1;
let mid = buf[midi];
let bef = if !tedge { buf[midi-width] } else { 255 };
let aft = if !bedge { buf[midi+width] } else { 255 };
let mut min = bef;
let mut t_minid = midi-width;
if mid <= bef {
min = mid;
t_minid = midi;
}
if min <= aft {
min_idx = t_minid;
} else {
min_idx = midi+width;
}
seam.insert(min_idx);
}
for (rem, i) in seam.iter().enumerate() {
image.remove(*i - rem);
buf.remove(*i - rem);
}
}
image
, i.e. the buf
is always stored row-major? This would significantly affect the indexing correction in the last loop.*i - rem
it assumes that exactly rem
pixels have been removed prior to the one to-be removed in any iteration.O(width ln width)
(typically square root of your image) but you don't have to do any index correction during removal
failed to fill whole buffer
error? I try to use image
to decode a JPEG and read into a buffer, but it keeps showing me this error. I checked that the buffer length and total_bytes()
is the same, and I have no problem getting dimension and color types from the stream, so I think there are no problems in decoding.
failed to fill whole buffer
error.
djpeg
or convert -verbose
to see if any warnings or errors occur in other decoders
base64
crate before constructing a JpegDecoder?
image-tiff
repo implementing support for GeoTiff?
image-tiff
. Until a few weeks ago, I was able to load normal sized TIFF images with over 300MiB after I increased the buffer limits. Now, I get a InconsistentSizesEncountered
error in expand_strip()
because for whatever reason at some point a strip that was read is bigger than all the others. I don't really have time to do much debugging, I just observed that the new
of LZWDecoder reads more bytes than a strip contains at some point, first few runs are fine. Has anyone any idea what could've changed that caused this?
0.6
now
Hello! I'm trying to use rayon with Pixels, but, although I see it implements ParallelBridge
, I am unable to do it. Here's the sample code
use image::{GenericImage, Pixel};
#[cfg(feature = "rayon")]
use rayon::prelude::*;
pub type Image<P> = ImageBuffer<P, Vec<<P as Pixel>::Subpixel>>;
pub fn map_colors<I, P, Q, F>(image: &I, f: F) -> Image<Q>
where
I: GenericImage<Pixel = P>,
P: Pixel,
Q: Pixel + 'static,
F: Fn(P) -> Q,
{
let (width, height) = image.dimensions();
let mut out: ImageBuffer<Q, Vec<Q::Subpixel>> = ImageBuffer::new(width, height);
#[cfg(feature = "rayon")]
let iter = image.pixels().par_bridge();
#[cfg(not(feature = "rayon"))]
let iter = image.pixels();
// UNSAFE JUSTIFICATION:
// - no need to check bounds
// - `out` is created from the dimensions of `image`
iter.for_each(|(x, y, pixel)| unsafe { out.unsafe_put_pixel(x, y, f(pixel)) });
out
}
And the error is
error[E0599]: no method named `par_bridge` found for struct `image::Pixels<'_, I>` in the current scope
--> src/map.rs:103:43
|
103 | let iter = image.pixels().into_iter().par_bridge();
| ^^^^^^^^^^ method not found in `image::Pixels<'_, I>`
|
::: /home/georg/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/image-0.23.11/./src/image.rs:558:1
|
558 | pub struct Pixels<'a, I: ?Sized + 'a> {
| -------------------------------------
| |
| doesn't satisfy `image::Pixels<'_, I>: rayon::iter::ParallelBridge`
| doesn't satisfy `image::Pixels<'_, I>: std::marker::Send`
|
= note: the method `par_bridge` exists but the following trait bounds were not satisfied:
`image::Pixels<'_, I>: std::marker::Send`
which is required by `image::Pixels<'_, I>: rayon::iter::ParallelBridge`
`(u32, u32, P): std::marker::Send`
which is required by `image::Pixels<'_, I>: rayon::iter::ParallelBridge`
`&image::Pixels<'_, I>: std::marker::Send`
which is required by `&image::Pixels<'_, I>: rayon::iter::ParallelBridge`
`&image::Pixels<'_, I>: std::iter::Iterator`
which is required by `&image::Pixels<'_, I>: rayon::iter::ParallelBridge`
`&mut image::Pixels<'_, I>: std::marker::Send`
which is required by `&mut image::Pixels<'_, I>: rayon::iter::ParallelBridge`
`(u32, u32, P): std::marker::Send`
which is required by `&mut image::Pixels<'_, I>: rayon::iter::ParallelBridge`
Does anyone know if it's possible to get it to work?
Pixels
in the end because it ended up being more readable and the par_bridge
was already there, so I didn't have to reinvent the wheel. However, if the goal is ultimate performance, I would need to go that route I think