Here is a small script that you can run with AutoHotKey.
AutoHotKey is a nice program which allows one to write scripts using an approachable language, then compile them into executables. Simply paste this code into a txt file, rename it to a .ahk file, then run or compile it with AutoHotKey.
It will ask you to choose a folder, then it will create an ini file with 5 configurable settings, plus a txt file containing the names of files viewed with the script.
You can then press a key to open a random file from the chosen folder, or a back key and forward key to browse files already viewed.
Unfortunately it does not close previous windows when opening a new one. For this reason it works well with JPEGView when you have JPEGView set to have only one window open at a time.
!!! Remember to exit the script from its taskbar icon when you're done, or you may accidentally open a file with it when you don't want to !!!
#Requires AutoHotkey v2.0 ;----- ;BEGIN STARTUP ;----- ToolTip "Starting up", 0, A_ScreenHeight startup := 0 ; define variable to denote the completion of startup processes processing := 0 ; define variable to denote the completion of hotkey processes extensions := "" CoordMode "ToolTip" SetTitleMatchMode 2 ;----- ;READ THE SETTINGS FILE TO FIND THE IMAGE FOLDER AND FILE TYPES TO WORK WITH, AS WELL AS HOTKEYS ;----- SetWorkingDir A_ScriptDir ; set the script's working directory to the script's directory doesFileExist := FileExist("ViewRandomImage Settings.ini") ; check if the settings ini file exists. if not, create an ini file with default settings if (doesFileExist = "") { FileAppend "[Settings]`nIMAGE_FOLDER=`nFILE_TYPES=png jpg jpeg gif`nRANDOM_IMAGE=Numpad0`nBROWSE_BACKWARD=Numpad4`nBROWSE_FORWARD=Numpad6", "ViewRandomImage Settings.ini" } imageFolder := IniRead("ViewRandomImage Settings.ini", "Settings", "IMAGE_FOLDER", 0) ; read the IMAGE_FOLDER key of the settings file to "imageFolder" if (InStr(imageFolder, ":\") = 0) OR (imageFolder = 0) ; if the key does not have ":\" or if the reading otherwise failed, then it is likely not a valid entry { imageFolder := DirSelect(, 2, "ViewRandomImage - Select Image Folder") ; ask user to select a folder IniWrite imageFolder, "ViewRandomImage Settings.ini", "Settings", "IMAGE_FOLDER" ; write the selected folder directory to the settings file } extensions := IniRead("ViewRandomImage Settings.ini", "Settings", "FILE_TYPES", 0) ; read the FILE_TYPES key of the settings file to "extensions" randomImageKey := IniRead("ViewRandomImage Settings.ini", "Settings", "RANDOM_IMAGE", 0) ; read the hotkey keys of the settings file Hotkey randomImageKey, randomImage ; and set them to function names with the Hotkey function browseBackwardKey := IniRead("ViewRandomImage Settings.ini", "Settings", "BROWSE_BACKWARD", 0) Hotkey browseBackwardKey, browseBackward browseForwardKey := IniRead("ViewRandomImage Settings.ini", "Settings", "BROWSE_FORWARD", 0) Hotkey browseForwardKey, browseForward SetWorkingDir imageFolder ; set the script's working directory from "imageFolder" ;----- ;STORE PATHS OF FILES WITH MATCHING FILE TYPES IN AN ARRAY ;----- Filearray := [] ; define an array which will be filled with file directories Loop Files "*" ; loop through all files in the working directory, with the filename as a wildcard { if InStr(extensions, A_LoopFileExt) ; if the extension of a file is present in the "extensions "string Filearray.push(A_LoopFileFullPath) ; then place the file directory at the end of the variable Filearray } total := Filearray.Length ; now that all files have been looped through, define a variable called "total" equal to the highest index of the array doesFileExist := FileExist(A_ScriptDir . "\FilesViewed.txt") ; check if the FilesViewed text file exists if (doesFileExist = "") { FileAppend "", A_ScriptDir . "\FilesViewed.txt" ; if not, create a blank text file } FilesViewedArray := [] ; define an array which will be filled with file names that this script stores in "Files Viewed.txt" Loop Read A_ScriptDir . "\FilesViewed.txt" ; loop through FilesViewed.txt { FilesViewedArray.Push(A_LoopReadLine) ; and assign each line to FilesViewedArray ToolTip "Starting up: Reading FilesViewed " . A_LoopReadLine, 0, A_ScreenHeight } filesViewedIndex := FilesViewedArray.Length ; assign the length of the array to a variable that will act as a "cursor" for backward and forward navigation of the FilesViewed list startup := 1 ToolTip "Starting up: Done" . A_LoopReadLine, 0, A_ScreenHeight ; denote the completion of startup SetTimer () => ToolTip(), -1000 ;Tooltip filesViewedIndex ;----- ;END STARTUP ;----- ;----- ;OPEN RANDOM IMAGE HOTKEY ;----- randomImage(ThisHotKey) { global processing ; allow this hotkey block to use the global variables initialised at startup global startup global filesViewedIndex if (processing = 0) && (startup = 1) ; check if another processing is occuring { processing := 1 randomNum := Random(1, total) ; create a variable equal to a randomly generated integer between 1 and the total number of entries in FilesViewed.txt SplitPath Filearray[randomNum], &FileChosen ; assign the filename of the path found at array index "randomNum" to the variable "fileChosen" for later use FilesViewedList := FileRead(A_ScriptDir . "\FilesViewed.txt") ; define a string called "FilesViewedList" containing the entirety of filesviewed.txt While InStr(FilesViewedList, FileChosen) > 0 ; as long as "fileChosen" appears in "filesViewedList" - { randomNum := Random(1, total) ; continue choosing random files SplitPath Filearray[randomNum], &FileChosen ; and assigning their filenames to "fileChosen" like before } Run Filearray[randomNum] ; run the file from the FileAppend(FileChosen . "`n", A_ScriptDir . "\FilesViewed.txt") ; finally, add the filename stored in "fileChosen" to the .txt list of viewed files FilesViewedArray.Push(FileChosen) filesViewedIndex := FilesViewedArray.Length ; Tooltip filesViewedIndex processing := 0 } return } ;----- ;BROWSE BACKWARD HOTKEY ;----- browseBackward(ThisHotKey) { global processing ; make global variables useable in this hotkey block global startup global filesViewedIndex if (processing = 0) && (startup = 1) ; check if no process is occuring { processing := 1 if filesViewedIndex > 1 ; if the browsing cursor is further than the first entry in FilesViewed.txt { filesViewedIndex -= 1 ; set the cursor back one Run FilesViewedArray[filesViewedIndex] ; run the file at the new cursor position ; Tooltip filesViewedIndex } processing := 0 } return } ;----- ;BROWSE FORWARD HOTKEY ;----- browseForward(ThisHotKey) { global processing global startup global filesViewedIndex if (processing = 0) && (startup = 1) { processing := 1 if filesViewedIndex < FilesViewedArray.Length { filesViewedIndex += 1 Run FilesViewedArray[filesViewedIndex] ; Tooltip filesViewedIndex } processing := 0 } return }
The default settings of the ini file are as follows.
You can change them to any hotkey name used by AutoHotKey
(e.g. "b" for the B key, "1" for the 1 key, "Space" "Tab" "Enter" "Alt" "Left" "Right" etc.)
[Settings] IMAGE_FOLDER= FILE_TYPES=png jpg jpeg gif RANDOM_IMAGE=Numpad0 BROWSE_BACKWARD=Numpad4 BROWSE_FORWARD=Numpad6