-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
# Wataru / boru 課題1 #2
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.idea | ||
.DS_Store |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# 課題 1 【TRY】画像変換コマンドを作ろう | ||
|
||
## 次の仕様を満たすコマンドを作って下さい | ||
|
||
- ディレクトリを指定する | ||
- 指定したディレクトリ以下の JPG ファイルを PNG に変換(デフォルト) | ||
- ディレクトリ以下は再帰的に処理する | ||
- 変換前と変換後の画像形式を指定できる(オプション) | ||
|
||
## 以下を満たすように開発してください | ||
|
||
- main パッケージと分離する | ||
- 自作パッケージと標準パッケージと準標準パッケージのみ使う | ||
- 準標準パッケージ:golang.org/x 以下のパッケージ | ||
- ユーザ定義型を作ってみる | ||
- GoDoc を生成してみる | ||
- Go Modules を使ってみる | ||
|
||
### 動作手順 | ||
|
||
``` | ||
$ go build -o imgconv | ||
$ ./imgconv -h | ||
Usage of ./imgconv: | ||
-a string | ||
Input extension after conversion. (short) (default "png") | ||
-after --after=jpg | ||
Input extension after conversion. | ||
ex) --after=jpg (default "png") | ||
-b string | ||
Input extension before conversion. (short) (default "jpg") | ||
-before --before=png | ||
Input extension before conversion. | ||
ex) --before=png (default "jpg") | ||
-d string | ||
Input target Directory. (short) | ||
-dir --dir=./convert_image | ||
Input target Directory. | ||
ex) --dir=./convert_image | ||
$ ./imgconv -d ./testdate | ||
or | ||
$ ./imgconv -d ./testdate -b png -a gif | ||
or | ||
$ ./imgconv -d ./testdate -b jpeg -a tiff | ||
``` | ||
|
||
### 感想等 | ||
|
||
- 前提として、@tenntennさんの公開されている[handsonプロジェクト](https://github.com/tenntenn/gohandson/tree/master/imgconv/ja)と似ている内容でして、以前やったことがありました。 | ||
- そちらに無い部分として、tiff変換やbmp変換の追加などを行いました。 | ||
- GoModulesを利用したく、`golang.org/x/image`を導入しました | ||
- 様々なソースをみていると、変数名やコマンド名が自分は冗長かな?と感じています。Go話者の方は短く記載するものなのでしょうか。 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/gopherdojo/dojo8/kadai1/wataboru/imageconverter" | ||
|
||
"flag" | ||
"fmt" | ||
"os" | ||
) | ||
|
||
const ( | ||
// ExitCodeSuccess is the exit code on success | ||
ExitCodeSuccess = 0 | ||
// ExitCodeError is the exit code when failed | ||
ExitCodeError = 1 | ||
// ExitCodeError is the exit code when failed | ||
ExitCodeInvalidDirectoryError = 2 | ||
) | ||
|
||
var ( | ||
args imageconverter.Args | ||
) | ||
|
||
func init() { | ||
flag.StringVar(&args.Directory, "dir", "", "Input target Directory.\n ex) `--dir=./convert_image`") | ||
flag.StringVar(&args.Directory, "d", "", "Input target Directory. (short)") | ||
flag.StringVar(&args.BeforeExtension, "before", "jpg", "Input extension before conversion.\n ex) `--before=png`") | ||
flag.StringVar(&args.BeforeExtension, "b", "jpg", "Input extension before conversion. (short)") | ||
flag.StringVar(&args.AfterExtension, "after", "png", "Input extension after conversion.\n ex) `--after=jpg`") | ||
flag.StringVar(&args.AfterExtension, "a", "png", "Input extension after conversion. (short)") | ||
flag.Parse() | ||
} | ||
|
||
func run() int { | ||
if args.Directory == "" { | ||
fmt.Fprintln(os.Stderr, "Input target Directory.\n ex) `--dir=./convert_image`") | ||
return ExitCodeInvalidDirectoryError | ||
} | ||
|
||
if _, err := os.Stat(args.Directory); os.IsNotExist(err) { | ||
fmt.Fprintln(os.Stderr, "Target directory is not found.") | ||
return ExitCodeInvalidDirectoryError | ||
} | ||
|
||
if err := imageconverter.Convert(args); err != nil { | ||
fmt.Fprintln(os.Stderr, err.Error()) | ||
return ExitCodeError | ||
} | ||
|
||
return ExitCodeSuccess | ||
} | ||
|
||
func main() { | ||
os.Exit(run()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module github.com/gopherdojo/dojo8/kadai1/wataboru | ||
|
||
go 1.14 | ||
|
||
require golang.org/x/image v0.0.0-20200618115811-c13761719519 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
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= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package imageconverter | ||
|
||
import ( | ||
"fmt" | ||
"image" | ||
"image/gif" | ||
"image/jpeg" | ||
"image/png" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"golang.org/x/image/bmp" | ||
"golang.org/x/image/tiff" | ||
) | ||
|
||
type Args struct { | ||
Directory string | ||
BeforeExtension string | ||
AfterExtension string | ||
} | ||
|
||
func convertImage(source, dest string) (err error) { | ||
sourceFile, err := os.Open(source) | ||
if err != nil { | ||
return fmt.Errorf("file could not be opened. target: %s", source) | ||
} | ||
defer sourceFile.Close() | ||
|
||
destFile, err := os.Create(dest) | ||
if err != nil { | ||
return fmt.Errorf("image file could not be created. target: %s", dest) | ||
} | ||
|
||
defer func(returnErr error) { | ||
if returnErr == nil { | ||
err = destFile.Close() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tenntenn 他の方のレビューの中で、「何をreturnしたか追いづらいので、名前付き戻り値はできるだけ使わない。」とあったので、名前付き戻り値を使わずにどのように呼び出し元にエラーを返したら良いか教えていただきたいです。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. このパターンのみ使わないとどうにもならないので使っても大丈夫です! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tenntenn |
||
} | ||
}(err) | ||
|
||
img, _, err := image.Decode(sourceFile) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
switch strings.ToLower(filepath.Ext(dest)) { | ||
case ".png": | ||
err = png.Encode(destFile, img) | ||
case ".jpg", ".jpeg": | ||
err = jpeg.Encode(destFile, img, &jpeg.Options{Quality: jpeg.DefaultQuality}) | ||
case ".gif": | ||
err = gif.Encode(destFile, img, &gif.Options{256, nil, nil}) | ||
case ".bmp": | ||
err = bmp.Encode(destFile, img) | ||
case ".tiff": | ||
err = tiff.Encode(destFile, img, nil) | ||
default: | ||
err = fmt.Errorf("image file could not be created due to an unknown extension. target: %s", dest) | ||
} | ||
|
||
return err | ||
} | ||
|
||
// 指定したディレクトリ以下のJPGファイルをPNGに変換(デフォルト) | ||
// ディレクトリ以下は再帰的に処理する | ||
// 変換前と変換後の画像形式を指定できる(オプション) | ||
func Convert(args Args) error { | ||
return filepath.Walk(args.Directory, func(path string, info os.FileInfo, err error) error { | ||
if err != nil { | ||
return fmt.Errorf("prevent panic by handling failure accessing a path %q: %v\n", path, err) | ||
} | ||
|
||
ext := strings.ToLower(filepath.Ext(path)) | ||
if "."+args.BeforeExtension != ext { | ||
return nil | ||
} | ||
|
||
return convertImage(path, replaceExt(info.Name(), "."+args.AfterExtension)) | ||
}) | ||
} | ||
|
||
func replaceExt(filePath, toExt string) string { | ||
return filePath[:len(filePath)-len(filepath.Ext(filePath))] + toExt | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍