-
Notifications
You must be signed in to change notification settings - Fork 7
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
kadai2-nejiyoshida #17
Open
nejiyoshida
wants to merge
1
commit into
gopherdojo:master
Choose a base branch
from
nejiyoshida:kadai2-nejiyoshida
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,9 @@ | ||
# 1.画像変換コマンドをつくろう | ||
|
||
## 使い方 | ||
imgconv {-s source-extension} {-t target-extension} search-directory save-directory | ||
|
||
## 説明 | ||
指定したディレクトリ配下を再帰的に探索し、指定形式の画像を変換します。 | ||
保存先を指定する必要があり、指定の保存先が存在しない場合、新たにディレクトリが作られます。 | ||
対応形式はjpg, png, bmp, gif の4種類です。 |
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.
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,56 @@ | ||
// dircrawler パッケージは指定のディレクトリ以下にある指定の形式のファイルのリストを再帰的に取得する機能を提供します | ||
package dircrawler | ||
|
||
import ( | ||
"io/ioutil" | ||
"log" | ||
"path/filepath" | ||
) | ||
|
||
// 指定ディレクトリ配下の特定形式のファイルパスリストを再帰的に取得します | ||
func SearchSpecificFormatFiles(rootDir, format string) []string { | ||
|
||
paths := searchFilePaths(rootDir) | ||
files := selectFormat(paths, format) | ||
|
||
return files | ||
|
||
} | ||
|
||
// 指定ディレクトリのファイルパスリストを再帰的に取得します | ||
func searchFilePaths(rootDir string) []string { | ||
files, err := ioutil.ReadDir(rootDir) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
var paths []string | ||
|
||
for _, file := range files { | ||
if file.IsDir() { | ||
paths = append(paths, searchFilePaths(filepath.Join(rootDir, file.Name()))...) | ||
continue | ||
} | ||
|
||
paths = append(paths, filepath.Join(rootDir, file.Name())) | ||
} | ||
|
||
return paths | ||
} | ||
|
||
//ファイルパスリストから特定のフォーマットのもののみ抜き出します | ||
func selectFormat(paths []string, format string) []string { | ||
var files []string | ||
for _, path := range paths { | ||
if isSpecifiedFormat(path, format) { | ||
files = append(files, path) | ||
} | ||
} | ||
return files | ||
} | ||
|
||
// ファイルパスが特定のフォーマットか確認します。 | ||
func isSpecifiedFormat(path, format string) bool { | ||
ext := filepath.Ext(path) | ||
return ext == format | ||
} |
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,74 @@ | ||
package dircrawler | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
func ExampleisSpecifiedFormat() { | ||
|
||
fmt.Println(isSpecifiedFormat("hoge.jpg", ".jpg")) | ||
//Output:true | ||
fmt.Println(isSpecifiedFormat("huga.jpg", ".png")) | ||
//Output:false | ||
fmt.Println(isSpecifiedFormat("foo.png", ".png")) | ||
//Output:true | ||
fmt.Println(isSpecifiedFormat("bar.png", ".png")) | ||
//Output:false | ||
} | ||
|
||
func TestSelectFormat(t *testing.T) { | ||
t.Helper() | ||
cases := []struct { | ||
ext string | ||
files []string | ||
ret []string | ||
}{ | ||
{ext: ".jpg", files: []string{"a.txt", "b.jpg", "c.jpg", "d.html", "e.png"}, ret: []string{"b.jpg", "c.jpg"}}, | ||
{ext: ".exe", files: []string{"a.txt", "b.jpg", "c.jpg", "d.html", "e.png"}, ret: nil}, | ||
{ext: ".jpg", files: []string{"./hoge/a.txt", "./hoge/huga/b.jpg", "./.git/c.jpg", "./d.html", "./e.png"}, ret: []string{"./hoge/huga/b.jpg", "./.git/c.jpg"}}, | ||
} | ||
for _, c := range cases { | ||
if !reflect.DeepEqual(selectFormat(c.files, c.ext), c.ret) { | ||
t.Errorf("test cases %v does not match\n", c) | ||
} | ||
} | ||
|
||
} | ||
|
||
func TestIsSpecifiedFormat(t *testing.T) { | ||
t.Helper() | ||
cases := []struct { | ||
file string | ||
ext string | ||
ans bool | ||
}{ | ||
{file: "a.jpg", ext: ".jpg", ans: true}, | ||
{file: "a.jpg", ext: ".txt", ans: false}, | ||
{file: "./hoge/huga/a.png", ext: ".png", ans: true}, | ||
{file: "./foo/bar/a.jpg", ext: ".png", ans: false}, | ||
} | ||
for _, c := range cases { | ||
if !isSpecifiedFormat("./hoge/huga.jpg", ".jpg") { | ||
t.Errorf("test cases %v is not %v formt\n", c.file, c.ext) | ||
} | ||
} | ||
} | ||
func TestSearchFilePaths(t *testing.T) { | ||
t.Helper() | ||
cases := []struct { | ||
rootDir string | ||
ret []string | ||
}{ | ||
{rootDir: "./test", ret: []string{"test\\TEST\\bar.txt", "test\\TEST\\gopher.jpg", "test\\foo.txt"}}, | ||
{rootDir: "./test/TEST", ret: []string{"test\\TEST\\bar.txt", "test\\TEST\\gopher.jpg"}}, | ||
} | ||
for _, c := range cases { | ||
|
||
if !reflect.DeepEqual(searchFilePaths(c.rootDir), c.ret) { | ||
t.Errorf("test case %v does not match\n", c) | ||
} | ||
|
||
} | ||
} |
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
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.
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 ( | ||
"flag" | ||
"fmt" | ||
|
||
"github.com/gopherdojo/dojo5/kadai1/nejiyoshida/dircrawler" | ||
"github.com/gopherdojo/dojo5/kadai1/nejiyoshida/imgconverter" | ||
) | ||
|
||
func main() { | ||
|
||
var ( | ||
s string | ||
t string | ||
) | ||
|
||
flag.StringVar(&s, "s", ".jpg", "format of image before conversion") | ||
flag.StringVar(&t, "t", ".png", "format of image after conversion") | ||
flag.Parse() | ||
|
||
args := flag.Args() | ||
searchDir, saveDir := args[0], args[1] | ||
files := dircrawler.SearchSpecificFormatFiles(searchDir, s) | ||
c := imgconverter.New(t, saveDir, files) | ||
c.Convert() | ||
fmt.Println("finished") | ||
} |
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,115 @@ | ||
// imgconverter パッケージは指定の画像ファイルを指定の形式に変換する機能を提供します | ||
package imgconverter | ||
|
||
import ( | ||
"fmt" | ||
"image" | ||
"image/gif" | ||
"image/jpeg" | ||
"image/png" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
"golang.org/x/image/bmp" | ||
) | ||
|
||
type Client struct { | ||
|
||
// tgtExt:変換先のファイル形式 | ||
tgtExt string | ||
// savePath:保存先ディレクトリ、存在しない場合新たに作成されます | ||
savePath string | ||
// 変換対象の画像リスト | ||
images []string | ||
} | ||
|
||
func New(tgtExt, savePath string, images []string) *Client { | ||
return &Client{ | ||
|
||
tgtExt: tgtExt, | ||
savePath: savePath, | ||
images: images, | ||
} | ||
} | ||
|
||
func (c *Client) Convert() { | ||
|
||
if _, err := os.Stat(c.savePath); os.IsNotExist(err) { | ||
os.MkdirAll(c.savePath, 0755) | ||
} | ||
|
||
for _, image := range c.images { | ||
err := convertImage(image, c.tgtExt, c.savePath) | ||
if err != nil { | ||
fmt.Println(err) | ||
} | ||
} | ||
|
||
return | ||
} | ||
|
||
//一枚の画像を特定のフォーマットに変換し指定のディレクトリに保存します | ||
func convertImage(imgPath, tgtExt, savePath string) (err error) { | ||
|
||
if tgtExt == filepath.Ext(imgPath) { | ||
err = fmt.Errorf("file \"%s\"'s extension is already %s, conversion skipped", imgPath, tgtExt) | ||
} | ||
if err == nil { | ||
src, err := os.Open(imgPath) | ||
if err == nil { | ||
defer src.Close() | ||
decoded, err := decode(src) | ||
|
||
if err == nil { | ||
name := imgPath[0 : len(imgPath)-len(filepath.Ext(imgPath))] | ||
name = filepath.Base(name) | ||
|
||
tgt, err := os.Create(savePath + "/" + name + tgtExt) | ||
if err == nil { | ||
defer tgt.Close() | ||
err = encode(tgt, decoded) | ||
} | ||
} | ||
} | ||
} | ||
return | ||
} | ||
|
||
//画像のデコードを行います | ||
func decode(srcImg *os.File) (decodedImg image.Image, err error) { | ||
name := srcImg.Name() | ||
ext := filepath.Ext(name) | ||
switch strings.ToLower(ext) { | ||
case ".jpg", ".jpeg": | ||
decodedImg, err = jpeg.Decode(srcImg) | ||
case ".png": | ||
decodedImg, err = png.Decode(srcImg) | ||
case ".gif": | ||
decodedImg, err = gif.Decode(srcImg) | ||
case ".bmp": | ||
decodedImg, err = bmp.Decode(srcImg) | ||
} | ||
|
||
return | ||
} | ||
|
||
//特定の形式へのエンコードを行います | ||
func encode(tgt *os.File, decodedImg image.Image) (err error) { | ||
name := tgt.Name() | ||
ext := filepath.Ext(name) | ||
switch strings.ToLower(ext) { | ||
case ".jpg", ".jpeg": | ||
opt := &jpeg.Options{Quality: 100} | ||
err = jpeg.Encode(tgt, decodedImg, opt) | ||
case ".png": | ||
err = png.Encode(tgt, decodedImg) | ||
case ".gif": | ||
opt := &gif.Options{} | ||
err = gif.Encode(tgt, decodedImg, opt) | ||
case ".bmp": | ||
err = bmp.Encode(tgt, decodedImg) | ||
} | ||
|
||
return | ||
} |
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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
エラー処理。log.Fatalは使わない。