222 lines
5.4 KiB
Go
222 lines
5.4 KiB
Go
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: <source_dir> <dest_dir> <width_resolution_px>")
|
|
os.Exit(1)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
fmt.Println("arguments: <source_dir> <dest_dir> <width_resolution_px>")
|
|
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)
|
|
}
|