package main import ( "image/jpeg" "image/png" "io" "os" "path" "path/filepath" "strings" "sync" "github.com/kataras/iris/v12" "github.com/nfnt/resize" ) // $ go get -u github.com/nfnt/resize const uploadsDir = "./public/uploads/" type uploadedFile struct { // {name: "", size: } are the dropzone's only requirements. Name string `json:"name"` Size int64 `json:"size"` } type uploadedFiles struct { dir string items []uploadedFile mu sync.RWMutex // slices are safe but RWMutex is a good practise for you. } func scanUploads(dir string) *uploadedFiles { f := new(uploadedFiles) lindex := dir[len(dir)-1] if lindex != os.PathSeparator && lindex != '/' { dir += string(os.PathSeparator) } // create directories if necessary // and if, then return empty uploaded files; skipping the scan. if err := os.MkdirAll(dir, os.FileMode(0666)); err != nil { return f } // otherwise scan the given "dir" for files. f.scan(dir) return f } func (f *uploadedFiles) scan(dir string) { f.dir = dir filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { // if it's directory or a thumbnail we saved earlier, skip it. if info.IsDir() || strings.HasPrefix(info.Name(), "thumbnail_") { return nil } f.add(info.Name(), info.Size()) return nil }) } func (f *uploadedFiles) add(name string, size int64) uploadedFile { uf := uploadedFile{ Name: name, Size: size, } f.mu.Lock() f.items = append(f.items, uf) f.mu.Unlock() return uf } func (f *uploadedFiles) createThumbnail(uf uploadedFile) { file, err := os.Open(path.Join(f.dir, uf.Name)) if err != nil { return } defer file.Close() name := strings.ToLower(uf.Name) out, err := os.OpenFile(f.dir+"thumbnail_"+uf.Name, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { return } defer out.Close() if strings.HasSuffix(name, ".jpg") { // decode jpeg into image.Image img, err := jpeg.Decode(file) if err != nil { return } // write new image to file resized := resize.Thumbnail(180, 180, img, resize.Lanczos3) jpeg.Encode(out, resized, &jpeg.Options{Quality: jpeg.DefaultQuality}) } else if strings.HasSuffix(name, ".png") { img, err := png.Decode(file) if err != nil { return } // write new image to file resized := resize.Thumbnail(180, 180, img, resize.Lanczos3) // slower but better res png.Encode(out, resized) } // and so on... you got the point, this code can be simplify, as a practise. } func main() { app := iris.New() app.RegisterView(iris.HTML("./views", ".html")) app.HandleDir("/public", iris.Dir("./public")) app.Get("/", func(ctx iris.Context) { if err := ctx.View("upload.html"); err != nil { ctx.HTML("