Skip to content
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

Kadai1 karasuex54 #84

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions kadai1/karasuex54/README.md
Original file line number Diff line number Diff line change
@@ -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] <変換する画像の入ったフォルダのパス>
```
121 changes: 121 additions & 0 deletions kadai1/karasuex54/converter/converter.go
Original file line number Diff line number Diff line change
@@ -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
}
3 changes: 3 additions & 0 deletions kadai1/karasuex54/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/karasuex54/gopherdojo-studyroom/kadai1/karasuex54

go 1.17
35 changes: 35 additions & 0 deletions kadai1/karasuex54/main.go
Original file line number Diff line number Diff line change
@@ -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()
}