commit efab03f328ae38d7671b744f48c895e8fdfae2dd Author: Arkadyuti Sarkar Date: Mon Mar 20 15:36:24 2023 +0530 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..00ff2e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +image-resize +results.csv +out \ No newline at end of file diff --git a/assets/SampleJPGImage_100kbmb.jpg b/assets/SampleJPGImage_100kbmb.jpg new file mode 100644 index 0000000..f6a8d28 Binary files /dev/null and b/assets/SampleJPGImage_100kbmb.jpg differ diff --git a/assets/Screenshot.png b/assets/Screenshot.png new file mode 100644 index 0000000..a38187d Binary files /dev/null and b/assets/Screenshot.png differ diff --git a/assets/bad.png b/assets/bad.png new file mode 100644 index 0000000..c28d984 Binary files /dev/null and b/assets/bad.png differ diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..4510da5 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module bitbucket.org/tekion/image-resize + +go 1.18 + +require github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..96adbed --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= diff --git a/main.go b/main.go new file mode 100644 index 0000000..12bb5e3 --- /dev/null +++ b/main.go @@ -0,0 +1,206 @@ +package main + +import ( + "encoding/csv" + "fmt" + "github.com/nfnt/resize" + "image" + "image/jpeg" + "image/png" + "io" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "strconv" +) + +var finalWidth uint = 1920 +var outPath = filepath.Join(".", "out") +var inputPath = filepath.Join(".", "assets") + +func readArgs() { + fmt.Println(len(os.Args), os.Args) + if len(os.Args) == 4 { + inputPath = os.Args[1] + outPath = os.Args[2] + i, _ := strconv.Atoi(os.Args[3]) + if i <= 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 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()) + 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) +}