Rust + Rust 图像 - 私有 'Associated Type'?
Rust + Rust Image - Private 'Associated Type'?
目标很简单 - 获取 (0, 0) 处的颜色,并在指定阈值(本例中为 16384)内移除图像中与其相似的所有像素。但是,下面的代码无法编译:
#![feature(env, old_path, core, old_io)]
extern crate image;
use std::env;
use std::num::ToPrimitive;
use std::old_io::File;
use image::color::FromColor;
use image::Pixel;
fn get_arguments() -> Vec<String> {
let mut argv: Vec<String> = env::args().collect();
argv.remove(0);
return argv;
}
fn remove_background<T:image::GenericImage>(img: &mut T) {
let background_color = img.get_pixel(0, 0).to_rgba();
let transparent_pixel = image::Rgba([0, 0, 0, 0]);
if background_color[3].to_uint().unwrap() > 0 {
for (x, y, color) in img.pixels() {
let rgba = color.to_rgba();
let (dr,dg,db) = (rgba[0] - background_color[0],
rgba[1] - background_color[1],
rgba[2] - background_color[2]);
if (dr*dr + dg*dg + db*db).to_uint().unwrap() < 16384 { img.put_pixel(x, y, transparent_pixel); } // Remove the background colour.
}
}
}
fn main() {
for filepath in get_arguments() {
let img = image::open( &Path::new(filepath) ).unwrap();
remove_background( &mut img );
let ref mut fout = File::create(&Path::new("output.png")).unwrap();
img.save(fout, image::PNG);
}
}
它给出了以下错误:
src/main.rs:32:83: 32:100 error: mismatched types:
expected `<T as image::image::GenericImage>::Pixel`,
found `image::color::Rgba<_>`
(expected associated type,
found struct `image::color::Rgba`) [E0308]
src/main.rs:32 if (dr*dr + dg*dg + db*db).to_uint().unwrap() < 16384 { img.put_pixel(x, y, transparent_pixel); } // Remove the background colour.
这大概是因为 GenericImage 结构定义了它自己的内部 "Pixel",我认为我无法访问它,但它与普通 Pixel 结构完全相同。我将如何获得具有此功能的代码进行编译?我见过的 put_pixel
的所有其他使用都在图像对象上使用了 get_pixel
并对其进行了操作,但我需要使用透明像素,所以这不起作用。
Chris Morgan 说得对 - 当您接受 GenericImage
时,您必须处理通用 Pixel
。但是,您正在尝试使用特定的 - Rgba
。不仅如此,您还必须指定 Rgba
.
的频道类型
您的原始代码的一个值得注意的问题是:当 GenericImage 由 不支持透明度 的像素组成时,您会怎么做?
这是一个选择一些具体类型并编译的版本:
fn remove_background<T>(img: &mut T)
where T: image::GenericImage<Pixel=image::Rgba<u8>>
{
let background_color = img.get_pixel(0, 0).to_rgba();
if background_color[3].to_uint().unwrap() > 0 {
for (_, _, color) in img.pixels_mut() {
let rgba = color.to_rgba();
let (dr,dg,db) = (rgba[0] - background_color[0],
rgba[1] - background_color[1],
rgba[2] - background_color[2]);
// Remove the background colour.
if (dr*dr + dg*dg + db*db).to_uint().unwrap() < 16384 {
for c in color.channels_mut().iter_mut() { *c = 0 }
}
}
}
}
除了在 where
子句中指定特定像素类型之外,您还将 运行 涉及可变性问题。我将其更改为 pixels_mut
、channels_mut
和 iter_mut
以使可变性达到正确的位置。
请注意,Rust 样式是 4-space 缩进,所以我也这样做了。
目标很简单 - 获取 (0, 0) 处的颜色,并在指定阈值(本例中为 16384)内移除图像中与其相似的所有像素。但是,下面的代码无法编译:
#![feature(env, old_path, core, old_io)]
extern crate image;
use std::env;
use std::num::ToPrimitive;
use std::old_io::File;
use image::color::FromColor;
use image::Pixel;
fn get_arguments() -> Vec<String> {
let mut argv: Vec<String> = env::args().collect();
argv.remove(0);
return argv;
}
fn remove_background<T:image::GenericImage>(img: &mut T) {
let background_color = img.get_pixel(0, 0).to_rgba();
let transparent_pixel = image::Rgba([0, 0, 0, 0]);
if background_color[3].to_uint().unwrap() > 0 {
for (x, y, color) in img.pixels() {
let rgba = color.to_rgba();
let (dr,dg,db) = (rgba[0] - background_color[0],
rgba[1] - background_color[1],
rgba[2] - background_color[2]);
if (dr*dr + dg*dg + db*db).to_uint().unwrap() < 16384 { img.put_pixel(x, y, transparent_pixel); } // Remove the background colour.
}
}
}
fn main() {
for filepath in get_arguments() {
let img = image::open( &Path::new(filepath) ).unwrap();
remove_background( &mut img );
let ref mut fout = File::create(&Path::new("output.png")).unwrap();
img.save(fout, image::PNG);
}
}
它给出了以下错误:
src/main.rs:32:83: 32:100 error: mismatched types:
expected `<T as image::image::GenericImage>::Pixel`,
found `image::color::Rgba<_>`
(expected associated type,
found struct `image::color::Rgba`) [E0308]
src/main.rs:32 if (dr*dr + dg*dg + db*db).to_uint().unwrap() < 16384 { img.put_pixel(x, y, transparent_pixel); } // Remove the background colour.
这大概是因为 GenericImage 结构定义了它自己的内部 "Pixel",我认为我无法访问它,但它与普通 Pixel 结构完全相同。我将如何获得具有此功能的代码进行编译?我见过的 put_pixel
的所有其他使用都在图像对象上使用了 get_pixel
并对其进行了操作,但我需要使用透明像素,所以这不起作用。
Chris Morgan 说得对 - 当您接受 GenericImage
时,您必须处理通用 Pixel
。但是,您正在尝试使用特定的 - Rgba
。不仅如此,您还必须指定 Rgba
.
您的原始代码的一个值得注意的问题是:当 GenericImage 由 不支持透明度 的像素组成时,您会怎么做?
这是一个选择一些具体类型并编译的版本:
fn remove_background<T>(img: &mut T)
where T: image::GenericImage<Pixel=image::Rgba<u8>>
{
let background_color = img.get_pixel(0, 0).to_rgba();
if background_color[3].to_uint().unwrap() > 0 {
for (_, _, color) in img.pixels_mut() {
let rgba = color.to_rgba();
let (dr,dg,db) = (rgba[0] - background_color[0],
rgba[1] - background_color[1],
rgba[2] - background_color[2]);
// Remove the background colour.
if (dr*dr + dg*dg + db*db).to_uint().unwrap() < 16384 {
for c in color.channels_mut().iter_mut() { *c = 0 }
}
}
}
}
除了在 where
子句中指定特定像素类型之外,您还将 运行 涉及可变性问题。我将其更改为 pixels_mut
、channels_mut
和 iter_mut
以使可变性达到正确的位置。
请注意,Rust 样式是 4-space 缩进,所以我也这样做了。