-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
150 lines (116 loc) · 4.71 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package main
import (
"flag"
"image"
_ "image/jpeg"
_ "image/png"
"log"
"math"
"os"
"time"
_ "golang.org/x/image/webp"
"github.com/DavidEsdrs/image-processing/configs"
"github.com/DavidEsdrs/image-processing/convert"
"github.com/DavidEsdrs/image-processing/logger"
"github.com/DavidEsdrs/image-processing/parsing"
"github.com/DavidEsdrs/image-processing/processor"
"github.com/DavidEsdrs/image-processing/utils"
)
// driver code
// Note that application starts and end here - any errors through all the
// application converges to the errors got there on the "if err != nil"
// statements
func main() {
var config *configs.Config = configs.GetConfig()
var verbose bool
var help bool
setFlags(config, &verbose, &help)
flag.Parse()
if help {
logger.Usage()
os.Exit(0)
}
logger := logger.NewLogger(verbose)
if config.Input == "" || config.Output == "" {
logger.Fatal("input and output files are required.", 2)
}
start := time.Now()
img, err := utils.LoadImage(config.Input)
if err != nil {
log.Fatalf("error while loading input file - %v\n", err.Error())
}
proc, err := config.ParseConfig(logger, img)
if err != nil {
log.Fatal(err.Error())
}
// main process
err = processImage(img, config.Output, proc, &logger)
if err != nil {
log.Fatal(err)
}
duration := time.Since(start)
logger.LogProcessf("completed: image %v processed - output image: %v - %v\n", config.Input, config.Output, duration.String())
}
func processImage(img image.Image, outputPath string, proc *processor.Invoker, logger *logger.Logger) error {
logger.LogProcess("Converting image into tensor")
q := utils.GetQuad(img)
logger.LogProcess("Start invoking filters")
err := proc.Invoke(q)
if err != nil {
return err
}
context := convert.NewConversionContext(logger)
conversor, err := context.GetConversor(img, proc.GetColorModel())
if err != nil {
return err
}
logger.LogProcess("Converting tensor back into image")
cImg := conversor.Convert(q)
pc := parsing.NewParsingContext(logger)
config, err := pc.GetConfig()
if err != nil {
return err
}
logger.LogProcessf("Saving image as %v", outputPath)
err = config.Save(cImg, outputPath)
return err
}
// set cli flags
//
// TODO: Avoid using pointer to primitive args
func setFlags(config *configs.Config, verbose *bool, help *bool) {
flag.BoolVar(help, "h", false, "Print tool usage")
flag.BoolVar(verbose, "v", false, "Verbose")
flag.StringVar(&config.Input, "i", "", "Input file")
flag.StringVar(&config.Output, "o", "", "Output file")
// filters
flag.BoolVar(&config.FlipY, "fy", false, "Flip y axis filter")
flag.BoolVar(&config.FlipX, "fx", false, "Flip x axis filter")
flag.BoolVar(&config.Transpose, "t", false, "Apply transpose process (rotate 270 degrees and flip Y axis)")
flag.BoolVar(&config.TurnLeft, "tl", false, "Rotate 90 degrees counterclockwise")
flag.BoolVar(&config.TurnRight, "tr", false, "Rotate 90 degrees clockwise")
flag.BoolVar(&config.Grayscale, "gs", false, "Apply grayscale filter")
flag.StringVar(&config.Crop, "c", "", "Crop image at given coordinates. Ex.: \"-c 0,1000,0,200\", xstart,xend,ystart,yend or \"-c 1000,200\", xend,yend (x and y start default to 0)")
flag.IntVar(&config.Ssr, "ssr", 0, "Subsample ratio for images YCbCr. 444 = 4:4:4, 422 = 4:2:2, 420 = 4:2:0, 440 = 4:4:0, 411 = 4:1:1, 410 = 4:1:0")
flag.IntVar(&config.Quality, "q", 0, "Quality of the JPEG image. 1-100")
flag.IntVar(&config.BlurSize, "b", 0, "How blurry the image will be")
flag.Float64Var(&config.Sigma, "s", 1.0, "Sigma value for blur")
flag.IntVar(&config.Brightness, "l", 1.0, "Brightness value")
flag.Float64Var(&config.Saturation, "sat", 0, "Saturation value")
flag.Float64Var(&config.Rotation, "r", 0, "Rotation value")
flag.BoolVar(&config.Invert, "inv", false, "Invert")
flag.IntVar(&config.Temperature, "temp", 0, "Color temperature in Kelvin (ranging from 1000 to 4000)")
flag.Float64Var(&config.Contrast, "cont", 1, "Contrast value (ranging from -1 for less contrast up to 1 for more contrast)")
// Resize
flag.BoolVar(&config.NearestNeighbor, "nn", false, "Apply nearest neighbor resize algorithm")
flag.IntVar(&config.Width, "width", math.MaxInt32, "Width")
flag.IntVar(&config.Height, "height", math.MaxInt32, "Height")
flag.Float64Var(&config.Factor, "f", 1, "Scale factor")
// overlay
flag.StringVar(&config.Overlay, "ov", "", "Image to overlay onto the input image")
flag.IntVar(&config.DistTop, "dt", math.MinInt32, "Distance to the top")
flag.IntVar(&config.DistRight, "dr", math.MinInt32, "Distance to the right")
flag.IntVar(&config.DistBottom, "db", math.MinInt32, "Distance to the bottom")
flag.IntVar(&config.DistLeft, "dl", math.MinInt32, "Distance to the left")
flag.BoolVar(&config.Fill, "fill", false, "Should the overlay fill in")
}