Image viewer using MiniFB
This example displays the PNG files in a directory, rotating through the available images on each mouse click.
This code needs Images.jl and ImageTransformations.jl. Add those packages to your environment before proceeding
using Images
using ImageTransformations
using MiniFB
Set the size of the window
global const WIDTH = 600
global const HEIGHT = 400
Global state
global ni = 1
global num_images = 1
A function that will be called when a mouse button is clicked. It simply rotates the current image by storing a global integer.
function onclick(window, button, mod, isPressed)::Cvoid
global ni, num_images
if Bool(isPressed)
if ni < num_images
ni = ni+1
else
ni = 1
end
end
return nothing
end
The callback needs to be passed to the C library. The @cfunction macro creates a
onclick_c = @cfunction(onclick, Cvoid, (Ptr{Cvoid}, mfb_mouse_button, mfb_key_mod, UInt8) )
Populate a MiniFB buffer from the image data. First, resize the image to the window dimensions. Calculate it's position so that it is centered in the window. Finally, inside the loop, convert each pixel to the 32 bit MiniFB buffer format.
function populate_buffer!(buffer, img)
global WIDTH, HEIGHT
buffer[:] = zeros(UInt32, HEIGHT*WIDTH)
h, w = size(img)
ratio = min(1, HEIGHT/h, WIDTH/w)
nimg = imresize(img, ratio=ratio)
nh, nw = size(nimg)
oh = (HEIGHT-nh) ÷ 2
ow = (WIDTH-nw) ÷ 2
for i in 1:nh
for j in 1:nw
buffer[(oh+i-1)*WIDTH + ow+j] = mfb_rgb(nimg[i,j])
end
end
end
This is the main function. It takes a directory, calls loadfiles
to get the image data. Creates the windows, and sets up the callback. Then, inside the while
loop, renders the buffer into the window. The mfb_update
not only renders the buffer, but also flushes the input event queue. The buffer is changed only when the state changes. The mfb_wait_sync
method enforces the required frame rate.
function imageview(dir::String=".")
global ni, num_images
images = loadfiles(dir)
num_images = length(images)
buffer = zeros(UInt32, HEIGHT*WIDTH)
mfb_set_target_fps(10)
window = mfb_open_ex("Image Viewer", WIDTH, HEIGHT, MiniFB.WF_RESIZABLE);
mfb_set_mouse_button_callback(window, onclick_c);
old_ni=0
while mfb_wait_sync(window)
if ni != old_ni
populate_buffer!(buffer, images[ni])
old_ni = ni
end
state = mfb_update(window, buffer);
if state != MiniFB.STATE_OK
break;
end
end
mfb_close(window)
end
Load the files from disk. Select all png files, and then use ImageIO to load them into memory.
function loadfiles(dir::String=".")
files = readdir(dir)
filter!(x->occursin(r"\.png"i, x), files)
[load(joinpath(dir,x)) for x in files]
end
Finally, call the main method to display the application
imageview(joinpath(dirname(pathof(MiniFB)),"..", "example"))