From e6d67acfeb79ecf5f3ada216ed48bf5f4b503122 Mon Sep 17 00:00:00 2001 From: Hiroyuki Tanaka Date: Mon, 6 Jul 2020 22:11:53 +0900 Subject: [PATCH 1/9] Implements imgconv --- kadai1/tanaka0325/README.md | 58 ++++++++++++ kadai1/tanaka0325/converter/conv_image.go | 81 +++++++++++++++++ kadai1/tanaka0325/converter/convert.go | 104 ++++++++++++++++++++++ kadai1/tanaka0325/converter/exts.go | 14 +++ kadai1/tanaka0325/go.mod | 5 ++ kadai1/tanaka0325/go.sum | 4 + kadai1/tanaka0325/images/sample1.jpg | Bin 0 -> 10979 bytes kadai1/tanaka0325/images2/img/sample3.jpg | Bin 0 -> 10979 bytes kadai1/tanaka0325/images2/sample2.jpg | Bin 0 -> 10979 bytes kadai1/tanaka0325/imgconv.go | 7 ++ 10 files changed, 273 insertions(+) create mode 100644 kadai1/tanaka0325/README.md create mode 100644 kadai1/tanaka0325/converter/conv_image.go create mode 100644 kadai1/tanaka0325/converter/convert.go create mode 100644 kadai1/tanaka0325/converter/exts.go create mode 100644 kadai1/tanaka0325/go.mod create mode 100644 kadai1/tanaka0325/go.sum create mode 100644 kadai1/tanaka0325/images/sample1.jpg create mode 100644 kadai1/tanaka0325/images2/img/sample3.jpg create mode 100644 kadai1/tanaka0325/images2/sample2.jpg create mode 100644 kadai1/tanaka0325/imgconv.go diff --git a/kadai1/tanaka0325/README.md b/kadai1/tanaka0325/README.md new file mode 100644 index 0000000..912ed3f --- /dev/null +++ b/kadai1/tanaka0325/README.md @@ -0,0 +1,58 @@ +# Image Converter + +## Spec + +``` +## 次の仕様を満たすコマンドを作って下さい + +- ディレクトリを指定する +- 指定したディレクトリ以下のJPGファイルをPNGに変換(デフォルト) +- ディレクトリ以下は再帰的に処理する +- 変換前と変換後の画像形式を指定できる(オプション) + +## 以下を満たすように開発してください + +- mainパッケージと分離する +- 自作パッケージと標準パッケージと準標準パッケージのみ使う +- 準標準パッケージ:golang.org/x以下のパッケージ +- ユーザ定義型を作ってみる +- GoDocを生成してみる +- Go Modulesを使ってみる +``` + +## Usage + +```zsh +# build +$ go build -o ./imgconv + +# display help +$ ./imgconv -h +Usage of ./imgconv: + -f string + file extention before convert (default "jpg") + -n dry run + -t string + file extention after convert (default "png") + +# single directory +$ ./imgconv images + +# multi directories +$ ./imgconv images images2 + +# customize ext +$ ./imgconv -f png -t gif images + +# dry run +$ ./imgconv -n images +images/sample1.jpg => images/sample1.png +images2/img/sample3.jpg => images2/img/sample3.png +images2/sample2.jpg => images2/sample2.png +``` + +## 感想 + +- long option(?) はどうやってやれば良いのだろうか +- そもそも作りとしてこれで良いのだろうか・・・めっちゃ悩みました + diff --git a/kadai1/tanaka0325/converter/conv_image.go b/kadai1/tanaka0325/converter/conv_image.go new file mode 100644 index 0000000..2be5c9a --- /dev/null +++ b/kadai1/tanaka0325/converter/conv_image.go @@ -0,0 +1,81 @@ +package converter + +import ( + "fmt" + "image" + "image/gif" + "image/jpeg" + "image/png" + "io" + "os" + + "golang.org/x/image/bmp" + "golang.org/x/image/tiff" +) + +type convImage struct { + filename string + fromExt string + toExt string + image image.Image +} + +func (i *convImage) decode() error { + r, err := os.Open(i.filename + "." + i.fromExt) + if err != nil { + return err + } + defer r.Close() + + img, err := decodeHelper(r, i.fromExt) + if err != nil { + return fmt.Errorf("decode error: %w", err) + } + + i.image = img + return nil +} + +func decodeHelper(r io.Reader, ext string) (image.Image, error) { + switch ext { + case "png": + return png.Decode(r) + case "jpg", "jpeg": + return jpeg.Decode(r) + case "gif": + return gif.Decode(r) + case "bmp": + return bmp.Decode(r) + case "tiff", "tif": + return tiff.Decode(r) + } + return nil, fmt.Errorf("%s is not allowed", ext) +} + +func (i *convImage) encode() error { + w, err := os.Create(i.filename + "." + i.toExt) + if err != nil { + return err + } + defer func() error { + if err := w.Close(); err != nil { + return err + } + return nil + }() + + switch i.toExt { + case "png": + return png.Encode(w, i.image) + case "jpg", "jpeg": + return jpeg.Encode(w, i.image, nil) + case "gif": + return gif.Encode(w, i.image, nil) + case "bmp": + return gif.Encode(w, i.image, nil) + case "tiff", "tif": + return gif.Encode(w, i.image, nil) + } + + return fmt.Errorf("cannot encode image") +} diff --git a/kadai1/tanaka0325/converter/convert.go b/kadai1/tanaka0325/converter/convert.go new file mode 100644 index 0000000..c5ee5c2 --- /dev/null +++ b/kadai1/tanaka0325/converter/convert.go @@ -0,0 +1,104 @@ +package converter + +import ( + "flag" + "fmt" + "log" + "os" + "path/filepath" + "strings" +) + +// flags +var ( + allowedExts = exts{"png", "jpg", "jpeg", "gif", "bmp", "tiff", "tif"} + f = flag.String("f", "jpg", "file extention before convert") + t = flag.String("t", "png", "file extention after convert") + dryRun = flag.Bool("n", false, "dry run") +) + +// Convert is to convert image file format +func Convert() { + // check options ext + flag.Parse() + to := strings.ToLower(*t) + from := strings.ToLower(*f) + targetExts := []string{to, from} + for _, e := range targetExts { + if err := allowedExts.include(e); err != nil { + log.Fatal(fmt.Errorf("%w. ext is only allowd in %s", err, allowedExts)) + } + } + + // get target image paths from args + dns := flag.Args() + udns := uniq(dns) + paths, err := getPaths(udns, from) + if err != nil { + log.Fatal(err) + } + + // convert + imgs, err := createConvImages(paths, from, to) + if err != nil { + log.Fatal(err) + } + for _, img := range imgs { + if err := img.decode(); err != nil { + log.Fatal(err) + } + + if *dryRun { + fmt.Println(img.filename+"."+img.fromExt, "=>", img.filename+"."+img.toExt) + } else { + if err := img.encode(); err != nil { + log.Fatal(err) + } + } + } +} + +func uniq(s []string) []string { + m := map[string]bool{} + u := []string{} + + for _, v := range s { + if !m[v] { + m[v] = true + u = append(u, v) + } + } + + return u +} + +func getPaths(dns []string, from string) ([]string, error) { + paths := []string{} + + for _, dn := range dns { + if err := filepath.Walk(dn, func(path string, info os.FileInfo, err error) error { + if filepath.Ext(path) == "."+from { + paths = append(paths, path) + } + return nil + }); err != nil { + return nil, err + } + } + + return paths, nil +} + +func createConvImages(paths []string, from, to string) ([]convImage, error) { + images := []convImage{} + for _, p := range paths { + i := convImage{ + filename: strings.Replace(p, "."+from, "", 1), + fromExt: strings.ToLower(from), + toExt: strings.ToLower(to), + } + images = append(images, i) + } + + return images, nil +} diff --git a/kadai1/tanaka0325/converter/exts.go b/kadai1/tanaka0325/converter/exts.go new file mode 100644 index 0000000..5343d8d --- /dev/null +++ b/kadai1/tanaka0325/converter/exts.go @@ -0,0 +1,14 @@ +package converter + +import "errors" + +type exts []string + +func (es exts) include(w string) error { + for _, e := range es { + if e == w { + return nil + } + } + return errors.New(w + " is not allowed") +} diff --git a/kadai1/tanaka0325/go.mod b/kadai1/tanaka0325/go.mod new file mode 100644 index 0000000..80a8fb1 --- /dev/null +++ b/kadai1/tanaka0325/go.mod @@ -0,0 +1,5 @@ +module github.com/gopherdojo/dojo8/kadai1/tanaka0325 + +go 1.14 + +require golang.org/x/image v0.0.0-20200618115811-c13761719519 diff --git a/kadai1/tanaka0325/go.sum b/kadai1/tanaka0325/go.sum new file mode 100644 index 0000000..83da957 --- /dev/null +++ b/kadai1/tanaka0325/go.sum @@ -0,0 +1,4 @@ +github.com/gopherdojo/dojo8 v0.0.0-20200703052727-6a79d18126bf h1:lpYevjFQMxI5VNBc3WXV6Z5pDDrdppdDKwmeBoyt5BE= +golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7UTjd6cgJNdatjPdFWf34= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/kadai1/tanaka0325/images/sample1.jpg b/kadai1/tanaka0325/images/sample1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7a1088190cee7554271ea0f297a9bbf8bd4ab023 GIT binary patch literal 10979 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 F|3CafUylF) literal 0 HcmV?d00001 diff --git a/kadai1/tanaka0325/images2/img/sample3.jpg b/kadai1/tanaka0325/images2/img/sample3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7a1088190cee7554271ea0f297a9bbf8bd4ab023 GIT binary patch literal 10979 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 F|3CafUylF) literal 0 HcmV?d00001 diff --git a/kadai1/tanaka0325/images2/sample2.jpg b/kadai1/tanaka0325/images2/sample2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7a1088190cee7554271ea0f297a9bbf8bd4ab023 GIT binary patch literal 10979 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 F|3CafUylF) literal 0 HcmV?d00001 diff --git a/kadai1/tanaka0325/imgconv.go b/kadai1/tanaka0325/imgconv.go new file mode 100644 index 0000000..badc036 --- /dev/null +++ b/kadai1/tanaka0325/imgconv.go @@ -0,0 +1,7 @@ +package main + +import "github.com/gopherdojo/dojo8/kadai1/tanaka0325/converter" + +func main() { + converter.Convert() +} From 5868629da1d545702c4d128bd85668dc1c56803c Mon Sep 17 00:00:00 2001 From: Hiroyuki Tanaka Date: Tue, 7 Jul 2020 01:39:13 +0900 Subject: [PATCH 2/9] Create testdata dir --- kadai1/tanaka0325/README.md | 15 ++++++++------- .../tanaka0325/{ => testdata}/images/sample1.jpg | Bin .../{ => testdata}/images2/img/sample3.jpg | Bin .../{ => testdata}/images2/sample2.jpg | Bin 4 files changed, 8 insertions(+), 7 deletions(-) rename kadai1/tanaka0325/{ => testdata}/images/sample1.jpg (100%) rename kadai1/tanaka0325/{ => testdata}/images2/img/sample3.jpg (100%) rename kadai1/tanaka0325/{ => testdata}/images2/sample2.jpg (100%) diff --git a/kadai1/tanaka0325/README.md b/kadai1/tanaka0325/README.md index 912ed3f..dd5b852 100644 --- a/kadai1/tanaka0325/README.md +++ b/kadai1/tanaka0325/README.md @@ -36,19 +36,20 @@ Usage of ./imgconv: file extention after convert (default "png") # single directory -$ ./imgconv images +$ ./imgconv testdata/images # multi directories -$ ./imgconv images images2 +$ ./imgconv testdata/images testdata/images2 # customize ext -$ ./imgconv -f png -t gif images +$ ./imgconv -f png -t gif testdata/images # dry run -$ ./imgconv -n images -images/sample1.jpg => images/sample1.png -images2/img/sample3.jpg => images2/img/sample3.png -images2/sample2.jpg => images2/sample2.png +$ ./imgconv -n testdata/images testdata/images2 +testdata/images/sample1.jpg => testdata/images/sample1.png +testdata/images2/img/sample3.jpg => testdata/images2/img/sample3.png +testdata/images2/sample2.jpg => testdata/images2/sample2.png + ``` ## 感想 diff --git a/kadai1/tanaka0325/images/sample1.jpg b/kadai1/tanaka0325/testdata/images/sample1.jpg similarity index 100% rename from kadai1/tanaka0325/images/sample1.jpg rename to kadai1/tanaka0325/testdata/images/sample1.jpg diff --git a/kadai1/tanaka0325/images2/img/sample3.jpg b/kadai1/tanaka0325/testdata/images2/img/sample3.jpg similarity index 100% rename from kadai1/tanaka0325/images2/img/sample3.jpg rename to kadai1/tanaka0325/testdata/images2/img/sample3.jpg diff --git a/kadai1/tanaka0325/images2/sample2.jpg b/kadai1/tanaka0325/testdata/images2/sample2.jpg similarity index 100% rename from kadai1/tanaka0325/images2/sample2.jpg rename to kadai1/tanaka0325/testdata/images2/sample2.jpg From 51e8c55a01b2e5be8150caa90d0a70c4be5102ec Mon Sep 17 00:00:00 2001 From: Hiroyuki Tanaka Date: Wed, 15 Jul 2020 23:05:54 +0900 Subject: [PATCH 3/9] change structure --- kadai1/tanaka0325/README.md | 2 +- kadai1/tanaka0325/imgconv.go | 7 ------ kadai1/tanaka0325/imgconv/cmd/imgconv/main.go | 9 ++++++++ .../{converter => imgconv}/conv_image.go | 2 +- .../tanaka0325/{converter => imgconv}/exts.go | 2 +- kadai1/tanaka0325/{ => imgconv}/go.mod | 2 +- kadai1/tanaka0325/{ => imgconv}/go.sum | 0 .../convert.go => imgconv/imgconv.go} | 21 +++++++++++------- .../{ => imgconv}/testdata/images/sample1.jpg | Bin .../testdata/images2/img/sample3.jpg | Bin .../testdata/images2/sample2.jpg | Bin 11 files changed, 26 insertions(+), 19 deletions(-) delete mode 100644 kadai1/tanaka0325/imgconv.go create mode 100644 kadai1/tanaka0325/imgconv/cmd/imgconv/main.go rename kadai1/tanaka0325/{converter => imgconv}/conv_image.go (98%) rename kadai1/tanaka0325/{converter => imgconv}/exts.go (91%) rename kadai1/tanaka0325/{ => imgconv}/go.mod (54%) rename kadai1/tanaka0325/{ => imgconv}/go.sum (100%) rename kadai1/tanaka0325/{converter/convert.go => imgconv/imgconv.go} (86%) rename kadai1/tanaka0325/{ => imgconv}/testdata/images/sample1.jpg (100%) rename kadai1/tanaka0325/{ => imgconv}/testdata/images2/img/sample3.jpg (100%) rename kadai1/tanaka0325/{ => imgconv}/testdata/images2/sample2.jpg (100%) diff --git a/kadai1/tanaka0325/README.md b/kadai1/tanaka0325/README.md index dd5b852..e239401 100644 --- a/kadai1/tanaka0325/README.md +++ b/kadai1/tanaka0325/README.md @@ -24,7 +24,7 @@ ```zsh # build -$ go build -o ./imgconv +$ go build -o imgconv ./cmd/imgconv # display help $ ./imgconv -h diff --git a/kadai1/tanaka0325/imgconv.go b/kadai1/tanaka0325/imgconv.go deleted file mode 100644 index badc036..0000000 --- a/kadai1/tanaka0325/imgconv.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "github.com/gopherdojo/dojo8/kadai1/tanaka0325/converter" - -func main() { - converter.Convert() -} diff --git a/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go b/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go new file mode 100644 index 0000000..344f749 --- /dev/null +++ b/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go @@ -0,0 +1,9 @@ +package main + +import ( + "github.com/gopherdojo/dojo8/kadai1/tanaka0325/imgconv" +) + +func main() { + imgconv.Run() +} diff --git a/kadai1/tanaka0325/converter/conv_image.go b/kadai1/tanaka0325/imgconv/conv_image.go similarity index 98% rename from kadai1/tanaka0325/converter/conv_image.go rename to kadai1/tanaka0325/imgconv/conv_image.go index 2be5c9a..7a873e5 100644 --- a/kadai1/tanaka0325/converter/conv_image.go +++ b/kadai1/tanaka0325/imgconv/conv_image.go @@ -1,4 +1,4 @@ -package converter +package imgconv import ( "fmt" diff --git a/kadai1/tanaka0325/converter/exts.go b/kadai1/tanaka0325/imgconv/exts.go similarity index 91% rename from kadai1/tanaka0325/converter/exts.go rename to kadai1/tanaka0325/imgconv/exts.go index 5343d8d..ab81016 100644 --- a/kadai1/tanaka0325/converter/exts.go +++ b/kadai1/tanaka0325/imgconv/exts.go @@ -1,4 +1,4 @@ -package converter +package imgconv import "errors" diff --git a/kadai1/tanaka0325/go.mod b/kadai1/tanaka0325/imgconv/go.mod similarity index 54% rename from kadai1/tanaka0325/go.mod rename to kadai1/tanaka0325/imgconv/go.mod index 80a8fb1..ad64074 100644 --- a/kadai1/tanaka0325/go.mod +++ b/kadai1/tanaka0325/imgconv/go.mod @@ -1,4 +1,4 @@ -module github.com/gopherdojo/dojo8/kadai1/tanaka0325 +module github.com/gopherdojo/dojo8/kadai1/tanaka0325/imgconv go 1.14 diff --git a/kadai1/tanaka0325/go.sum b/kadai1/tanaka0325/imgconv/go.sum similarity index 100% rename from kadai1/tanaka0325/go.sum rename to kadai1/tanaka0325/imgconv/go.sum diff --git a/kadai1/tanaka0325/converter/convert.go b/kadai1/tanaka0325/imgconv/imgconv.go similarity index 86% rename from kadai1/tanaka0325/converter/convert.go rename to kadai1/tanaka0325/imgconv/imgconv.go index c5ee5c2..2edc0d1 100644 --- a/kadai1/tanaka0325/converter/convert.go +++ b/kadai1/tanaka0325/imgconv/imgconv.go @@ -1,4 +1,4 @@ -package converter +package imgconv import ( "flag" @@ -9,18 +9,23 @@ import ( "strings" ) -// flags var ( + // flags + f = flag.String("f", "jpg", "file extention before convert") + t = flag.String("t", "png", "file extention after convert") + dryRun = flag.Bool("n", false, "dry run") + + // allow extensions allowedExts = exts{"png", "jpg", "jpeg", "gif", "bmp", "tiff", "tif"} - f = flag.String("f", "jpg", "file extention before convert") - t = flag.String("t", "png", "file extention after convert") - dryRun = flag.Bool("n", false, "dry run") ) -// Convert is to convert image file format -func Convert() { - // check options ext +func init() { flag.Parse() +} + +// Run is to convert image file format +func Run() { + // check options ext to := strings.ToLower(*t) from := strings.ToLower(*f) targetExts := []string{to, from} diff --git a/kadai1/tanaka0325/testdata/images/sample1.jpg b/kadai1/tanaka0325/imgconv/testdata/images/sample1.jpg similarity index 100% rename from kadai1/tanaka0325/testdata/images/sample1.jpg rename to kadai1/tanaka0325/imgconv/testdata/images/sample1.jpg diff --git a/kadai1/tanaka0325/testdata/images2/img/sample3.jpg b/kadai1/tanaka0325/imgconv/testdata/images2/img/sample3.jpg similarity index 100% rename from kadai1/tanaka0325/testdata/images2/img/sample3.jpg rename to kadai1/tanaka0325/imgconv/testdata/images2/img/sample3.jpg diff --git a/kadai1/tanaka0325/testdata/images2/sample2.jpg b/kadai1/tanaka0325/imgconv/testdata/images2/sample2.jpg similarity index 100% rename from kadai1/tanaka0325/testdata/images2/sample2.jpg rename to kadai1/tanaka0325/imgconv/testdata/images2/sample2.jpg From 6c9f2bb5307f7b7424f6bef96f2bd0108c122b9c Mon Sep 17 00:00:00 2001 From: Hiroyuki Tanaka Date: Wed, 15 Jul 2020 23:34:19 +0900 Subject: [PATCH 4/9] error handling --- kadai1/tanaka0325/imgconv/cmd/imgconv/main.go | 10 +++++++++- kadai1/tanaka0325/imgconv/imgconv.go | 15 ++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go b/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go index 344f749..95155e0 100644 --- a/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go +++ b/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go @@ -1,9 +1,17 @@ package main import ( + "fmt" + "os" + "github.com/gopherdojo/dojo8/kadai1/tanaka0325/imgconv" ) func main() { - imgconv.Run() + if err := imgconv.Run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + os.Exit(0) } diff --git a/kadai1/tanaka0325/imgconv/imgconv.go b/kadai1/tanaka0325/imgconv/imgconv.go index 2edc0d1..28410ad 100644 --- a/kadai1/tanaka0325/imgconv/imgconv.go +++ b/kadai1/tanaka0325/imgconv/imgconv.go @@ -3,7 +3,6 @@ package imgconv import ( "flag" "fmt" - "log" "os" "path/filepath" "strings" @@ -24,14 +23,14 @@ func init() { } // Run is to convert image file format -func Run() { +func Run() error { // check options ext to := strings.ToLower(*t) from := strings.ToLower(*f) targetExts := []string{to, from} for _, e := range targetExts { if err := allowedExts.include(e); err != nil { - log.Fatal(fmt.Errorf("%w. ext is only allowd in %s", err, allowedExts)) + return fmt.Errorf("%w. ext is only allowd in %s", err, allowedExts) } } @@ -40,27 +39,29 @@ func Run() { udns := uniq(dns) paths, err := getPaths(udns, from) if err != nil { - log.Fatal(err) + return err } // convert imgs, err := createConvImages(paths, from, to) if err != nil { - log.Fatal(err) + return err } for _, img := range imgs { if err := img.decode(); err != nil { - log.Fatal(err) + return err } if *dryRun { fmt.Println(img.filename+"."+img.fromExt, "=>", img.filename+"."+img.toExt) } else { if err := img.encode(); err != nil { - log.Fatal(err) + return err } } } + + return nil } func uniq(s []string) []string { From d5664c88b021cfea3f74bdfeae3b6b2c9aab02d8 Mon Sep 17 00:00:00 2001 From: Hiroyuki Tanaka Date: Thu, 16 Jul 2020 15:55:58 +0900 Subject: [PATCH 5/9] =?UTF-8?q?=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7?= =?UTF-8?q?=E3=83=B3=E3=80=81=E5=BC=95=E6=95=B0=E3=81=AE=E5=9F=BA=E6=9C=AC?= =?UTF-8?q?=E7=9A=84=E3=81=AA=E5=87=A6=E7=90=86=E3=81=AE=E5=A0=B4=E6=89=80?= =?UTF-8?q?=E3=82=92=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kadai1/tanaka0325/README.md | 1 + kadai1/tanaka0325/imgconv/args.go | 17 +++++++ kadai1/tanaka0325/imgconv/cmd/imgconv/main.go | 15 +++++- kadai1/tanaka0325/imgconv/exts.go | 14 ----- kadai1/tanaka0325/imgconv/go.mod.back | 5 ++ kadai1/tanaka0325/imgconv/go.sum | 1 - kadai1/tanaka0325/imgconv/imgconv.go | 51 ++++--------------- kadai1/tanaka0325/imgconv/options.go | 35 +++++++++++++ 8 files changed, 81 insertions(+), 58 deletions(-) create mode 100644 kadai1/tanaka0325/imgconv/args.go delete mode 100644 kadai1/tanaka0325/imgconv/exts.go create mode 100644 kadai1/tanaka0325/imgconv/go.mod.back create mode 100644 kadai1/tanaka0325/imgconv/options.go diff --git a/kadai1/tanaka0325/README.md b/kadai1/tanaka0325/README.md index e239401..c04f8c5 100644 --- a/kadai1/tanaka0325/README.md +++ b/kadai1/tanaka0325/README.md @@ -24,6 +24,7 @@ ```zsh # build +$ cd imgconv $ go build -o imgconv ./cmd/imgconv # display help diff --git a/kadai1/tanaka0325/imgconv/args.go b/kadai1/tanaka0325/imgconv/args.go new file mode 100644 index 0000000..5bb286f --- /dev/null +++ b/kadai1/tanaka0325/imgconv/args.go @@ -0,0 +1,17 @@ +package imgconv + +type Args []string + +func (args Args) uniq() []string { + m := map[string]bool{} + u := []string{} + + for _, v := range args { + if !m[v] { + m[v] = true + u = append(u, v) + } + } + + return u +} diff --git a/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go b/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go index 95155e0..10a5a56 100644 --- a/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go +++ b/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go @@ -1,14 +1,27 @@ package main import ( + "flag" "fmt" "os" "github.com/gopherdojo/dojo8/kadai1/tanaka0325/imgconv" ) +var options imgconv.Options +var args imgconv.Args + +func init() { + options.From = flag.String("f", "jpg", "file extention before convert") + options.To = flag.String("t", "png", "file extention after convert") + options.DryRun = flag.Bool("n", false, "dry run") + flag.Parse() + + args = flag.Args() +} + func main() { - if err := imgconv.Run(); err != nil { + if err := imgconv.Run(options, args); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } diff --git a/kadai1/tanaka0325/imgconv/exts.go b/kadai1/tanaka0325/imgconv/exts.go deleted file mode 100644 index ab81016..0000000 --- a/kadai1/tanaka0325/imgconv/exts.go +++ /dev/null @@ -1,14 +0,0 @@ -package imgconv - -import "errors" - -type exts []string - -func (es exts) include(w string) error { - for _, e := range es { - if e == w { - return nil - } - } - return errors.New(w + " is not allowed") -} diff --git a/kadai1/tanaka0325/imgconv/go.mod.back b/kadai1/tanaka0325/imgconv/go.mod.back new file mode 100644 index 0000000..ad64074 --- /dev/null +++ b/kadai1/tanaka0325/imgconv/go.mod.back @@ -0,0 +1,5 @@ +module github.com/gopherdojo/dojo8/kadai1/tanaka0325/imgconv + +go 1.14 + +require golang.org/x/image v0.0.0-20200618115811-c13761719519 diff --git a/kadai1/tanaka0325/imgconv/go.sum b/kadai1/tanaka0325/imgconv/go.sum index 83da957..394251b 100644 --- a/kadai1/tanaka0325/imgconv/go.sum +++ b/kadai1/tanaka0325/imgconv/go.sum @@ -1,4 +1,3 @@ -github.com/gopherdojo/dojo8 v0.0.0-20200703052727-6a79d18126bf h1:lpYevjFQMxI5VNBc3WXV6Z5pDDrdppdDKwmeBoyt5BE= golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7UTjd6cgJNdatjPdFWf34= golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/kadai1/tanaka0325/imgconv/imgconv.go b/kadai1/tanaka0325/imgconv/imgconv.go index 28410ad..be2338d 100644 --- a/kadai1/tanaka0325/imgconv/imgconv.go +++ b/kadai1/tanaka0325/imgconv/imgconv.go @@ -1,49 +1,30 @@ package imgconv import ( - "flag" "fmt" "os" "path/filepath" "strings" ) -var ( - // flags - f = flag.String("f", "jpg", "file extention before convert") - t = flag.String("t", "png", "file extention after convert") - dryRun = flag.Bool("n", false, "dry run") - - // allow extensions - allowedExts = exts{"png", "jpg", "jpeg", "gif", "bmp", "tiff", "tif"} -) - -func init() { - flag.Parse() -} +var allowedExts = []string{"png", "jpg", "jpeg", "gif", "bmp", "tiff", "tif"} // Run is to convert image file format -func Run() error { - // check options ext - to := strings.ToLower(*t) - from := strings.ToLower(*f) - targetExts := []string{to, from} - for _, e := range targetExts { - if err := allowedExts.include(e); err != nil { - return fmt.Errorf("%w. ext is only allowd in %s", err, allowedExts) - } +func Run(options Options, args Args) error { + // validator + if err := options.validate(allowedExts); err != nil { + return err } // get target image paths from args - dns := flag.Args() - udns := uniq(dns) - paths, err := getPaths(udns, from) + udns := args.uniq() + paths, err := getPaths(udns, *options.From) if err != nil { return err } // convert - imgs, err := createConvImages(paths, from, to) + imgs, err := createConvImages(paths, *options.From, *options.To) if err != nil { return err } @@ -52,7 +33,7 @@ func Run() error { return err } - if *dryRun { + if *options.DryRun { fmt.Println(img.filename+"."+img.fromExt, "=>", img.filename+"."+img.toExt) } else { if err := img.encode(); err != nil { @@ -64,20 +45,6 @@ func Run() error { return nil } -func uniq(s []string) []string { - m := map[string]bool{} - u := []string{} - - for _, v := range s { - if !m[v] { - m[v] = true - u = append(u, v) - } - } - - return u -} - func getPaths(dns []string, from string) ([]string, error) { paths := []string{} diff --git a/kadai1/tanaka0325/imgconv/options.go b/kadai1/tanaka0325/imgconv/options.go new file mode 100644 index 0000000..99accea --- /dev/null +++ b/kadai1/tanaka0325/imgconv/options.go @@ -0,0 +1,35 @@ +package imgconv + +import ( + "errors" + "fmt" + "strings" +) + +type Options struct { + From *string + To *string + DryRun *bool +} + +func (opt Options) validate(allow_list []string) error { + to := strings.ToLower(*opt.To) + from := strings.ToLower(*opt.From) + targetExts := []string{to, from} + for _, e := range targetExts { + if err := include(allow_list, e); err != nil { + return fmt.Errorf("%w. ext is only allowd in %s", err, allow_list) + } + } + + return nil +} + +func include(list []string, w string) error { + for _, e := range list { + if e == w { + return nil + } + } + return errors.New(w + " is not allowed") +} From bcdcd95b03b69bdf373b8273058adec11e7876af Mon Sep 17 00:00:00 2001 From: Hiroyuki Tanaka Date: Fri, 17 Jul 2020 11:41:46 +0900 Subject: [PATCH 6/9] refactoring 1 --- kadai1/tanaka0325/imgconv/imgconv.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kadai1/tanaka0325/imgconv/imgconv.go b/kadai1/tanaka0325/imgconv/imgconv.go index be2338d..e201b92 100644 --- a/kadai1/tanaka0325/imgconv/imgconv.go +++ b/kadai1/tanaka0325/imgconv/imgconv.go @@ -16,9 +16,8 @@ func Run(options Options, args Args) error { return err } - // get target image paths from args - udns := args.uniq() - paths, err := getPaths(udns, *options.From) + // get target image flepaths from args + paths, err := getTargetFilePaths(args, *options.From) if err != nil { return err } @@ -45,11 +44,12 @@ func Run(options Options, args Args) error { return nil } -func getPaths(dns []string, from string) ([]string, error) { +func getTargetFilePaths(args Args, from string) ([]string, error) { + uns := args.uniq() paths := []string{} - for _, dn := range dns { - if err := filepath.Walk(dn, func(path string, info os.FileInfo, err error) error { + for _, n := range uns { + if err := filepath.Walk(n, func(path string, info os.FileInfo, err error) error { if filepath.Ext(path) == "."+from { paths = append(paths, path) } From a265027b090933f341e5b57875b7c91978a94f84 Mon Sep 17 00:00:00 2001 From: Hiroyuki Tanaka Date: Fri, 17 Jul 2020 11:58:37 +0900 Subject: [PATCH 7/9] Add comments --- kadai1/tanaka0325/imgconv/args.go | 1 + kadai1/tanaka0325/imgconv/conv_image.go | 1 + kadai1/tanaka0325/imgconv/imgconv.go | 1 + kadai1/tanaka0325/imgconv/options.go | 1 + 4 files changed, 4 insertions(+) diff --git a/kadai1/tanaka0325/imgconv/args.go b/kadai1/tanaka0325/imgconv/args.go index 5bb286f..c5cd6f6 100644 --- a/kadai1/tanaka0325/imgconv/args.go +++ b/kadai1/tanaka0325/imgconv/args.go @@ -1,5 +1,6 @@ package imgconv +// Args is type for command line arguments. type Args []string func (args Args) uniq() []string { diff --git a/kadai1/tanaka0325/imgconv/conv_image.go b/kadai1/tanaka0325/imgconv/conv_image.go index 7a873e5..cb92ef3 100644 --- a/kadai1/tanaka0325/imgconv/conv_image.go +++ b/kadai1/tanaka0325/imgconv/conv_image.go @@ -13,6 +13,7 @@ import ( "golang.org/x/image/tiff" ) +// convImage is type included infomation to convert file format. type convImage struct { filename string fromExt string diff --git a/kadai1/tanaka0325/imgconv/imgconv.go b/kadai1/tanaka0325/imgconv/imgconv.go index e201b92..29db8da 100644 --- a/kadai1/tanaka0325/imgconv/imgconv.go +++ b/kadai1/tanaka0325/imgconv/imgconv.go @@ -1,3 +1,4 @@ +// Imgconv package is to convert images file format. package imgconv import ( diff --git a/kadai1/tanaka0325/imgconv/options.go b/kadai1/tanaka0325/imgconv/options.go index 99accea..3a31e15 100644 --- a/kadai1/tanaka0325/imgconv/options.go +++ b/kadai1/tanaka0325/imgconv/options.go @@ -6,6 +6,7 @@ import ( "strings" ) +// Args is type for command line options. type Options struct { From *string To *string From a235d16896efedd9f69e4dd79f7e8fcdc62ad2c4 Mon Sep 17 00:00:00 2001 From: Hiroyuki Tanaka Date: Fri, 17 Jul 2020 23:18:43 +0900 Subject: [PATCH 8/9] refactoring --- kadai1/tanaka0325/imgconv/args.go | 1 + kadai1/tanaka0325/imgconv/cmd/imgconv/main.go | 4 +- kadai1/tanaka0325/imgconv/cnv_image.go | 81 ++++++++++++++++ kadai1/tanaka0325/imgconv/conv_image.go | 82 ----------------- kadai1/tanaka0325/imgconv/go.mod.back | 5 - kadai1/tanaka0325/imgconv/imgconv.go | 92 +++++++++++++------ kadai1/tanaka0325/imgconv/options.go | 7 +- 7 files changed, 153 insertions(+), 119 deletions(-) create mode 100644 kadai1/tanaka0325/imgconv/cnv_image.go delete mode 100644 kadai1/tanaka0325/imgconv/conv_image.go delete mode 100644 kadai1/tanaka0325/imgconv/go.mod.back diff --git a/kadai1/tanaka0325/imgconv/args.go b/kadai1/tanaka0325/imgconv/args.go index c5cd6f6..4212901 100644 --- a/kadai1/tanaka0325/imgconv/args.go +++ b/kadai1/tanaka0325/imgconv/args.go @@ -10,6 +10,7 @@ func (args Args) uniq() []string { for _, v := range args { if !m[v] { m[v] = true + u = append(u, v) } } diff --git a/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go b/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go index 10a5a56..875aefa 100644 --- a/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go +++ b/kadai1/tanaka0325/imgconv/cmd/imgconv/main.go @@ -12,8 +12,8 @@ var options imgconv.Options var args imgconv.Args func init() { - options.From = flag.String("f", "jpg", "file extention before convert") - options.To = flag.String("t", "png", "file extention after convert") + options.From = flag.String("f", "jpg", "file extension before convert") + options.To = flag.String("t", "png", "file extension after convert") options.DryRun = flag.Bool("n", false, "dry run") flag.Parse() diff --git a/kadai1/tanaka0325/imgconv/cnv_image.go b/kadai1/tanaka0325/imgconv/cnv_image.go new file mode 100644 index 0000000..869a7d9 --- /dev/null +++ b/kadai1/tanaka0325/imgconv/cnv_image.go @@ -0,0 +1,81 @@ +package imgconv + +import ( + "image" + "image/gif" + "image/jpeg" + "image/png" + "io" + + "golang.org/x/image/bmp" + "golang.org/x/image/tiff" +) + +type Decoder interface { + Decode(io.Reader) (image.Image, error) +} + +type Encoder interface { + Encode(io.Writer, image.Image) error +} + +type DecodeEncoder interface { + Decoder + Encoder +} + +type CnvImage struct{} + +// CnvImagePng is type for png format. +type CnvImagePNG CnvImage + +func (ip CnvImagePNG) Decode(r io.Reader) (image.Image, error) { return png.Decode(r) } + +func (ip CnvImagePNG) Encode(w io.Writer, i image.Image) error { return png.Encode(w, i) } + +// CnvImageJPEG is type for jpeg format. +type CnvImageJPEG CnvImage + +func (ip CnvImageJPEG) Decode(r io.Reader) (image.Image, error) { return jpeg.Decode(r) } + +func (ip CnvImageJPEG) Encode(w io.Writer, i image.Image) error { return jpeg.Encode(w, i, nil) } + +// CnvImageGIF is type for gif format. +type CnvImageGIF CnvImage + +func (ip CnvImageGIF) Decode(r io.Reader) (image.Image, error) { return gif.Decode(r) } + +func (ip CnvImageGIF) Encode(w io.Writer, i image.Image) error { + return gif.Encode(w, i, &gif.Options{NumColors: 256}) +} + +// CnvImageBMP is type for bmp format. +type CnvImageBMP CnvImage + +func (ip CnvImageBMP) Decode(r io.Reader) (image.Image, error) { return bmp.Decode(r) } + +func (ip CnvImageBMP) Encode(w io.Writer, i image.Image) error { return bmp.Encode(w, i) } + +// CnvImageTIFF is type for tiff format. +type CnvImageTIFF CnvImage + +func (ip CnvImageTIFF) Decode(r io.Reader) (image.Image, error) { return tiff.Decode(r) } + +func (ip CnvImageTIFF) Encode(w io.Writer, i image.Image) error { return tiff.Encode(w, i, nil) } + +func newCnvImage(ext string) DecodeEncoder { + switch ext { + case "png": + return &CnvImagePNG{} + case "jpg", "jpeg": + return &CnvImageJPEG{} + case "gif": + return &CnvImageGIF{} + case "bmp": + return &CnvImageBMP{} + case "tiff", "tif": + return &CnvImageTIFF{} + } + + return nil +} diff --git a/kadai1/tanaka0325/imgconv/conv_image.go b/kadai1/tanaka0325/imgconv/conv_image.go deleted file mode 100644 index cb92ef3..0000000 --- a/kadai1/tanaka0325/imgconv/conv_image.go +++ /dev/null @@ -1,82 +0,0 @@ -package imgconv - -import ( - "fmt" - "image" - "image/gif" - "image/jpeg" - "image/png" - "io" - "os" - - "golang.org/x/image/bmp" - "golang.org/x/image/tiff" -) - -// convImage is type included infomation to convert file format. -type convImage struct { - filename string - fromExt string - toExt string - image image.Image -} - -func (i *convImage) decode() error { - r, err := os.Open(i.filename + "." + i.fromExt) - if err != nil { - return err - } - defer r.Close() - - img, err := decodeHelper(r, i.fromExt) - if err != nil { - return fmt.Errorf("decode error: %w", err) - } - - i.image = img - return nil -} - -func decodeHelper(r io.Reader, ext string) (image.Image, error) { - switch ext { - case "png": - return png.Decode(r) - case "jpg", "jpeg": - return jpeg.Decode(r) - case "gif": - return gif.Decode(r) - case "bmp": - return bmp.Decode(r) - case "tiff", "tif": - return tiff.Decode(r) - } - return nil, fmt.Errorf("%s is not allowed", ext) -} - -func (i *convImage) encode() error { - w, err := os.Create(i.filename + "." + i.toExt) - if err != nil { - return err - } - defer func() error { - if err := w.Close(); err != nil { - return err - } - return nil - }() - - switch i.toExt { - case "png": - return png.Encode(w, i.image) - case "jpg", "jpeg": - return jpeg.Encode(w, i.image, nil) - case "gif": - return gif.Encode(w, i.image, nil) - case "bmp": - return gif.Encode(w, i.image, nil) - case "tiff", "tif": - return gif.Encode(w, i.image, nil) - } - - return fmt.Errorf("cannot encode image") -} diff --git a/kadai1/tanaka0325/imgconv/go.mod.back b/kadai1/tanaka0325/imgconv/go.mod.back deleted file mode 100644 index ad64074..0000000 --- a/kadai1/tanaka0325/imgconv/go.mod.back +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/gopherdojo/dojo8/kadai1/tanaka0325/imgconv - -go 1.14 - -require golang.org/x/image v0.0.0-20200618115811-c13761719519 diff --git a/kadai1/tanaka0325/imgconv/imgconv.go b/kadai1/tanaka0325/imgconv/imgconv.go index 29db8da..e80c35c 100644 --- a/kadai1/tanaka0325/imgconv/imgconv.go +++ b/kadai1/tanaka0325/imgconv/imgconv.go @@ -9,47 +9,85 @@ import ( ) var allowedExts = []string{"png", "jpg", "jpeg", "gif", "bmp", "tiff", "tif"} +var fromExt string +var toExt string -// Run is to convert image file format +// Run is to convert image file format. func Run(options Options, args Args) error { - // validator + // // validator if err := options.validate(allowedExts); err != nil { return err } + fromExt = *options.From + toExt = *options.To + // get target image flepaths from args - paths, err := getTargetFilePaths(args, *options.From) + paths, err := getTargetFilePaths(args, fromExt) if err != nil { return err } // convert - imgs, err := createConvImages(paths, *options.From, *options.To) - if err != nil { - return err - } - for _, img := range imgs { - if err := img.decode(); err != nil { - return err - } + for _, path := range paths { + filename := strings.Replace(path, "."+fromExt, "", -1) + // ")) + f := newCnvImage(fromExt) + t := newCnvImage(toExt) if *options.DryRun { - fmt.Println(img.filename+"."+img.fromExt, "=>", img.filename+"."+img.toExt) - } else { - if err := img.encode(); err != nil { - return err - } + fmt.Printf("%s.%s => %s.%s \n", filename, fromExt, filename, toExt) + } else if err := convert(f, t, filename); err != nil { + return err } } return nil } +func convert(d Decoder, e Encoder, filename string) (err error) { + // open file + r, err := os.Open(filename + "." + fromExt) + if err != nil { + return + } + defer r.Close() + + // decode + img, err := d.Decode(r) + if err != nil { + return + } + + // create file + w, err := os.Create(filename + "." + toExt) + if err != nil { + return err + } + + defer func() { + err = w.Close() + }() + + // encode + if err := e.Encode(w, img); err != nil { + return err + } + + return +} + func getTargetFilePaths(args Args, from string) ([]string, error) { uns := args.uniq() - paths := []string{} + paths := []string{} for _, n := range uns { + if ok, err := isDir(n); err != nil { + return nil, err + } else if !ok { + return nil, fmt.Errorf("%s is not a directory", n) + } + if err := filepath.Walk(n, func(path string, info os.FileInfo, err error) error { if filepath.Ext(path) == "."+from { paths = append(paths, path) @@ -63,16 +101,16 @@ func getTargetFilePaths(args Args, from string) ([]string, error) { return paths, nil } -func createConvImages(paths []string, from, to string) ([]convImage, error) { - images := []convImage{} - for _, p := range paths { - i := convImage{ - filename: strings.Replace(p, "."+from, "", 1), - fromExt: strings.ToLower(from), - toExt: strings.ToLower(to), - } - images = append(images, i) +func isDir(path string) (bool, error) { + f, err := os.Open(path) + if err != nil { + return false, err + } + + fi, err := f.Stat() + if err != nil { + return false, err } - return images, nil + return fi.IsDir(), nil } diff --git a/kadai1/tanaka0325/imgconv/options.go b/kadai1/tanaka0325/imgconv/options.go index 3a31e15..1d91f04 100644 --- a/kadai1/tanaka0325/imgconv/options.go +++ b/kadai1/tanaka0325/imgconv/options.go @@ -13,13 +13,14 @@ type Options struct { DryRun *bool } -func (opt Options) validate(allow_list []string) error { +func (opt Options) validate(allowList []string) error { to := strings.ToLower(*opt.To) from := strings.ToLower(*opt.From) targetExts := []string{to, from} + for _, e := range targetExts { - if err := include(allow_list, e); err != nil { - return fmt.Errorf("%w. ext is only allowd in %s", err, allow_list) + if err := include(allowList, e); err != nil { + return fmt.Errorf("%w. ext is only allowd in %s", err, allowList) } } From 4d6cc8d5c721d3e0c4b169742c3e426001a90d75 Mon Sep 17 00:00:00 2001 From: Hiroyuki Tanaka Date: Sat, 18 Jul 2020 12:50:58 +0900 Subject: [PATCH 9/9] Fix typo --- kadai1/tanaka0325/imgconv/options.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kadai1/tanaka0325/imgconv/options.go b/kadai1/tanaka0325/imgconv/options.go index 1d91f04..e3e231c 100644 --- a/kadai1/tanaka0325/imgconv/options.go +++ b/kadai1/tanaka0325/imgconv/options.go @@ -6,7 +6,7 @@ import ( "strings" ) -// Args is type for command line options. +// Options is type for command line options. type Options struct { From *string To *string