0

目标很简单 - 获取 (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 结构完全相同。我将如何获得具有此功能的代码进行编译?put_pixel我见过的所有其他用法都get_pixel在图像对象上使用并对其进行了操作,但我需要使用透明像素,这样就行不通了。

4

1 回答 1

0

Chris Morgan 是正确的——当你接受 a 时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_mutiter_mut,以便将可变性放到正确的位置。

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

于 2015-02-24T01:17:39.100 回答