-
Notifications
You must be signed in to change notification settings - Fork 6
kadai1-shinta #3
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
base: master
Are you sure you want to change the base?
Changes from 5 commits
2b3d105
a679450
64d4b94
83715d4
a92ff4d
e2f69b0
3f051bf
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 @@ | ||
testdatadir |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# 課題1 | ||
## 次の仕様を満たすコマンドを作って下さい | ||
- ディレクトリを指定する | ||
|
||
- 指定したディレクトリ以下のJPGファイルをPNGに変換(デフォルト) | ||
|
||
- ディレクトリ以下は再帰的に処理する | ||
|
||
- 変換前と変換後の画像形式を指定できる(オプション) | ||
|
||
- 以下を満たすように開発してください | ||
|
||
- mainパッケージと分離する | ||
|
||
- 自作パッケージと標準パッケージと準標準パッケージのみ使う | ||
|
||
- ユーザ定義型を作ってみる | ||
|
||
- GoDocを生成してみる | ||
|
||
## 使い方 | ||
``` | ||
# build | ||
go build -o "任意のコマンド名" | ||
# 例 | ||
go build -o imgcov | ||
# 実行方法(上記の例の場合) | ||
imgcov [-d=ディレクトリ(default ./), -p=変更対象の拡張子(default jpg), -a=変更後の拡張子(default png)] | ||
# 変換可能な拡張子として、jpg、jpeg、png、gif としています。 | ||
``` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module github.com/gopherdojo/dojo7/kadai1/shinta | ||
|
||
go 1.12 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
/* | ||
Package imageconversion は画像ファイル形式の変換を行います。 | ||
optionで、実行するディレクトリと変換前と変換後の画像形式を指定できます。 | ||
option を指定しない場合、コマンドを実行するディレクトリと、 変換前の画像タイプがjpeg、変換後の画像タイプがpngになります。 | ||
変換可能な拡張子として、jpg、jpeg、png、gif としています。 | ||
*/ | ||
package imageconversion | ||
|
||
import ( | ||
"errors" | ||
"flag" | ||
"image" | ||
"image/gif" | ||
"image/jpeg" | ||
"image/png" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
// judgeArgExt は引数に設定された拡張子が変換可能なものか判別する | ||
func judgeArgExt(preExt string, afterExt string) (err error) { | ||
allowExtList := []string{"jpg", "jpeg", "png", "gif"} | ||
argExtList := []string{preExt, afterExt} | ||
var judgeExtFlag bool | ||
for _, argExt := range argExtList { | ||
// 変換前の拡張子の判定結果が正しい場合、フラグを初期化する。 | ||
if judgeExtFlag { | ||
judgeExtFlag = false | ||
} | ||
// 拡張子が正しい拡張子か判定する。 | ||
for _, allowExt := range allowExtList { | ||
if allowExt == argExt { | ||
judgeExtFlag = true | ||
} | ||
} | ||
// 拡張子判定結果が正しくない場合breakする。フラグはfalseになる。 | ||
if !judgeExtFlag { | ||
break | ||
} | ||
} | ||
if !judgeExtFlag { | ||
err = errors.New("指定できる拡張子:" + strings.Join(allowExtList, ",")) | ||
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. 直接 |
||
} | ||
return | ||
} | ||
|
||
// passArgs は引数を受け取りその引数(ディレクトリ、変換前拡張子、変換後拡張子)が正しいか判別し、引数の値を返します。 | ||
func passArgs() (dir string, preExt string, afterExt string, err error) { | ||
d := flag.String("d", "./", "対象ディレクトリ") | ||
p := flag.String("p", "jpg", "変換前拡張子") | ||
a := flag.String("a", "png", "変換後拡張子") | ||
flag.Parse() | ||
dir, preExt, afterExt = *d, *p, *a | ||
err = judgeArgExt(preExt, afterExt) | ||
if err != nil { | ||
return | ||
} | ||
preExt = "." + preExt | ||
afterExt = "." + afterExt | ||
return | ||
} | ||
|
||
// imageFile struct は変換対象の画像のpath(path)、拡張子を除いたファイル名(base)、拡張子(ext)を持っています。 | ||
type imageFile struct { | ||
path string | ||
base string | ||
ext string | ||
} | ||
|
||
// getFileNameWithoutExt は対象ファイルのpathと拡張子を除いたファイル名を返します。 | ||
func getFileNameWithoutExt(path string) string { | ||
return filepath.Base(path[:len(path)-len(filepath.Ext(path))]) | ||
} | ||
|
||
// createImgStrunct は、imageFile structを生成し、返します。 | ||
func createImgStruct(path string) (image imageFile) { | ||
base := getFileNameWithoutExt(path) | ||
image = imageFile{filepath.Dir(path), base, filepath.Ext(path)} | ||
return | ||
} | ||
|
||
/* | ||
convertExec は画像ファイルを引数で指定された変換後の拡張子(defaultはpng)に変換した新しい画像ファイルを生成します。 | ||
処理が成功するとnil、errorが起きた場合、errorを返します。 | ||
*/ | ||
func convertExec(path string, afterExt string) (err error) { | ||
img := createImgStruct(path) | ||
targetImg, err := os.Open(img.path + "/" + img.base + img.ext) | ||
if err != nil { | ||
return err | ||
} | ||
readImg, _, err := image.Decode(targetImg) | ||
if err != nil { | ||
return err | ||
} | ||
outputImg, err := os.Create((img.path + "/" + img.base + afterExt)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
switch afterExt { | ||
case "jpeg", "jpg": | ||
jpeg.Encode(outputImg, readImg, nil) | ||
case "gif": | ||
gif.Encode(outputImg, readImg, nil) | ||
default: | ||
png.Encode(outputImg, readImg) | ||
} | ||
|
||
targetImg.Close() | ||
outputImg.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. エラー処理 |
||
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. 不要 |
||
} | ||
|
||
/* | ||
convertImages は、引数で指定されたディレクトリ以下から引数で指定した変換前拡張子(defaultはjpg)のファイルを、 | ||
変換後拡張子(defaultはpng)に変換した新しい画像ファイルを生成します。 | ||
処理が成功するとnil、errorが起きた場合、errorを返します。 | ||
*/ | ||
func convertImages(dir string, preExt string, afterExt string) (err error) { | ||
// 変換対象ファイルが jpeg or jpg かを確認する | ||
jpgType := [2]string{".jpg", ".jpeg"} | ||
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. コメントに記載のvalue無しではなく、下記のように宣言するということであってますでしょうか?(missing key in map literal エラーになるので)
|
||
var jpgFlag bool | ||
for _, v := range jpgType { | ||
if preExt == v { | ||
jpgFlag = true | ||
} | ||
} | ||
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { | ||
if err != nil { | ||
return err | ||
} | ||
// jpeg は jpgも変換対象とする | ||
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. 以下、すべて対象 |
||
if jpgFlag && filepath.Ext(path) == ".jpeg" || filepath.Ext(path) == ".jpg" { | ||
convertExec(path, afterExt) | ||
} | ||
if filepath.Ext(path) == preExt { | ||
convertExec(path, afterExt) | ||
} | ||
return nil | ||
}) | ||
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. return errする |
||
} | ||
|
||
/* | ||
Excute は画像変換処理を実行します。 | ||
このpackageで呼び出せる唯一の関数です。 | ||
引数で、ディレクトリ(デフォルトは ./)、変換前拡張子(デフォルトは jpg)、変換後拡張子(デフォルトは png)を受け取ります。 | ||
引数が指定されない場合はデフォルトの値が適用されます。 | ||
引数で受け取ったディレクトリ以下の変換前拡張子のファイルを変換後拡張子に変換した新しいファイルを作成します。 | ||
処理が成功の場合、nilをerrorが起きた場合はerrorを返します。 | ||
*/ | ||
func Excute() error { | ||
dir, preExt, afterExt, err := passArgs() | ||
if err != nil { | ||
return err | ||
} | ||
err = convertImages(dir, preExt, afterExt) | ||
return err | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/gopherdojo/dojo7/kadai1/shinta/imageconversion" | ||
) | ||
|
||
func main() { | ||
err := imageconversion.Excute() | ||
if err != nil { | ||
fmt.Fprintln(os.Stderr, err) | ||
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. os.Exitで終了コードを指定する |
||
} | ||
} |
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.
map[string]bool
を使う