Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@acoshift
Created February 16, 2019 11:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save acoshift/305c2268bc7fe91926b302eed3209cff to your computer and use it in GitHub Desktop.
Save acoshift/305c2268bc7fe91926b302eed3209cff to your computer and use it in GitHub Desktop.
Example how to use semaphore in Golang
package main
import (
"context"
"fmt"
"os"
"path/filepath"
"strconv"
"sync"
"github.com/disintegration/imaging"
"golang.org/x/sync/semaphore"
)
// Build with `go build -o thumbnail main.go`
func main() {
args := os.Args
if len(args) != 5 {
fmt.Println("thumbnail converts images to thumbnail")
fmt.Println("Usage: thumbnail src-folder dst-folder width height")
return
}
src, dst := args[1], args[2]
width, _ := strconv.Atoi(args[3])
height, _ := strconv.Atoi(args[4])
if src == "" || dst == "" || width <= 0 || height <= 0 {
fmt.Println("invalid arguments")
os.Exit(1)
}
os.MkdirAll(dst, 0777)
fmt.Printf("resize images from '%s' to '%s'\n", src, dst)
worker := newImageResizerWorker(10)
srcFiles, _ := filepath.Glob(src + "/*")
wg := sync.WaitGroup{}
for _, in := range srcFiles {
in := in
_, out := filepath.Split(in)
out = filepath.Join(dst, out)
wg.Add(1)
go func() {
defer wg.Done()
err := worker.ResizeFile(out, in, width, height)
if err != nil {
fmt.Printf("%s; %s\n", in, err)
} else {
fmt.Printf("%s; success\n", in)
}
}()
}
wg.Wait()
}
type imageResizerWorker struct {
sem *semaphore.Weighted
}
func newImageResizerWorker(worker int64) *imageResizerWorker {
return &imageResizerWorker{
sem: semaphore.NewWeighted(worker),
}
}
func (rz *imageResizerWorker) ResizeFile(dst, src string, width, height int) error {
rz.sem.Acquire(context.Background(), 1)
defer rz.sem.Release(1)
format, err := imaging.FormatFromExtension(filepath.Ext(src))
if err != nil {
return err
}
r, err := os.Open(src)
if err != nil {
return err
}
defer r.Close()
w, err := os.Create(dst)
if err != nil {
return err
}
defer w.Close()
img, err := imaging.Decode(r)
if err != nil {
return err
}
img = imaging.Fill(img, width, height, imaging.Center, imaging.Lanczos)
return imaging.Encode(w, img, format)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment