package main import ( "encoding/csv" "fmt" "github.com/nfnt/resize" "image" "image/jpeg" "image/png" "io" "io/ioutil" "net/http" "os" "path/filepath" "regexp" "strconv" ) //ffmpeg -i "tmp/${fName}" -c:v libvpx-vp9 -c:a libopus -s 640x360 -b:v 276k -minrate 138k -maxrate 400k -tile-columns 1 -threads 4 -quality good -crf 36 "tmp/${fName}.webm" 2> /dev/null var finalWidth uint = 1920 var outPath = filepath.Join(".", "out") var inputPath = filepath.Join(".", "assets") func readArgs() { if len(os.Args) == 4 { inputPath = os.Args[1] outPath = os.Args[2] i, _ := strconv.Atoi(os.Args[3]) finalWidth = uint(i) if finalWidth <= 0 { fmt.Println("Wrong input for resolution, arguments: ") os.Exit(1) } } } func main() { fmt.Println("arguments: ") readArgs() err := os.MkdirAll(outPath, os.ModePerm) if err != nil { fmt.Println("unable to create path", err) return } results := [][]string{ {"File name", "success", "resized", "old resolution", "new resolution"}, } allFilePath := listFiles(inputPath) for _, filePath := range allFilePath { handleFile(filePath, &results) } fmt.Println("results:", results) writeResult(results) } func removeSpacialCharFromString(src string) string { reg, err := regexp.Compile("[^a-zA-Z0-9-.]+") if err != nil { fmt.Println("regex err:", err) } processedString := reg.ReplaceAllString(src, "-") return processedString } func handleFile(filePath string, results *[][]string) { var individualResult = map[string]string{"fileName": filepath.Base(filePath), "success": "no", "resized": "no", "old": ""} file, err := os.Open(filePath) if err != nil { individualResult["success"] = "no" individualResult["resized"] = "no" fmt.Println("unable to open file", err) updateResult(results, individualResult) return } var img image.Image isImage := false fileType := readFileType(filePath) switch fileType { case "image/jpeg": img, err = jpeg.Decode(file) if err != nil { individualResult["success"] = "no" individualResult["resized"] = "no" fmt.Println("unable to decode jpeg", err) updateResult(results, individualResult) return } isImage = true case "image/png": img, err = png.Decode(file) if err != nil { individualResult["success"] = "no" individualResult["resized"] = "no" fmt.Println("unable to decode png", err) updateResult(results, individualResult) return } isImage = true } if isImage { resizeImage(filePath, file, img, individualResult) } else { individualResult["success"] = "no" individualResult["resized"] = "no" } defer func() { updateResult(results, individualResult) file.Close() }() } func updateResult(results *[][]string, individualResult map[string]string) { *results = append(*results, []string{individualResult["fileName"], individualResult["success"], individualResult["resized"], individualResult["old"], individualResult["new"]}) } func resizeImage(filePath string, file *os.File, img image.Image, individualResult map[string]string) { fileName := filepath.Base(file.Name()) fileName = removeSpacialCharFromString(fileName) outFileName := outPath + "/" + fileName individualResult["old"] = strconv.Itoa(img.Bounds().Dx()) + " x " + strconv.Itoa(img.Bounds().Dy()) if uint(img.Bounds().Dx()) <= finalWidth { fmt.Println("ignoring as the resolution is less, file:", filepath.Base(filePath)) individualResult["resized"] = "no" individualResult["success"] = "yes" _, err := copy(filePath, outFileName) if err != nil { individualResult["success"] = "no" individualResult["resized"] = "no" fmt.Println("Error while copying file", err) return } return } m := resize.Resize(finalWidth, 0, img, resize.Lanczos3) individualResult["new"] = strconv.Itoa(m.Bounds().Dx()) + " x " + strconv.Itoa(m.Bounds().Dy()) out, err := os.Create(outFileName) if err != nil { individualResult["success"] = "no" individualResult["resized"] = "no" fmt.Println("unable to create image", err) return } // write new image to file err = jpeg.Encode(out, m, nil) if err != nil { individualResult["success"] = "no" individualResult["resized"] = "no" fmt.Println("unable to write image", err) return } individualResult["success"] = "yes" individualResult["resized"] = "yes" defer out.Close() } func listFiles(path string) []string { var allFilePath []string entries, err := os.ReadDir(path) if err != nil { fmt.Println("unable to read dir", err) } for _, e := range entries { allFilePath = append(allFilePath, filepath.Join(".", path, e.Name())) } return allFilePath } func readFileType(path string) string { contents, _ := ioutil.ReadFile(path) return http.DetectContentType(contents) } func copy(src, dst string) (int64, error) { sourceFileStat, err := os.Stat(src) if err != nil { return 0, err } if !sourceFileStat.Mode().IsRegular() { return 0, fmt.Errorf("%s is not a regular file", src) } source, err := os.Open(src) if err != nil { return 0, err } defer source.Close() destination, err := os.Create(dst) if err != nil { return 0, err } defer destination.Close() nBytes, err := io.Copy(destination, source) return nBytes, err } func writeResult(results [][]string) { f, err := os.Create("results.csv") defer f.Close() if err != nil { fmt.Println("writeResult: failed to open file", err) return } w := csv.NewWriter(f) w.WriteAll(results) }