Skip to content
This repository was archived by the owner on Nov 17, 2023. It is now read-only.

Commit 15ca025

Browse files
committed
Initial commit
0 parents  commit 15ca025

12 files changed

+1846
-0
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Milan Nikolic <gen2brain@gmail.com>

COPYING

+674
Large diffs are not rendered by default.

README.md

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
## goiv
2+
3+
Small and simple image viewer written in pure Go.
4+
5+
6+
### Features
7+
8+
* Supports JPEG, PNG, GIF, BMP, PCX, TIFF, PBM, PGM, PPM, WEBP, PSD and TGA formats.
9+
* Scales images to window size and preserves aspect ratio.
10+
* Supports HTTP URLs passed as arguments
11+
* Cross-platform (note: on macOS you need to install [XQuartz](https://www.xquartz.org/)).
12+
13+
14+
### Download
15+
16+
- [Linux 64bit](https://github.com/gen2brain/goiv/releases/download/1.0/goiv-1.0-linux-64bit.tar.gz)
17+
- [Windows 32bit](https://github.com/gen2brain/goiv/releases/download/1.0/goiv-1.0-windows-32bit.zip)
18+
- [macOS 64bit](https://github.com/gen2brain/goiv/releases/download/1.0/goiv-1.0-darwin-64bit.zip)
19+
20+
21+
### Installation
22+
23+
go get -v github.com/gen2brain/goiv
24+
25+
26+
This will install app in `$GOPATH/bin/goiv`.
27+
28+
Note: On Windows you need to generate manifest .syso file, use this instead:
29+
30+
go get github.com/akavel/rsrc
31+
32+
go get -d github.com/gen2brain/goiv
33+
go generate github.com/gen2brain/goiv
34+
go install github.com/gen2brain/goiv
35+
36+
37+
### Keybindings
38+
39+
* j / Right / PageDown / Space
40+
Next image
41+
42+
* k / Left / PageUp
43+
Previous image
44+
45+
* f / F11
46+
Fullscreen
47+
48+
* [ / ]
49+
Go 10 images back/forward
50+
51+
* , / .
52+
Go to first/last image
53+
54+
* q / Escape
55+
Quit
56+
57+
* Enter
58+
Print current image path to stdout
59+
60+
61+
### Example usage
62+
63+
* View all images in a directory
64+
goiv /path/to/dir/*
65+
66+
* View all JPEG's in all subdirectories
67+
find . -iname "*.jpg" | goiv
68+
69+
* Delete current image when enter is pressed
70+
goiv * | xargs rm
71+
72+
* Rotate current image when enter is pressed
73+
goiv * | xargs -i convert -rotate 90 {} {}
74+
75+
76+
### Planned features
77+
78+
- [ ] draw in console on DRM/KMS and Framebuffer
79+
- [ ] flip image vertically/horizontally
80+
- [ ] rotate image 90 degrees clockwise/counter-clockwise

goiv.go

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"flag"
6+
"fmt"
7+
"io"
8+
"os"
9+
"path/filepath"
10+
"strings"
11+
)
12+
13+
const (
14+
appName = "goiv"
15+
appVersion = "1.0"
16+
)
17+
18+
func main() {
19+
flag.Usage = usage
20+
21+
width := flag.Int("w", 1024, "Window width")
22+
height := flag.Int("h", 768, "Window height")
23+
version := flag.Bool("v", false, "Print version and exit")
24+
filelist := flag.String("f", "", "Use list of images from file, one per line")
25+
26+
flag.Parse()
27+
28+
if *version {
29+
fmt.Fprintf(os.Stdout, "%s version %s\n", appName, appVersion)
30+
os.Exit(0)
31+
}
32+
33+
args := arguments(flag.Args())
34+
35+
if *filelist != "" {
36+
file, err := os.Open(*filelist)
37+
if err != nil {
38+
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
39+
os.Exit(1)
40+
}
41+
42+
ln := lines(file)
43+
args = append(args, ln...)
44+
45+
file.Close()
46+
}
47+
48+
if piped() {
49+
ln := lines(os.Stdin)
50+
args = append(args, ln...)
51+
}
52+
53+
if len(args) == 0 {
54+
flag.Usage()
55+
os.Exit(1)
56+
}
57+
58+
display(args, *width, *height)
59+
}
60+
61+
// usage prints default usage.
62+
func usage() {
63+
fmt.Fprintf(os.Stderr, "Usage: %s [FILE1 [FILE2 [...]]]\n", appName)
64+
fmt.Fprintf(os.Stderr, `
65+
-f path
66+
Use list of images from file, one per line
67+
-w int
68+
Window width (default 1024)
69+
-h int
70+
Window height (default 768)
71+
-v
72+
Print version and exit
73+
74+
Keybindings:
75+
76+
j / Right / PageDown / Space
77+
Next image
78+
79+
k / Left / PageUp
80+
Previous image
81+
82+
f / F11
83+
Fullscreen
84+
85+
[ / ]
86+
Go 10 images back/forward
87+
88+
, / .
89+
Go to first/last image
90+
91+
q / Escape
92+
Quit
93+
94+
Enter
95+
Print current image path to stdout`)
96+
fmt.Fprintf(os.Stderr, "\n")
97+
}
98+
99+
// arguments returns slice of arguments.
100+
func arguments(in []string) []string {
101+
out := make([]string, 0)
102+
for _, arg := range in {
103+
if _, err := os.Stat(arg); err == nil {
104+
out = append(out, arg)
105+
} else {
106+
if isURL(arg) {
107+
out = append(out, arg)
108+
} else {
109+
g, err := filepath.Glob(arg)
110+
if err == nil {
111+
out = append(out, g...)
112+
}
113+
}
114+
}
115+
}
116+
117+
return out
118+
}
119+
120+
// lines returns slice of lines from reader.
121+
func lines(r io.Reader) []string {
122+
ln := make([]string, 0)
123+
124+
scanner := bufio.NewScanner(r)
125+
for scanner.Scan() {
126+
ln = append(ln, scanner.Text())
127+
}
128+
129+
return ln
130+
}
131+
132+
// piped checks if we have a piped stdin.
133+
func piped() bool {
134+
f, err := os.Stdin.Stat()
135+
if err != nil {
136+
return false
137+
}
138+
139+
if f.Mode()&os.ModeNamedPipe == 0 {
140+
return false
141+
} else {
142+
return true
143+
}
144+
}
145+
146+
// isURL checks if arguments is URL.
147+
func isURL(arg string) bool {
148+
if strings.HasPrefix(arg, "http://") || strings.HasPrefix(arg, "https://") {
149+
return true
150+
}
151+
152+
return false
153+
}

goiv_darwin.go

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// +build darwin
2+
3+
package main
4+
5+
func display(images []string, width, height int) {
6+
displayX11(images, width, height)
7+
}

0 commit comments

Comments
 (0)