generated from gopherdojo/template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
284 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# 課題 1 画像変換コマンドを作ろう | ||
|
||
## 課題内容 | ||
### 次の仕様を満たすコマンドを作って下さい | ||
|
||
- ディレクトリを指定する | ||
- 指定したディレクトリ以下の JPG ファイルを PNG に変換(デフォルト) | ||
- ディレクトリ以下は再帰的に処理する | ||
- 変換前と変換後の画像形式を指定できる(オプション) | ||
|
||
### 以下を満たすように開発してください | ||
|
||
- main パッケージと分離する | ||
- 自作パッケージと標準パッケージと準標準パッケージのみ使う | ||
- 準標準パッケージ:golang.org/x 以下のパッケージ | ||
- ユーザ定義型を作ってみる | ||
- GoDoc を生成してみる | ||
- Go Modules を使ってみる | ||
|
||
## 対応したこと | ||
- 画像を変換 | ||
- 現状はjpg, pngのみ | ||
- jpg, png以外はエラー表示 | ||
- 画像出力先は対象画像と同じディレクトリ | ||
- 指定したディレクトリが無いとエラーを表示 | ||
|
||
## 動作 | ||
```shell | ||
$ go build -o test_imgconv | ||
|
||
$ ./test_imgconv -h | ||
Usage of ./test_imgconv: | ||
-from string | ||
Conversion source extension. (default "jpg") | ||
-to string | ||
Conversion target extension. (default "png") | ||
|
||
# testdata内のすべてのjpgファイルをpngに変換する | ||
$ ./test_imgconv testdata | ||
Conversion finished! | ||
|
||
# testdata内のすべてのpngファイルをjpgに変換する | ||
$ ./test_imgconv -from png -to jpg testdata | ||
Conversion finished! | ||
|
||
# ディレクトリの指定が無い場合はエラー | ||
$ ./test_imgconv | ||
Please specify a directory. | ||
|
||
# 存在しないディレクトリの場合はエラー | ||
$ ./test_imgconv non_exist_dir | ||
Cannot find directory. | ||
|
||
# 対応していない拡張子の場合はエラー | ||
$ ./test_imgconv -from txt -to jpg testdata | ||
Selected extension is not supported. | ||
``` | ||
|
||
## 工夫したこと | ||
- png, jpg以外にも拡張子が増えそうなので、`image_type`というinterfaceを作ってみた。 | ||
- 拡張子の微妙な違い(jpg, jpeg, JPGなど)にも対応できるようにした。 | ||
|
||
## わからなかったこと、むずかしかったこと | ||
- go mod initで指定するmodule名に命名規則があるのか。 | ||
- 普段オブジェクト指向(その上動的型付け言語)で書いているので、それがgoらしいコードになっているのか不安。 | ||
- なんでもかんでも構造体メソッドにしたい願望がでてくる |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module imgconv | ||
|
||
go 1.14 |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package imgconv | ||
|
||
import ( | ||
"image" | ||
"os" | ||
"path/filepath" | ||
) | ||
|
||
func converterFactory(from string, to string) (*Converter, error) { | ||
fromImage, err := selectImage("." + from) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
toImage, err := selectImage("." + to) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &Converter{fromImage, toImage}, nil | ||
} | ||
|
||
type Converter struct { | ||
fromImage ImageType | ||
toImage ImageType | ||
} | ||
|
||
func (conv *Converter) Execute(path string) error { | ||
// ignore unrelated file | ||
if !conv.fromImage.IsMatchExt(filepath.Ext(path)) { | ||
return nil | ||
} | ||
|
||
// file open | ||
file, err := os.Open(path) | ||
defer file.Close() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// convert to image obj | ||
img, _, err := image.Decode(file) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// output file | ||
out, err := os.Create(conv.SwitchExt(path)) | ||
defer out.Close() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// output image | ||
conv.toImage.Encode(out, img) | ||
return nil | ||
} | ||
|
||
func (conv *Converter) SwitchExt(path string) string { | ||
ext := filepath.Ext(path) | ||
toExt := conv.toImage.Extensions()[0] | ||
|
||
return path[:len(path)-len(ext)] + toExt | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package imgconv | ||
|
||
import ( | ||
"errors" | ||
"image" | ||
"io" | ||
) | ||
|
||
type ImageType interface { | ||
Encode(w io.Writer, m image.Image) error | ||
IsMatchExt(ext string) bool | ||
Extensions() []string | ||
} | ||
|
||
func selectImage(ext string) (ImageType, error) { | ||
pngImage := PngImage{} | ||
jpegImage := JpegImage{} | ||
|
||
if pngImage.IsMatchExt(ext) { | ||
return pngImage, nil | ||
} else if jpegImage.IsMatchExt(ext) { | ||
return jpegImage, nil | ||
} | ||
|
||
return nil, errors.New("Selected extension is not supported.") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package imgconv | ||
|
||
import ( | ||
"errors" | ||
"flag" | ||
"os" | ||
"path/filepath" | ||
) | ||
|
||
func Call() error { | ||
var ( | ||
from = flag.String("from", "jpg", "Conversion source extension.") | ||
to = flag.String("to", "png", "Conversion target extension.") | ||
) | ||
flag.Parse() | ||
dir := flag.Arg(0) | ||
|
||
if flag.Arg(0) == "" { | ||
return errors.New("Please specify a directory.") | ||
} | ||
|
||
if f, err := os.Stat(dir); os.IsNotExist(err) || !f.IsDir() { | ||
return errors.New("Cannot find directory.") | ||
} | ||
|
||
converter, err := converterFactory(*from, *to) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = filepath.Walk(dir, | ||
func(path string, info os.FileInfo, err error) error { | ||
err = converter.Execute(path) | ||
return err | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package imgconv | ||
|
||
import ( | ||
"image" | ||
"image/jpeg" | ||
"io" | ||
) | ||
|
||
const QUALITY = 100 | ||
|
||
type JpegImage struct{} | ||
|
||
func (_ JpegImage) Encode(w io.Writer, m image.Image) error { | ||
err := jpeg.Encode(w, m, &jpeg.Options{Quality: QUALITY}) | ||
return err | ||
} | ||
|
||
func (ji JpegImage) IsMatchExt(ext string) bool { | ||
for _, myExt := range ji.Extensions() { | ||
if ext == myExt { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func (_ JpegImage) Extensions() []string { | ||
return []string{".jpg", ".jpeg", ".JPG", ".JPEG"} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package imgconv | ||
|
||
import ( | ||
"image" | ||
"image/png" | ||
"io" | ||
) | ||
|
||
type PngImage struct{} | ||
|
||
func (_ PngImage) Encode(w io.Writer, m image.Image) error { | ||
err := png.Encode(w, m) | ||
return err | ||
} | ||
|
||
func (pi PngImage) IsMatchExt(ext string) bool { | ||
for _, myExt := range pi.Extensions() { | ||
if ext == myExt { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func (_ PngImage) Extensions() []string { | ||
return []string{".png", ".PNG"} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"imgconv/imgconv" | ||
"os" | ||
) | ||
|
||
const ( | ||
ExitCodeOk int = iota | ||
ExitCodeError | ||
) | ||
|
||
func main() { | ||
os.Exit(run()) | ||
} | ||
|
||
func run() int { | ||
err := imgconv.Call() | ||
|
||
if err != nil { | ||
fmt.Fprintln(os.Stderr, err) | ||
return ExitCodeError | ||
} | ||
|
||
fmt.Println("Conversion finished!") | ||
return ExitCodeOk | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.