我试图在单击鼠标左键时修改 pixbuf,但我认为它没有被修改。 modify_pixel 函数只是从 pixbuf 中获取特定像素并对其进行修改。
fn build_ui(application: &Application) {
let pixbuf = Pixbuf::from_file("assets/map.png").expect("msg");
let pixbuf = Rc::new(RefCell::new(pixbuf));
let gesture = GestureClick::new();
let pixbuf_clone = Rc::clone(&pixbuf);
gesture.connect_pressed(move |_gesture, _n_press, x, y| {
let mut pixbuf = pixbuf_clone.borrow_mut();
let position = [x as usize, y as usize];
if position[0] < pixbuf.width() as usize && position[1] < pixbuf.height() as usize {
modify_pixel(&mut pixbuf, position);
} else {
println!("Out of bounds");
}
});
let picture = Picture::for_pixbuf(Some(&pixbuf.borrow()).expect("No se pudo crear el Picture"));
let window = ApplicationWindow::builder()
.application(application)
.default_height(800)
.default_width(800)
.title("My GTK App")
.build();
window.set_child(Some(&picture));
window.add_controller(gesture);
window.present();
}
fn modify_pixel(pixbuf: &mut Pixbuf, position: [usize;2]){
let pixels = unsafe {pixbuf.pixels()};
let rowstride = pixbuf.rowstride() as usize;
let n_channels = pixbuf.n_channels() as usize;
let offset = position[1] * rowstride + position[0] * n_channels;
let mut pixels = pixels.to_vec();
pixels[offset] = 255;
pixels[offset + 1] = 0;
pixels[offset + 2] = 0;
*pixbuf = Pixbuf::from_mut_slice(
pixels,
Colorspace::Rgb,
pixbuf.has_alpha(),
8,
pixbuf.width(),
pixbuf.height(),
rowstride as i32,
);
}
我也不确定使用手势是否是最合适的选择。我尝试修改条款中的图片,但我遇到了同样的问题
set_pixbuf
来更新 Pixbuf
,如下所示:
fn build_ui(application: &Application) {
let pixbuf = Pixbuf::from_file("assets/map.png").expect("msg");
let pixbuf = Rc::new(RefCell::new(pixbuf));
let pixbuf_clone = Rc::clone(&pixbuf);
let gesture = GestureClick::new();
let picture = Picture::for_pixbuf(Some(&pixbuf.borrow()).expect("Failed to load image."));
let window = ApplicationWindow::builder()
.application(application)
.default_height(800)
.default_width(800)
.title("GTK Pixbuf test")
.build();
window.set_child(Some(&picture));
gesture.connect_pressed(move |_gesture, _n_press, x, y| {
let mut pixbuf = pixbuf_clone.borrow_mut();
let position = [x as usize, y as usize];
if position[0] < pixbuf.width() as usize && position[1] < pixbuf.height() as usize {
modify_pixel(&mut pixbuf, position);
picture.set_pixbuf(Some(&pixbuf));
} else {
println!("Out of bounds");
}
});
window.add_controller(gesture);
window.present();
}
用鼠标单击图像时,会将像素更改为红色。
我认为这并不完全是您想要做的,因此,我建议查看 DrawingArea 示例。
顺便说一句,自 GTK v4.12 起,Pixbuf 相关方法已被弃用。应替换为
paintable
,如下所示:
fn build_ui(application: &Application) {
let pixbuf = Pixbuf::from_file("assets/blank.png").expect("msg");
let pixbuf = Rc::new(RefCell::new(pixbuf));
let pixbuf_clone = Rc::clone(&pixbuf);
let gesture = GestureClick::new();
let picture = Picture::for_paintable(&Texture::for_pixbuf(&pixbuf.borrow()));
let window = ApplicationWindow::builder()
.application(application)
.default_height(800)
.default_width(800)
.title("GTK Pixbuf test")
.build();
window.set_child(Some(&picture));
gesture.connect_pressed(move |_gesture, _n_press, x, y| {
let mut pixbuf = pixbuf_clone.borrow_mut();
let position = [x as usize, y as usize];
if position[0] < pixbuf.width() as usize && position[1] < pixbuf.height() as usize {
modify_pixel(&mut pixbuf, position);
picture.set_paintable(Some(&Texture::for_pixbuf(&pixbuf)));
} else {
println!("Out of bounds");
}
});
window.add_controller(gesture);
window.present();
}