Code Monkey home page Code Monkey logo

show-image-rs's Introduction

Docs.rs CI

show-image

show-image is a library for quickly displaying images. It is intended as a debugging aid for writing image processing code. The library is not intended for making full-featured GUIs, but you can process keyboard events from the created windows.

Supported image types.

The library aims to support as many different data types used to represent images. To keep the dependency graph as small as possible, support for third party libraries must be enabled explicitly with feature flags.

Currently, the following types are supported:

If you think support for a some data type is missing, feel free to send a PR or create an issue on GitHub.

Global context and threading

The library uses a global context that runs an event loop. This context must be initialized before any show-image functions can be used. Additionally, some platforms require the event loop to be run in the main thread. To ensure portability, the same restriction is enforced on all platforms.

The easiest way to initialize the global context and run the event loop in the main thread is to use the main attribute macro on your main function. If you want to run some code in the main thread before the global context takes over, you can use the run_context() function or one of it's variations instead. Note that you must still call those functions from the main thread, and they do not return control back to the caller.

Event handling.

You can register an event handler to run in the global context thread using WindowProxy::add_event_handler() or some of the similar functions. You can also register an event handler directly with the context to handle global events (including all window events). Since these event handlers run in the event loop, they should not block for any significant time.

You can also receive events using WindowProxy::event_channel() or ContextProxy::event_channel(). These functions create a new channel for receiving window events or global events, respectively. As long as you're receiving the events in your own thread, you can block as long as you like.

Saving displayed images.

If the save feature is enabled, windows allow the displayed image to be saved using Ctrl+S or Ctrl+Shift+S. The first shortcut will open a file dialog to save the currently displayed image. The second shortcut will directly save the image in the current working directory using the name of the image.

The image is saved without any overlays. To save an image including overlays, add Alt to the shortcut: Ctrl+Alt+S and Ctrl+Alt+Shift+S.

Note that images are saved in a background thread. To ensure that no data loss occurs, call exit() to terminate the process rather than std::process::exit(). That will ensure that the background threads are joined before the process is terminated.

Example 1: Showing an image.

use show_image::{ImageView, ImageInfo, create_window};

#[show_image::main]
fn main() -> Result<(), Box<dyn std::error::Error>> {

  let image = ImageView::new(ImageInfo::rgb8(1920, 1080), pixel_data);

  // Create a window with default options and display the image.
  let window = create_window("image", Default::default())?;
  window.set_image("image-001", image)?;

  Ok(())
}

Example 2: Handling keyboard events using an event channel.

use show_image::{event, create_window};

// Create a window and display the image.
let window = create_window("image", Default::default())?;
window.set_image("image-001", &image)?;

// Print keyboard events until Escape is pressed, then exit.
// If the user closes the window, the channel is closed and the loop also exits.
for event in window.event_channel()? {
  if let event::WindowEvent::KeyboardInput(event) = event {
        println!("{:#?}", event);
        if event.input.key_code == Some(event::VirtualKeyCode::Escape) && event.input.state.is_pressed() {
            break;
        }
    }
}

Back-end and GPU selection

This crate uses wgpu for rendering. You can force the selection of a specfic WGPU backend by setting the WGPU_BACKEND environment variable to one of the supported values:

  • primary: Use the primary backend for the platform (the default).
  • vulkan: Use the vulkan back-end.
  • metal: Use the metal back-end.
  • dx12: Use the DirectX 12 back-end.
  • dx11: Use the DirectX 11 back-end.
  • gl: Use the OpenGL back-end.
  • webgpu: Use the browser WebGPU back-end.

You can also influence the GPU selection by setting the WGPU_POWER_PREF environment variable:

  • low: Prefer a low power GPU (the default).
  • high: Prefer a high performance GPU.

show-image-rs's People

Contributors

danielvschoor avatar de-vri-es avatar decahedron1 avatar gan74 avatar hgaiser avatar jsmcconn avatar kamduis avatar vsuryamurthy avatar xanecs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

show-image-rs's Issues

Black screen when using the Vulkan backend

The example works with WGPU_BACKEND=dx12, but shows a black screen when it uses Vulkan (which is the default for my system) on Windows.

Log:

ImageInfo {
    pixel_format: Rgb8,
    size: UVec2(
        553,
        289,
    ),
    stride: UVec2(
        3,
        1659,
    ),
}
[2022-10-14T16:58:13Z INFO  wgpu_core::instance] Adapter Vulkan AdapterInfo { name: "NVIDIA GeForce RTX 3070", vendor: 4318, device: 9348, device_type: DiscreteGpu, backend: Vulkan }
[2022-10-14T16:58:13Z INFO  wgpu_hal::vulkan::adapter] Private capabilities: PrivateCapabilities { flip_y_requires_shift: true, imageless_framebuffers: true, image_view_usage: true, timeline_semaphores: true, texture_d24: true, texture_d24_s8: true, can_present: true, non_coherent_map_mask: 63, robust_buffer_access: 
true, robust_image_access: true }
[2022-10-14T16:58:13Z INFO  naga::front::spv] Generated by 524298 version 10000
[2022-10-14T16:58:13Z WARN  naga::front::spv] Unknown decoration Block
[2022-10-14T16:58:13Z WARN  naga::front::spv] Unknown decoration Block
[2022-10-14T16:58:13Z INFO  naga::front::spv] Patching...
[2022-10-14T16:58:13Z INFO  naga::front::spv] Generated by 524298 version 10000
[2022-10-14T16:58:13Z WARN  naga::front::spv] Unknown decoration Block
[2022-10-14T16:58:13Z INFO  naga::front::spv] Patching...
[2022-10-14T16:58:13Z INFO  wgpu_core::device] Created render pipeline Valid((0, 1, Vulkan)) with RenderPipelineDescriptor { label: Some("show-image-pipeline"), layout: Some((0, 1, Vulkan)), vertex: VertexState { stage: ProgrammableStageDescriptor { module: (0, 1, Vulkan), entry_point: "main" }, buffers: [] }, primitive: PrimitiveState { topology: TriangleList, strip_index_format: None, front_face: Cw, cull_mode: Some(Back), unclipped_depth: false, polygon_mode: Fill, conservative: false }, depth_stencil: None, multisample: MultisampleState { count: 1, mask: 18446744073709551615, alpha_to_coverage_enabled: false }, fragment: Some(FragmentState { stage: ProgrammableStageDescriptor { module: (1, 1, Vulkan), entry_point: "main" }, targets: [Some(ColorTargetState { format: Bgra8Unorm, blend: Some(BlendState { color: BlendComponent { src_factor: SrcAlpha, dst_factor: OneMinusSrcAlpha, operation: Add }, alpha: BlendComponent { src_factor: One, dst_factor: OneMinusSrcAlpha, operation: Add } }), write_mask: RED | GREEN | BLUE | ALPHA | COLOR | ALL })] }), multiview: None }
[2022-10-14T16:58:13Z INFO  wgpu_core::device] configuring surface with SurfaceConfiguration { usage: RENDER_ATTACHMENT, format: Bgra8Unorm, width: 800, height: 600, present_mode: AutoVsync }
[2022-10-14T16:58:13Z INFO  wgpu_core::device] Automatically choosing presentation mode by rule AutoVsync. Chose Fifo
[2022-10-14T16:58:13Z INFO  wgpu_core::device] Created buffer Valid((0, 1, Vulkan)) with BufferDescriptor { label: None, size: 64, usage: COPY_DST | UNIFORM, mapped_at_creation: true }
[2022-10-14T16:58:13Z INFO  wgpu_core::device] configuring surface with SurfaceConfiguration { usage: RENDER_ATTACHMENT, format: Bgra8Unorm, width: 1858, height: 1020, present_mode: AutoVsync }
[2022-10-14T16:58:13Z WARN  wgpu_core::device] Requested size 1858x1020 is outside of the supported range: Extent3d { width: 800, height: 600, depth_or_array_layers: 1 }..=Extent3d { width: 800, height: 600, depth_or_array_layers: 1 }
[2022-10-14T16:58:13Z INFO  wgpu_core::device] Automatically choosing presentation mode by rule AutoVsync. Chose Fifo
[2022-10-14T16:58:13Z INFO  wgpu_core::device] configuring surface with SurfaceConfiguration { usage: RENDER_ATTACHMENT, format: Bgra8Unorm, width: 800, height: 600, present_mode: AutoVsync }
[2022-10-14T16:58:13Z INFO  wgpu_core::device] Automatically choosing presentation mode by rule AutoVsync. Chose Fifo
[2022-10-14T16:58:13Z INFO  wgpu_core::device] configuring surface with SurfaceConfiguration { usage: RENDER_ATTACHMENT, format: Bgra8Unorm, width: 800, height: 600, present_mode: AutoVsync }
[2022-10-14T16:58:13Z INFO  wgpu_core::device] Automatically choosing presentation mode by rule AutoVsync. Chose Fifo
[2022-10-14T16:58:13Z INFO  wgpu_core::device] Created buffer Valid((1, 1, Vulkan)) with BufferDescriptor { label: Some("Untitled_uniforms_buffer"), size: 20, 
usage: UNIFORM, mapped_at_creation: true }
[2022-10-14T16:58:13Z INFO  wgpu_core::device] Created buffer Valid((2, 1, Vulkan)) with BufferDescriptor { label: Some("Untitled_image_buffer"), size: 479452, usage: STORAGE, mapped_at_creation: true }
[2022-10-14T16:58:13Z INFO  wgpu_core::device] Created buffer Valid((3, 1, Vulkan)) with BufferDescriptor { label: None, size: 64, usage: COPY_SRC, mapped_at_creation: true }

Panic on wayland

I am using weston with xwayland. When trying to run my program I get

thread 'main' panicked at 'failed to initialize global context: NoSuitableAdapterFound(NoSuitableAdapterFound)', /home/julius/.cargo/registry/src/github.com-1ecc6299db9ec823/show-image-0.8.4/src/backend/mod.rs:61:40
stack backtrace:
   0: rust_begin_unwind
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/panicking.rs:92:14
   2: core::option::expect_none_failed
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/option.rs:1329:5
   3: show_image::backend::run_context
   4: main::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Could it be that wayland is not supported? I am wondering why xwayland does not work..

Panic when minimizing on Windows due to invalid swapchain size

Hi!

On Windows minimizing an image_show window causes a panic deep within wgpu:

'Error in Device::create_swap_chain: Both SwapChain width and height must be non-zero. Wait to recreate the SwapChain until the window has non-zero area.'

Minimized windows seem to have a size of 0,0 which isn't a valid swapchain size.

Repro code (basically the example from the readme)
extern crate show_image;
use show_image::{ImageView, ImageInfo, create_window, event};

#[show_image::main]
fn main() -> Result<(), Box<dyn std::error::Error>> {
  let size = 512;

  let mut pixel_data = Vec::new();
  pixel_data.resize(size * size, 0_u8);

  let image = ImageView::new(ImageInfo::rgb8(size as u32, size as u32), pixel_data.as_slice());

  let window = create_window("image", Default::default())?;
  window.set_image("image-001", &image)?;

  for event in window.event_channel()? {
      if let event::WindowEvent::KeyboardInput(event) = event {
          println!("{:#?}", event);
          if event.input.key_code == Some(event::VirtualKeyCode::Escape) && event.input.state.is_pressed() {
              break;
          }
      }
  }

  Ok(())
}

Why is it a bad idea to base a GUI on this crate?

Hi there!

First of all, thank you so much for the awesome crate! You handle so many things already!

I am kind of new to GUI development, so this might be an ignorant question but, why should I not base a GUI on this crate?

You mention quite early in the README "The library is not intended for making full-featured GUIs, but you can process keyboard events from the created windows.", could you elaborate what would be the challenges?

That is all!
Thanks again!

Show-image application works fine except armbian

My mandelbrot navigator is working fine on Ubuntu20.04 x86_64 and Windows 10.
Mouse interactive function works well.
However in armbian os , application fails while other Rust application works fine in armbian.
Of course this is not so important for me. FYI

thread 'main' panicked at 'failed to initialize global context: NoSuitableAdapterFound(NoSuitableAdapterFound)', /home/rock64/.cargo/registry/src/github.com-1ecc6299db9ec823/show-image-0.9.5/src/backend/mod.rs:61:40
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

mandel
madel1

How to convert `ImageBuffer<Rgb<u8>, Vec<u8>>` to this crate `window.set_image(...,image)`

I mean for the 2ed example in crates.io:

use show_image::{event, create_window};

// Create a window and display the image.
let window = create_window("image", Default::default())?;
window.set_image("image-001", &image)?;

// Print keyboard events until Escape is pressed, then exit.
// If the user closes the window, the channel is closed and the loop also exits.
for event in window.event_channel()? {
  if let event::WindowEvent::KeyboardInput(event) = event {
        println!("{:#?}", event);
        if event.input.key_code == Some(event::VirtualKeyCode::Escape) && event.input.state.is_pressed() {
            break;
        }
    }
}

I wonder how to convert an ImageBuffer from Image to the 2ed param of window.set_image("image-001", &image)?; here?

Problems setting background color

Hi!

Sorry if I am using wrongly the crate, but could you give an example of changing the background color (maybe in examples?). I am afraid I can not make it work on my computer (running Windows).

I would like to change the transparency of the background. I am doing something like this

window.run_function_wait(|mut window| {
    let mut background_color = window.background_color();
    background_color.alpha = background_color.alpha + 0.1;
    if background_color.alpha > 1.0 {
        background_color.alpha = 0.0;
    }
    window.set_background_color(background_color);
})?;

This is inside a reaction to a Tab key.

I am sure this code runs, but it does not produce any change in the image, even when the background_color.alpha correctly cycles.

Images are cropped by 0.5 pixels

I am working with low resolution images and noticed a strange behavior.

cropped_image

use show_image::{create_window, event};
use image::{ImageBuffer, Rgb};

#[show_image::main]
fn main() -> Result<(), Box<dyn std::error::Error>> {

    let mut img = ImageBuffer::from_pixel(16, 16, Rgb([255, 255, 255]));
    img.put_pixel(0, 0, Rgb([0, 0, 255]));
    img.put_pixel(2, 0, Rgb([0, 0, 255]));
    img.put_pixel(0, 2, Rgb([0, 0, 255]));
    img.put_pixel(2, 2, Rgb([0, 0, 255]));

    // Create a window with default options and display the image.
    let window = create_window("image", Default::default())?;
    window.set_image("image-001", img)?;

    for event in window.event_channel()? {
        if let event::WindowEvent::KeyboardInput(event) = event {
            if event.input.key_code == Some(event::VirtualKeyCode::Escape) && event.input.state.is_pressed() {
                break;
            }
        }
    }

    Ok(())
}

use of undeclared crate or module `image`

Hello

I am trying to learn rust and I came up to your repo while searching how to show images. I made a package using cargo new and copied the code example show-image.rs. On a cargo build I keep getting the error:

error[E0433]: failed to resolve: use of undeclared crate or module image
--> src/main.rs:9:14
|
9 | let image = image::open(path).map_err(|e| format!("Failed to read image from {:?}: {}", path, e))?;
| ^^^^^ use of undeclared crate or module image

In my Cargo.toml I have only show-image = "0.12.3".

I have also tried to add crate image with the version = "0.24.1" as a dependency, but it didn't help. Cargo for some reason updated the version to 0.24.3 and it solved the previous error but the new error occured:

11 | let image_info = show_image::image_info(&image).map_err(|e| e.to_string())?;
| ---------------------- ^^^^^^ the trait AsImageView is not implemented for DynamicImage
| |
| required by a bound introduced by this call

Cargo version is 1.62.1

I am not sure if adding the image crate into the Cargo.toml is a step forward or the problem is in image crate version, if so why is cargo updating it? What is the point of defining the version if cargo is going to update it anyway...
Can you point me to right direction?

Intermittent error on startup,

Running a simple sample on Windows, I sometimes get an error on startup, it isn't all that easy to repro:

Finished release [optimized] target(s) in 9.60s
 Running `target\release\examples\ilbm_view.exe S:\IFF\RAYTRACE_HAM\SKYSCRAPE2.I24`

thread 'main' panicked at 'called Result::unwrap() on an Err value: "failed to receive CreateWindow result from context thread: the value of the oneshot channel is not available yet"', examples\ilbm_view.rs:31:43
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
error: process didn't exit successfully: target\release\examples\ilbm_view.exe S:\IFF\RAYTRACE_HAM\SKYSCRAPE2.I24 (exit code: 101)

My usage of show_image is very simple, it fails on the first call which looks like this:

 let window = make_window("ILBM View").unwrap();

show_image::make_window does not work in macOS

This crate is very useful. Thank you for creating it!

I tried to show image in macOS and got the following error.

ywr@mbp:~/show-image-rs$ cargo run --example show-image cat.jpg
    Finished dev [unoptimized + debuginfo] target(s) in 0.09s
     Running `target/debug/examples/show-image cat.jpg`
Ok(
    ImageInfo {
        width: 256,
        height: 256,
        row_stride: 768,
        pixel_format: Rgb8,
    },
)
2020-06-17 01:10:42.263 show-image[31826:286727] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'nextEventMatchingMask should only be called from the Main Thread!'
*** First throw call stack:
(
        0   CoreFoundation                      0x00007fff36713be7 __exceptionPreprocess + 250
        1   libobjc.A.dylib                     0x00007fff6f4eb5bf objc_exception_throw + 48
        2   AppKit                              0x00007fff3390bb65 +[NSEvent _discardTrackingAndCursorEventsIfNeeded] + 0
        3   libSDL2-2.0.0.dylib                 0x000000010f13f24a Cocoa_PumpEvents + 116
        4   libSDL2-2.0.0.dylib                 0x000000010f0b21ce SDL_PumpEvents_REAL + 23
        5   libSDL2-2.0.0.dylib                 0x000000010f0b2238 SDL_WaitEventTimeout_REAL + 44
        6   show-image                          0x000000010ea26d4e _ZN4sdl25event10poll_event17h5f8eaf8e994cfe2aE + 62
        7   show-image                          0x000000010ea34408 _ZN4sdl25event38_$LT$impl$u20$sdl2..sdl..EventPump$GT$10poll_event17h548f6d02599e4ecaE + 24
        8   show-image                          0x000000010e705bf7 _ZN10show_image7backend3sdl12ContextInner7run_one17h4700e0c29aa13a4bE + 167
        9   show-image                          0x000000010e7059be _ZN10show_image7backend3sdl12ContextInner3run17h9e2570d5529461d4E + 174
        10  show-image                          0x000000010e6dc78c _ZN10show_image7backend3sdl7Context3new28_$u7b$$u7b$closure$u7d$$u7d$17h2fe589dec5da9bd5E + 348
        11  show-image                          0x000000010e70c071 _ZN10show_image17background_thread25BackgroundThread$LT$T$GT$3new28_$u7b$$u7b$closure$u7d$$u7d$17hb818174416b6eff1E + 65
        12  show-image                          0x000000010e6da2f7 _ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h9c1d07224a66e808E + 55
        13  show-image                          0x000000010e6eff57 _ZN3std6thread7Builder15spawn_unchecked28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17h585f5fd6720a9ce5E + 55
        14  show-image                          0x000000010e6da3c7 _ZN101_$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$9call_once17h48a839c8dc36cf2eE + 55
        15  show-image                          0x000000010e6f9a8c _ZN3std9panicking3try7do_call17h368ff18c4c8902daE + 108
        16  show-image                          0x000000010e6f9c7d __rust_try + 29
        17  show-image                          0x000000010e6f994c _ZN3std9panicking3try17hd1c05ae424e6fbc8E + 236
        18  show-image                          0x000000010e6da417 _ZN3std5panic12catch_unwind17h92a05365424b3e5aE + 55
        19  show-image                          0x000000010e6efd7e _ZN3std6thread7Builder15spawn_unchecked28_$u7b$$u7b$closure$u7d$$u7d$17h2e8bbde1bbc2dcbdE + 318
        20  show-image                          0x000000010e6d35f1 _ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17h1239f50068b602f1E + 17
        21  show-image                          0x000000010ea521ad _ZN3std3sys4unix6thread6Thread3new12thread_start17h2b28b74d30bce841E + 45
        22  libsystem_pthread.dylib             0x00007fff70897109 _pthread_start + 148
        23  libsystem_pthread.dylib             0x00007fff70892b8b thread_start + 15
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Abort trap: 6

Error, panics, then segfault

On Wayland Gnome Ubuntu 21.10 with Nvidia driver 510 on hybrid GPU:

user@host:show-image-rs$ cargo run --example show-image test.png
MESA-INTEL: warning: Performance support disabled, consider sysctl dev.i915.perf_stream_paranoid=0

ImageInfo {
    pixel_format: Rgba8(
        Unpremultiplied,
    ),
    size: UVec2(
        1920,
        1080,
    ),
    stride: UVec2(
        4,
        7680,
    ),
}
[2022-03-21T21:57:35Z ERROR smithay_client_toolkit::window::concept_frame] No font could be found
thread 'main' panicked at 'Error in Surface::configure: surface does not support the adapter's queue family', /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.11.0/src/backend/direct.rs:204:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread '<unnamed>' panicked at 'global context failed to send function return value back, which can only happen if the event loop stopped, but that should also kill the process: Disconnected', /home/user/develop/show-image-rs/src/backend/proxy.rs:144:14
Segmentation fault (core dumped)

Memory overflow after repeated updates

Hello, I was using this crate to draw frames from a simulation and ran into some sort of memory overflow. I'm pretty new to Rust, so it may be my fault, but the following example causing memory usage to grow continuously until it crashes:

    let mut window = create_window("image", Default::default()).unwrap();
    loop {
        let mut img: ImageBuffer<Rgb<u8>, Vec<u8>> = ImageBuffer::new(WIDTH, WIDTH);
        for (x, y, pixel) in img.enumerate_pixels_mut() {
            *pixel = Rgb([(x + y) as u8 % 255u8, 0, 0]);
        }
        window.set_image("image-001", img).unwrap();
    }

Any help would be appreciated

Fullscreen view

I would like to display image in a fullscreen window but it seems not to be possible. I also struggle to get information from the current monitor the window is displayed on (e.g. the max. Resolution).

show-image itself seems not to provide monitor information and all instances of the underlying winit window are private and cannot be accessed.

Is there a way to make the window fullscreen either directly or by getting the screen resolution and setting the window's size accordingly?

How to get window.inner_size() from WindowProxy object

Hi,
I am creating a Mandelbrot and Julia set navigator by using show-image crate.
Showing Julia set in multiple windows works well.
Nice crate !!!
I am implementing mouse interactive function to navigate the set.
Created windows size are re-sizable.
I want to get the inner window size from the current active window.
I feel the current show-image source tree are not well implemented for that purpose.
Let me know the advice.

let mut window = create_window("image", Default::default())?
Screenshot from 2021-11-11 15-28-07
;

`run_window_event_handlers` panics when window is destroyed.

I wrote the following code to close the window when any key is pressed:

window.run_function(|mut window| {
    use show_image::event::WindowEvent;
    window.add_event_handler(|w, e, eh| {
        match e {
            WindowEvent::KeyboardInput(_) | WindowEvent::TextInput(_) => {
                w.destroy();
                eh.remove_handler = true;
                eh.stop_propagation = true;
            }
            _ => {}
        }
    })
});

After the handler's execution, the window becomes invalid, but the subsequent code in src/backend/context.rs line 659 will try to access the window, leads to panicking:

RetainMut::retain_mut(&mut event_handlers, |handler| {
	if stop_propagation {
		false
	} else {
		let context_handle = ContextHandle::new(self, event_loop);
		let window_handle = WindowHandle::new(context_handle, window_index);
		let mut control = EventHandlerControlFlow::default();
		(handler)(window_handle, event, &mut control);
		stop_propagation = control.stop_propagation;
		!control.remove_handler
	}
});
// Access outbound!
let new_event_handlers = std::mem::take(&mut self.windows[window_index].event_handlers);

Failing to build

cargo run returns this error: error: failed to run custom build command for servo-fontconfig-sys v5.1.0
Operating system: Fedora 37

Example 1 doesn't work

Yours "Example 1. Showing an image" doesn't work.

use show_image::{ImageView, ImageInfo, create_window};

#[show_image::main]
fn main() -> Result<(), Box<dyn std::error::Error>> {

  let image = ImageView::new(ImageInfo::rgb8(1920, 1080), pixel_data);

  // Create a window with default options and display the image.
  let window = create_window("image", Default::default())?;
  window.set_image("image-001", image)?;

  Ok(())
}

What is "pixel_data" and how to get it?

Black Screen

When running examples, the window only contains solid black, no image.
MacOS Big Sur
iMac Pro 2017

No longer works with the latest version (0.25.0) of image crate

Steps to reproduce

cargo init
cargo add image
cargo add show_image -F image
use image::*;
use show_image::*;

#[show_image::main]
fn main() -> Result<(), Box<dyn std::error::Error>>
{
    let img = RgbImage::new(512, 512);
    let window = create_window("Hi", Default::default())?;
    window.set_image("Hi", img)?;
    window.wait_until_destroyed()?;

    Ok(())
}
error[E0277]: the trait bound `Image: From<ImageBuffer<Rgb<u8>, Vec<u8>>>` is not satisfied
   --> src\main.rs:9:28
    |
9   |     window.set_image("Hi", img)?;
    |            ---------       ^^^ the trait `From<ImageBuffer<Rgb<u8>, Vec<u8>>>` is not implemented for `Image`
    |            |
    |            required by a bound introduced by this call       
    |
    = help: the following other types implement trait `From<T>`:   
              <Image as From<std::boxed::Box<(dyn AsImageView + Send + 'static)>>>
              <Image as From<std::boxed::Box<T>>>
              <Image as From<ImageView<'_>>>
              <Image as From<BoxImage>>
              <Image as From<ArcImage>>
              <Image as From<image::buffer_::ImageBuffer<P, Container>>>
              <Image as From<image::dynimage::DynamicImage>>       
              <Image as From<std::sync::Arc<(dyn AsImageView + Send + Sync + 'static)>>>
            and 2 others
    = note: required for `ImageBuffer<Rgb<u8>, Vec<u8>>` to implement `Into<Image>`
note: required by a bound in `WindowProxy::set_image`
   --> C:\Users\Kendall\.cargo\registry\src\index.crates.io-6f17d22bba15001f\show-image-0.13.1\src\backend\proxy.rs:265:63
    |
265 | ...ng>, image: impl Into<Image>) -> Result<(), SetImageEr... 
    |                     ^^^^^^^^^^^ required by this bound in `WindowProxy::set_image`

For more information about this error, try `rustc --explain E0277`.

Workaround

Change the image dependency in Cargo.toml to image = "0.24.*"

windows support?

no font-kit/fontconfig on windows.

      Adding show-image v0.13.1 to dev-dependencies.
             Features:
             + macros
             + show-image-macros
             - doc-only
             - full
             - image
             - log
             - nightly
             - png
             - raqote
             - save
             - tch
             - tinyfiledialogs
    Updating crates.io index
error: failed to select a version for `yeslogic-fontconfig-sys`.
    ... required by package `font-kit v0.11.0`
    ... which satisfies dependency `font-kit = "^0.11.0"` of package 
versions that meet the requirements `^3.0.0` are: 3.2.0, 3.1.0, 3.0.1, 3.0.0

the package `yeslogic-fontconfig-sys` links to the native library `fontconfig`, but it conflicts with a previous package which links to `fontconfig` as well:
package `servo-fontconfig-sys v5.1.0`
    ... which satisfies dependency `servo-fontconfig-sys = "^5.1.0"` of package `servo-fontconfig v0.5.1`
    ... which satisfies dependency `servo-fontconfig = "^0.5.1"` of package `crossfont v0.5.0`
    ... which satisfies dependency `crossfont = "^0.5.0"` of package `sctk-adwaita v0.4.1`
    ... which satisfies dependency `sctk-adwaita = "^0.4.1"` of package `winit v0.27.3`
    ... which satisfies dependency `winit = "^0.27.3"` of package `show-image v0.13.1`
    ... which satisfies dependency `show-image = "^0.13.1"` of package `rust_mpv v0.1.0 (C:\w\rust_mpv)`
Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the links ='yeslogic-fontconfig-sys' value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.

failed to select a version for `yeslogic-fontconfig-sys` which could resolve this conflict

show-image panics in unit tests

I'm trying to show an image in a unit test for debugging purposes.

mod tests {
use show_image::{create_window, WindowOptions, run_context, main};
use show_image::tch::TensorAsImage;

#[test]
fn test() {
    test_main()
}

#[main]
fn test_main()  {
    let window = create_window("image", WindowOptions::default()).unwrap();
    window.set_image("image-001",  tch::vision::image::load("image-001.jpg").unwrap().as_image_guess_rgb()).unwrap();
    println!("Done!");
}
}

This short snippet results in this panic:

panicked at 'Initializing the event loop outside of the main thread is a
significant cross-platform compatibility hazard.
If you really, absolutely need to create an EventLoop on a different thread,
please use the `EventLoopExtWindows::new_any_thread` function.

I believe this is a winit error relating to starting windows in secondary threads. I think this is because cargo runs each unit test in a separate thread. Is there a way to get show-image to work in unit tests or secondary threads?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.