diff --git a/kadai1/karasuex54/README.md b/kadai1/karasuex54/README.md new file mode 100644 index 00000000..2d151bce --- /dev/null +++ b/kadai1/karasuex54/README.md @@ -0,0 +1,26 @@ +# 画像変換コマンドを作ろう + +## 次の仕様を満たすコマンドを作成 +- ディレクトリを指定 +- 指定したディレクトリ以下のJPGファイルをPNGに変換(デフォルト) +- ディレクトリ以下は再帰的に処理 +- 変換前と変換後の画像形式を指定可能(オプション) + +## 以下を満たすように開発 +- mainパッケージと分離 +- 自作パッケージと標準パッケージと準標準パッケージのみを使用 + - 準標準パッケージ:golang.org/x以下のパッケージ +- ユーザ定義型を作成 +- GoDocを生成 +- Go Modulesを使用 + +## 使い方 +1.バイナリファイル作成 +```sh +go build -o main +``` + +2.コマンド実行 +```sh +./main -from=[jpg|jpeg|png|gif] -to=[jpg|jpeg|png|gif] <変換する画像の入ったフォルダのパス> +``` \ No newline at end of file diff --git a/kadai1/karasuex54/converter/converter.go b/kadai1/karasuex54/converter/converter.go new file mode 100644 index 00000000..684d8cbc --- /dev/null +++ b/kadai1/karasuex54/converter/converter.go @@ -0,0 +1,121 @@ +// Package converter is image file convert package. +package converter + +import ( + "fmt" + "image" + "image/gif" + "image/jpeg" + "image/png" + "io" + "os" + "path/filepath" +) + +// Converter is a struct that has target directory, target file extention and convert file extention. +type Converter struct { + targetDir string + fromExt string + toExt string +} + +type Option func(*Converter) error + +func FromExt(ext string) Option { + return func(c *Converter) error { + c.fromExt = ext + return nil + } +} + +func ToExt(ext string) Option { + return func(c *Converter) error { + c.toExt = ext + return nil + } +} + +// Decode reads an image from r and returns it as an image.Image. +func (c Converter) Decode(r io.Reader) (image.Image, error) { + switch c.fromExt { + case "png": + return png.Decode(r) + case "jpg", "jpeg": + return jpeg.Decode(r) + case "gif": + return gif.Decode(r) + default: + return nil, fmt.Errorf("fail setting Converter.fromExt") + } +} + +// Encode writes the Image m to w in c.toExt format. +func (c Converter) Encode(w io.Writer, m image.Image) error { + switch c.toExt { + case "png": + return png.Encode(w, m) + case "jpg", "jpeg": + return jpeg.Encode(w, m, &jpeg.Options{Quality: 100}) + case "gif": + return gif.Encode(w, m, &gif.Options{NumColors: 256}) + default: + return fmt.Errorf("fail setting Converter.toExt") + } +} + +// Convert reads an image file from path, creates a file, and writes to it in c.toExt format. +func (c Converter) Convert(path string) error { + sf, err := os.Open(path) + if err != nil { + return err + } + defer sf.Close() + img, err := c.Decode(sf) + if err != nil { + return err + } + fileName := filepath.Base(path) + convertedPath := fileName[:len(fileName)-len(filepath.Ext(path))] + "." + c.toExt + df, err := os.Create(convertedPath) + if err != nil { + return err + } + defer df.Close() + err = c.Encode(df, img) + if err != nil { + if removeErr := os.Remove(convertedPath); removeErr != nil { + return removeErr + } + return err + } + return nil +} + +// Run finds files of c.fromExt form in the directories and files under c.targetDir. It passes the path of the file as an argument to c.Convert(). +func (c Converter) Run() { + ext := "." + c.fromExt + err := filepath.Walk(c.targetDir, + func(path string, info os.FileInfo, err error) error { + if filepath.Ext(path) == ext { + c.Convert(path) + } + return nil + }) + if err != nil { + fmt.Println("error :", err) + return + } +} + +// NewConverter returns c.Converter. +func NewConverter(dirPath string, options ...Option) *Converter { + c := Converter{ + targetDir: dirPath, + fromExt: "jpg", + toExt: "png", + } + for _, option := range options { + option(&c) + } + return &c +} diff --git a/kadai1/karasuex54/go.mod b/kadai1/karasuex54/go.mod new file mode 100644 index 00000000..25b458a0 --- /dev/null +++ b/kadai1/karasuex54/go.mod @@ -0,0 +1,3 @@ +module github.com/karasuex54/gopherdojo-studyroom/kadai1/karasuex54 + +go 1.17 diff --git a/kadai1/karasuex54/main.go b/kadai1/karasuex54/main.go new file mode 100644 index 00000000..03f7b86b --- /dev/null +++ b/kadai1/karasuex54/main.go @@ -0,0 +1,35 @@ +package main + +import ( + "flag" + "fmt" + + "github.com/karasuex54/gopherdojo-studyroom/kadai1/karasuex54/converter" +) + +var ( + targetDir string + fromExt string + toExt string +) + +func main() { + flag.StringVar(&fromExt, "from", "jpg", "target image file extention") + flag.StringVar(&toExt, "to", "png", "convert image file extention") + flag.Parse() + + args := flag.Args() + switch len(args) { + case 0: + fmt.Println("few arguments") + return + case 1: + targetDir = args[0] + default: + fmt.Println("too arguments") + return + } + + c := converter.NewConverter(targetDir, converter.FromExt(fromExt), converter.ToExt(toExt)) + c.Run() +}