2015-02-23 44 views
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,但是我需要使用透明像素,所以这样做不起作用。

+1

实现'GenericImage'的类型为'Pixel'指定了一个特定的类型,我认为'put_pixel'方法需要;但是,你已经给它一个'Rgba',这不一定是正确的类型。 – 2015-02-24 00:41:23

回答

0

克里斯摩根是现货 - 当您接受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空间缩进,所以我也这样做了。