From e41be5a4c04eeefcd25e4ecf089d1c39af01107a Mon Sep 17 00:00:00 2001 From: Ino Ayaka <60222003+InoAyaka@users.noreply.github.com> Date: Mon, 6 Jul 2020 23:19:49 +0900 Subject: [PATCH] Add files via upload --- kadai1/InoAyaka/README.md | 46 ++++++++++++++ kadai1/InoAyaka/converter/converter.go | 84 ++++++++++++++++++++++++++ kadai1/InoAyaka/go.mod | 5 ++ kadai1/InoAyaka/go.sum | 4 ++ kadai1/InoAyaka/imageConv.go | 75 +++++++++++++++++++++++ 5 files changed, 214 insertions(+) create mode 100644 kadai1/InoAyaka/README.md create mode 100644 kadai1/InoAyaka/converter/converter.go create mode 100644 kadai1/InoAyaka/go.mod create mode 100644 kadai1/InoAyaka/go.sum create mode 100644 kadai1/InoAyaka/imageConv.go diff --git a/kadai1/InoAyaka/README.md b/kadai1/InoAyaka/README.md new file mode 100644 index 0000000..2cace57 --- /dev/null +++ b/kadai1/InoAyaka/README.md @@ -0,0 +1,46 @@ +# <課題1>【TRY】画像変換コマンドを作ろう +## 概要 +### 次の仕様を満たすコマンドを作って下さい + +- ディレクトリを指定する +- 指定したディレクトリ以下のJPGファイルをPNGに変換(デフォルト) +- ディレクトリ以下は再帰的に処理する +- 変換前と変換後の画像形式を指定できる(オプション) + + +### 以下を満たすように開発してください + +- mainパッケージと分離する +- 自作パッケージと標準パッケージと準標準パッケージのみ使う +- 準標準パッケージ:golang.org/x以下のパッケージ +- ユーザ定義型を作ってみる +- GoDocを生成してみる +- Go Modulesを使ってみる + + +## 使い方 +``` +$ go build -o imageConv +$ +$ ./imageConv -h +Usage of ./imageConv: + -af string + Image format after conversion (default "png") + -bf string + Image format before conversion (default "jpg") + -dir string + Directory containing images to be converted +$ +$ +``` + +実行例 +``` +$ ./imageConv -bf=png -af=gif -dir=./image +``` + +### 感想 + +- mainパッケージと自作パッケージの分離をどこにするのか悩みました。(画像変換部分のみを切り出して自作パッケージにしましたが、ディレクトリを渡して検索〜変換までの一連の処理をパッケージに纏めた方が良かったのかもしれないと考えています。) +- errの扱いについても、errを返してmainで一貫して処理を行うのか、それぞれで行うべきなのか悩んだ点になります。 +- 画像変換を行うImageConverter()での、errチェックを行う部分が適切かも少し不安な点ではあります。 diff --git a/kadai1/InoAyaka/converter/converter.go b/kadai1/InoAyaka/converter/converter.go new file mode 100644 index 0000000..17ce22f --- /dev/null +++ b/kadai1/InoAyaka/converter/converter.go @@ -0,0 +1,84 @@ +//Package converter は指定されたパスに対し、画像変換を行います。 +//(対応形式:jpg,png,gif,bmp,tiff) +package converter + +import ( + "fmt" + "image" + "image/gif" + "image/jpeg" + "image/png" + "os" + "regexp" + "strings" + + "golang.org/x/image/bmp" + "golang.org/x/image/tiff" +) + +//Args ImageConverter()を使う際に指定が必要となる引数 +type Args struct { + FilePath string //変換対象となるファイル名 + Bf string //変換前 画像形式 + Af string //変換後 画像形式 +} + +//ImageConverter 指定した画像形式に変換を行います。 +func ImageConverter(a Args) error { + + f, err := os.Open(a.FilePath) + if err != nil { + return addFileName(err, a.FilePath) + } + defer f.Close() + + //ファイルオブジェクトを画像オブジェクトに変換 + img, _, err := image.Decode(f) + if err != nil { + return addFileName(err, f.Name()) + } + + //変換後のファイルパス + rep := regexp.MustCompile("(?i)" + a.Bf + "$") + outFilePath := rep.ReplaceAllString(f.Name(), a.Af) + + //変換後ファイルの新規作成 + out, err := os.Create(outFilePath) + if err != nil { + return addFileName(err, f.Name()) + } + + //変換する画像形式に応じてエンコードする + switch strings.ToLower(a.Af) { + case "jpg": + err = jpeg.Encode(out, img, &jpeg.Options{Quality: jpeg.DefaultQuality}) + case "png": + err = png.Encode(out, img) + case "gif": + err = gif.Encode(out, img, &gif.Options{NumColors: 256, Quantizer: nil, Drawer: nil}) + case "bmp": + err = bmp.Encode(out, img) + case "tiff": + err = tiff.Encode(out, img, &tiff.Options{Compression: 0, Predictor: true}) + default: + fmt.Println("The specified image format is not supported. : " + f.Name()) + } + + //エンコード時にエラーが返ってきていないかチェック + if err != nil { + return addFileName(err, out.Name()) + } + + if err := out.Close(); err != nil { + return addFileName(err, out.Name()) + } + + return nil + +} + +//addFileName どのファイルでエラーになったか分かるようにerrにファイル名を付加して返します。 +func addFileName(err error, f string) error { + err = fmt.Errorf("%v\nerrFile : %s", err, f) + return err +} diff --git a/kadai1/InoAyaka/go.mod b/kadai1/InoAyaka/go.mod new file mode 100644 index 0000000..5cedc3a --- /dev/null +++ b/kadai1/InoAyaka/go.mod @@ -0,0 +1,5 @@ +module github.com/gopherdojo/dojo8/kadai1/InAyk + +go 1.14 + +require golang.org/x/image v0.0.0-20200618115811-c13761719519 diff --git a/kadai1/InoAyaka/go.sum b/kadai1/InoAyaka/go.sum new file mode 100644 index 0000000..83da957 --- /dev/null +++ b/kadai1/InoAyaka/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/InoAyaka/imageConv.go b/kadai1/InoAyaka/imageConv.go new file mode 100644 index 0000000..b986eed --- /dev/null +++ b/kadai1/InoAyaka/imageConv.go @@ -0,0 +1,75 @@ +//画像変換を行います。 +package main + +import ( + "flag" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/gopherdojo/dojo8/kadai1/InAyk/converter" +) + +//オプション指定 +var bf = flag.String("bf", "jpg", "Image format before conversion") +var af = flag.String("af", "png", "Image format after conversion") +var dir = flag.String("dir", "", "Directory containing images to be converted") + +func main() { + //オプションの解析 + flag.Parse() + + //入力されたディレクトリのチェックをかける + if err := checkDir(); err != nil { + //入力チェックで返ってきたらエラーを出力し、プログラムを終了させる + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + convert() + +} + +//checkDir 指定されたディレクトリのチェックを行います。 +//チェック内容:引数の値、ディレクトリの存在、ディレクトリを表しているか +func checkDir() error { + //引数の数チェック + if *dir == "" { + return fmt.Errorf("No directory specified") + } + + //ディレクトリの存在チェック & ディレクトリを表しているかどうか + if m, err := os.Stat(*dir); os.IsNotExist(err) { + return err + } else if !m.IsDir() { + return fmt.Errorf("%s : not a directory", *dir) + } + + return nil + +} + +//convert 指定ディレクトリに対し、画像変換を行います。 +func convert() { + + ca := converter.Args{ + Bf: strings.ToLower(*bf), + Af: strings.ToLower(*af), + } + + //ディレクトリを再帰的にチェック + filepath.Walk(*dir, func(path string, info os.FileInfo, err error) error { + + //対象の画像形式のみ画像変換ImageConverter()の実行 + if strings.ToLower(filepath.Ext(path)) == "."+*bf { + ca.FilePath = path + if err := converter.ImageConverter(ca); err != nil { + //エラーが返ってきても、エラーを表示しプログラムは続行 + fmt.Fprintln(os.Stderr, err) + } + } + return nil + }) + +}