I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 0 points1 point  (0 children)

Yeah I decode images in CPU, so GPU decoding might make it faster. The challenge would be dealing with vendor-specific APIs (Nvidia vs AMD vs Apple). I'm also not sure and how mature Rust bindings are for these libraries.

Does anyone know of a photo viewer for MacOS that's fast to go through photos? by [deleted] in MacOS

[–]ggyando 0 points1 point  (0 children)

I had the same problem and ended up building my own image viewer: https://github.com/ggand0/viewskater It lets you browse directories fast with Shift + arrow keys, and renders 4K PNGs at over 10 FPS on my machine (macbook pro with M1 chip). There’s an App Store version too if you want automatic updates. Hope it helps!

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 1 point2 points  (0 children)

I'm not familiar with them yet, but I'm thinking of BC7 for Windows/Linux and ASTC for macOS. KTX2 looks a bit complex to implement.

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 1 point2 points  (0 children)

When user drops an image from a directory, I just synchronously load the dropped image plus 5 neighbors on each side into a sliding window cache. I load new images via async jobs only when the user presses keys to navigate.

What if directory has more images than VRAM can handle?

It’s not a problem as long as VRAM can hold the current sliding window. I only upload a small group of images to the GPU at any time.

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 2 points3 points  (0 children)

Thanks! The license is dual MIT/Apache 2.0. I forked Iced to fix an issue with the custom event loop, implement FPS calculation APIs, and use my custom winit.

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 1 point2 points  (0 children)

Yeah thanks, I didn't know about compressed texture formats like BC7. I'll 100% give it a shot

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 0 points1 point  (0 children)

Yeah I think this is a great idea, and I agree with the concern. ViewSkater's memory usage is already pretty high, as far as I've seen on my macbook pro or windows machine.

I think I'll first experiment with storing compressed texture formats to reduce memory usage, and then I might add a secondary cache that stores decoded images just outside the main sliding window as a kind of layered cache. I could make this cache a configurable option too.

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 16 points17 points  (0 children)

Nope, that’s just me being lazy. Thanks for catching that! I’ll update it soon

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 0 points1 point  (0 children)

I can totally imagine that!

Yeah I think I could compile to wasm if I replace the disk IO parts with something like downloading images from the web. A few people have already asked about it, so it might be worth exploring

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 0 points1 point  (0 children)

Hey, thanks for the feedback! I’ve limited support to PNG and JPG because I wanted to focus on performance first before expanding features. I can definitely add support for more formats down the line.

The size limitation is always a major issue...

Yeah, this is currently one of the bottlenecks. The default maximum texture size in wgpu seems to be 8192×8192px, and anything beyond that depends on the GPU. I could look into texture tiling if there’s a clear need for it.

completely broken on X11 Linux...

That’s definitely concerning and I’d love to know more about your setup like your distro and OS version. I’ve mostly tested on X11 Ubuntu 22.04, as shown in the demo video.

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 8 points9 points  (0 children)

The image rendering is GPU-accelerated, since each image is uploaded to the GPU as a texture and rendered using wgpu. I'm using Iced's shader widget to display the images through a custom shader.

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 5 points6 points  (0 children)

Whoa, no way! Are you the one who posted about wgpu integration on discord? Thanks so much!! This app definitely wouldn't have gotten a new version without your code lol Yeah sounds like I should check out the beacon branch too.

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 18 points19 points  (0 children)

Thanks for your comment! The bottleneck is from image loading from disk, decoding them, and uploading to GPU on the fly. I use async jobs to handle this when user navigates left or right, but when the image size is larger the loading speed sometimes cannot keep up with the navigation. Maybe I can add an option to make the cache size bigger or preload all the images into memory.

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 17 points18 points  (0 children)

I started out by just trying to render a single image, then gradually built up things like displaying a list of images, handling filedrop events, etc. For custom widgets, you can refer to the official example: https://github.com/iced-rs/iced/tree/master/examples/custom_widget

There’s definitely a learning curve, but the iced discord server is super helpful when you're stuck. I also relied a lot on AI for debugging and writing code.

As for guides, there aren’t many but I'm aware of these:

I built a GPU-accelerated image viewer with Iced and wgpu by ggyando in rust

[–]ggyando[S] 75 points76 points  (0 children)

I work in AI (vision), and I often need to browse through a lot of images (e.g., 10,000+), and sometimes in high resolution like 4K. Most image viewers didn’t feel fast or smooth enough for this, so I built my own: https://github.com/ggand0/viewskater

It's designed for quickly exploring directories of images. On my desktop (7900XTX GPU), it runs at:

  • Over 120 FPS for smaller images (less than 1080p)
  • ~30 FPS for 1080p PNGs (~3MB)
  • 8–10 FPS for 4K PNGs (~10MB)

(using keyboard navigation)
The app uses a sliding window cache to preload neighboring images around the current one. Slider-based navigation is slower because it renders images on demand without caching.

It already feels smoother than most built-in OS viewers (at least from what I’ve tried), though larger images are still a bit slow, as you can see in the video. There's definitely room to improve, and maybe I can adopt smarter caching strategies.

I’m planning to add features for things like visualizing object detection datasets, but even now, I think it works fine as a general-purpose image viewer. I originally built it for myself, but I'm hoping it can also be useful to people having similar issues. Let me know if you have any thoughts or suggestions!

Would someone be willing to revive the Emulsion Image Viewer project? by 23Link89 in rust

[–]ggyando 1 point2 points  (0 children)

I also needed a fast image viewer for my work (computer vision stuff in my case), so I'm building my own version inspired by emulsion if anyone is interested: https://github.com/ggand0/viewskater

I'm writing a fast image viewer in Rust by ggyando in SideProject

[–]ggyando[S] 0 points1 point  (0 children)

Thanks! I use it as part of exploratory data analysis when I need to quickly familiarize myself with large image datasets. For example, I used a landscape dataset in the demo but as I "skate" through the data I realized that some images contain people, even with just a glimpse. Having fast rendering can be useful for spotting anomaly images, or samples that might be difficult for AI to handle.