I am using the piston Rust image library (version 0.10.3) like so:
extern crate image;
use std::f32;
use std::fs::File;
use std::path::Path;
use image::GenericImage;
use image::Pixels;
use image::Pixel;
fn init(input_path: &str) {
let mut img = image::open(&Path::new(input_path)).unwrap();
let img_width = img.dimensions().0;
let img_height = img.dimensions().1;
for p in img.pixels() { println!("pixel: {}", p.2.channel_count()); }
}
fn main() {
init("file.png");
}
This example fails with an error message
error: no method named `channel_count` found for type `image::Rgba<u8>` in the current scope
--> src/main.rs:20:55
|
20 | for p in img.pixels() { println!("pixel: {}", p.2.channel_count()); }
| ^^^^^^^^^^^^^
<std macros>:2:27: 2:58 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
src/main.rs:20:29: 20:72 note: in this expansion of println! (defined in <std macros>)
|
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: candidate #1 is defined in the trait `image::Pixel`
--> src/main.rs:20:55
|
20 | for p in img.pixels() { println!("pixel: {}", p.2.channel_count()); }
| ^^^^^^^^^^^^^
<std macros>:2:27: 2:58 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
src/main.rs:20:29: 20:72 note: in this expansion of println! (defined in <std macros>)
Which i understand is true, because the documentation mentions that the method I want to have is part of the Pixel trait - the documentation doesn't really make it clear how to access a single pixel in a buffer loaded from an existing image, it mostly talks about getting pixels from ImageBuffer
.
How can I iterate over all pixels in an image and get rgb/other values from it?
EDIT: After reading the source code, I worked around this by calling Pixel::channels(&self)
which takes &self
, therefore I figured out this must be a method added via the trait to objects that implement Pixel.
So the signature of channel_count()
has neither parameters nor &self
. How am I supposed to call this method?
The function you're trying to call, channel_count()
, is a static method. It is defined for a type, not for an object of that type. You call it with
Rgba::channel_count()
or
<Rgba<u8> as Pixel>::channel_count()
as the first form will likely fail (in this instance) due to lack of type information.
However, I don't think it will give you what you want. It should just return the number 4
as that is the number of channels that Rgba
has.
To get what you want, the RGB values, take a look at the documentation for the type you have, Rgba
.
It has a public member, data
, which is a 4-element array, and it implements Index
.
If pixel
is of type Rgba<u8>
(corresponding to your p.2
), you can get the values you seek either by calling pixel.data
which will give them to you as an array, or by indexing. For example, pixel[0]
will give you the red value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With