image - Rust + Rust 图像 - 私有(private) 'Associated Type' ?

标签 image image-processing types rust associated-types

目标很简单 - 获取 (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 的 channel 类型。

原始代码的一个值得注意的问题是:当 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_mutchannels_mutiter_mut 以使可变性达到正确的位置。

请注意,Rust 样式是 4 个空格的缩进,所以我也这样做了。

关于image - Rust + Rust 图像 - 私有(private) 'Associated Type' ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28669417/

相关文章:

linux - Imagemagick use-trimbox 根本不起作用

c# - 使用 GDI+ 混合透明图像时的伪像

Angular 2 @Input 数字问题

java - 确认方法签名未被更改的测试?

java - 允许 Java Applet 访问网络服务器上的图像

html - 在文本 html 和 css 旁边对齐图像

java - 当今最先进的图像压缩(不在浏览器上)?

python - 如何找到具有给定值的像素位置

python - 对 HLS jpeg 图像进行颜色阈值处理

types - Impl Add 为类型别名元组 (f64, f64)