почему я получаю ошибку: захваченная переменная не может избежать тела закрытия `FnMut`?

#rust #rust-cargo

#Ржавчина #rust-груз

Вопрос:

Я пытался написать код, который применяет маску для трех прямоугольных областей в моем изображении. Цель состоит в том, чтобы создать вектор, содержащий эти области, чтобы я мог размыть их позже.

Вот мой код :

 fn main() {
    let img = image::open(
        "C:/Users/hp/Desktop/Multiprocessor real-time scheduling/Project2/data/aLIEz.jpg",
    )
    .unwrap();
    let mut gray_image = img.to_luma8();

    struct Rectangles {
        line1: Vec<(u32, u32, u32, u32)>,
        line2: Vec<(u32, u32, u32, u32)>,
        line3: Vec<(u32, u32, u32, u32)>,
    }

    let rectangles1 = Rectangles {
        line1: vec![(250, 325, 350, 415)],
        line2: vec![(225, 500, 350, 615)],
        line3: vec![(50, 825, 185, 980)],
    };
    let img_parts: Vec<_> = rectangles1
        .line1
        .iter()
        .map(|(start_i, start_j, stop_i, stop_j)| {
            gray_image.sub_image(*start_i, *start_j, stop_i - start_i, stop_j - start_j)
        })
        .collect();

    gray_image.save("C:/Users/hp/Desktop/Multiprocessor real-time scheduling/Project2/data_output/test12.png").unwrap();
}
 

Пожалуйста, найдите ошибку ниже :

     error: captured variable cannot escape `FnMut` closure body
  --> srcmain.rs:45:47
   |
17 |     let mut gray_image = img.to_luma8();
   |         -------------- variable defined here
...
45 |     .map(|(start_i, start_j, stop_i, stop_j)| gray_image.sub_image(*start_i, *start_j, stop_i-start_i, stop_j-start_j)).collect();
   |                                             - ----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |                                             | |
   |                                             | returns a reference to a captured variable which escapes the closure body
   |                                             | variable captured here
   |                                             inferred to be a `FnMut` closure
   |
   = note: `FnMut` closures only have access to their captured variables while they are executing...
   = note: ...therefore, they cannot allow references to captured variables to escape
 

Ответ №1:

sub_image возвращает изменяемый вид в изображение. Очевидно, что вы не можете иметь несколько изменяемых представлений в одном и том же изображении из-за конфликтов проверки заимствования. Итак, вместо этого используйте GenericImageView::view для неизменяемого представления:

 // get the trait into scope
use image::GenericImageView;

fn main() {
    let img = image::open(
        "C:/Users/hp/Desktop/Multiprocessor real-time scheduling/Project2/data/aLIEz.jpg",
    )
    .unwrap();
    let mut gray_image = img.to_luma8();

    struct Rectangles {
        line1: Vec<(u32, u32, u32, u32)>,
        line2: Vec<(u32, u32, u32, u32)>,
        line3: Vec<(u32, u32, u32, u32)>,
    }

    let rectangles1 = Rectangles {
        line1: vec![(250, 325, 350, 415)],
        line2: vec![(225, 500, 350, 615)],
        line3: vec![(50, 825, 185, 980)],
    };
    let img_parts: Vec<_> = rectangles1
        .line1
        .iter()
        .map(|(start_i, start_j, stop_i, stop_j)| {
            // use view instead of sub_image here
            gray_image.view(*start_i, *start_j, stop_i - start_i, stop_j - start_j)
        })
        .collect();

    gray_image.save("C:/Users/hp/Desktop/Multiprocessor real-time scheduling/Project2/data_output/test12.png").unwrap();
}
 

Комментарии:

1. Спасибо, ошибка больше не появляется. Я избегал использовать view, потому что хочу выполнять операции в части изображения, но view неизменен, как вы сказали

2. Затем либо выполните операции в map , чтобы у вас была только одна изменяемая ссылка за раз, либо сохраните координаты, чтобы вы могли создавать подизображения по одному позже по мере необходимости.

3. Я не вижу, как я могу сделать размытие на карте. docs.rs/imageproc/0.22.0/imageproc/filter/fn.box_filter.html . Для этого мне нужна ссылка на gray_image