1hドロは言い訳にも向く
この記事は
の11日目である。10日が事故っているが、多分大丈夫。ギリギリまで登録が無かったので今日も僕です。
1hで描く
短時間で絵を仕上げるのも神絵師に要求されるスキルだと思われる。
短時間で描くコツはどうやら * 線をそのまま残しっぱなし * パステル塗り
あたりをするとごまかせる気がしたので、そうした。
今日はハピメアの内藤舞亜ちゃんを描きたかった。
明日はきっとちゃんと。
アオリ失敗録、若しくは希実香ちゃんは可愛い
この記事は
の7日目の記事になる。
動画講座
先日の記事でも少し触れたが、Pixiv動画講座「sensei イラストの描き方を動画で学ぶ! - sensei by pixiv」というのがあって、最初の2週間は無料、以後プレミアム会員にならないと全動画が見られないというサービスがある。 「全」動画を見るには月額課金というだけで、チラッと見るなら別にお金はかからないので気になった方はどうぞ。
で、何が学べるのかというと、頭身を図ったりアタリをつけたりする、まあ基本的なことから始まる。僕が見ているのもまだこの辺り。 進んでいくとキャラクター、人体、背景と種類が分かれていく。
構図
大胆な構図で勝負をかける話をされたので、触発されて橘希実香ちゃんのアオリに挑戦、撃沈した。失敗の原因を挙げていく。
- まず服の構造を理解せず描いた
- 髪と重力の関係を上手く描けなかった
- 影主体の塗りの基礎ができていない
悔しかったので一時間で顔のみを描いた。
希実香ちゃんについて詳しくは
終わりに
8日目は@ioriveur。ここまで来たら完走したいので登録はガンガンしてくれると嬉しいです。
Pixivプレミアム会員になったと思ったらCLIP STUDIOに入信していた
動画講座の続きが見たいなと思ってpixivプレミアム会員に登録したらCLIP STUDIO PAINTが使える(使えるとはいっていない)ようになったので描きます。Kritaと比べると、あまりいじらずに鉛筆が使えて良い感じです。選択とかもやりやすいし、 アニメ塗りに良いかもしれない。
これをコミケで中高生に配っていたと@karasuTXに聞いて中高生になりたいよなと語り合った。
この記事は
の5日目です。僕は二回目です。神絵師までバトンを繋ぐぞ*1!!!
SD
可愛いキャラクターを描く上で割と重要と思われるデフォルメ。その一つの到達点でありそうなSDキャラクター。大体2、3頭身あたり。
@karasuTXとSDキャラについて話したところ、好きなSD絵師の描くSDキャラが描くには一番良いのではということになったので、せのぴーこと瀬之本久史先生のSD絵を 意識してSDキャラを描いていきたい。最新作「王の耳には届かない!」も可愛いので買います。
他にもこもわた遥華先生とかぺろ先生とか鳥取砂丘先生とか好きな絵師はいっぱいいるのでいずれ……いずれ!!!
描く
一日目の記事について@ioriveurに言われたのでポイントを描く。 今回気を付けて描いた、重要そうなのは大体以下の通り。できるかは別にして。
- 髪はそこそこ細かい
- 目は大きい
- 輪郭線太め
- 体系は下がでかい台形を意識
- 手はギザギザで良し
台形とかは意識する絵師によって変わる気はする。
すーぱーそに子を描いた。描いたったら描いた。
所感
- 瀬之本先生は遠い
- グラデーションをもっと使えるようになりたい
- 線がブレる(手ブレ補正もっと足すか?)
- 眉とまつ毛描いてたのに統合し忘れてる(そして元ファイル消した)
明日は@gaogao_9さん。
*1:昨日4日目にして事故ってたが
Gravaterの画像を自分で描く
何
一日目だしハードルは無いに等しい。ということで、今までやりたかったがやっていなかったGravater*1を設定することにした。
好きなキャラクターの画像は心に良いが、そのまま引っ張ってくるのはあまりよろしくない。そこで神絵師*2だ。 神絵師なら版権絵も自分のテイストに落としこんでいい感じになるはず。
描く
描いた。Krita*3、一太郎30周年記念ペンタブ*4を用いた。 ちなみにこれに一時間かけている。察せ。
平グモちゃん*5可愛い。可愛い平グモちゃんを描いたからには可愛い絵が爆誕しているはずだ。
上げる
先ずは上記サイトにて登録。メールが来るので承認ページへ。
上げた。達成感がある。段々恥ずかしくなってくるが耐える。
おわり
2日目は@karasuTXのはず。
*2:これは神絵師になるのが目的のカレンダー、らしい。
Golangのtemplateライブラリハマり
ちょこちょこやっているので追加するかも。
ブレース"{" "}"が{{}}の前後に書けないっていう。
LeTeX用のテンプレートを書こうとしてハマる。
というわけで、
\title{{print "{"}}{{.Booktitle}}{{print "}"}}
のようにして解決した(解決していない)。
げっちゅな屋でスクレイピング2
何
以前のエントリで書いたのは月別の発売日を出力するものでしたが、今回は検索を行うものを書きました。基本は一緒で、URL、クエリ、matcherなどが変わりました。要は別サイトをスクレイピングした感じになりました。
詰まった所
- クエリをEucJPにするのを忘れてしばらく時間を使った。
- 発売日に特徴的なタグがついていない(諦めて該当箇所全部出すことにした)。
code
package main import ( "flag" "fmt" "net/http" "strings" "io/ioutil" "net/http/cookiejar" "net/url" "github.com/yhat/scrape" "golang.org/x/net/html" "golang.org/x/net/html/atom" "golang.org/x/text/encoding/japanese" "golang.org/x/text/transform" ) var ( keyword string title string brand string person string isbn string jan string age string genre string startDate string endDate string sort string sort2 string listCount string listType string search string ) func eucjpToUtf8(str string) (string, error) { ret, err := ioutil.ReadAll(transform.NewReader(strings.NewReader(str), japanese.EUCJP.NewDecoder())) if err != nil { return "", err } return string(ret), err } func utf8ToEucjp(str string) (string, error) { ret, err := ioutil.ReadAll(transform.NewReader(strings.NewReader(str), japanese.EUCJP.NewEncoder())) if err != nil { return "", err } return string(ret), err } func main() { flag.StringVar(&keyword, "keyword", "", "search keyword") flag.StringVar(&keyword, "k", "", "search keyword short") flag.StringVar(&title, "title", "", "search title") flag.StringVar(&title, "t", "", "search title short") flag.StringVar(&brand, "brand", "", "search brand") flag.StringVar(&brand, "b", "", "search brand short") flag.StringVar(&person, "person", "", "search person") flag.StringVar(&person, "p", "", "search person short") flag.StringVar(&isbn, "isbn", "", "search isbn") flag.StringVar(&isbn, "i", "", "search isbn short") flag.StringVar(&jan, "jan", "", "search jan") flag.StringVar(&jan, "j", "", "search jan short") flag.StringVar(&age, "age", "", "age") flag.StringVar(&age, "a", "", "age short") flag.StringVar(&genre, "genre", "pc_soft", "genre") flag.StringVar(&genre, "g", "pc_soft", "genre default pc_soft") flag.StringVar(&startDate, "startdate", "", "start date") flag.StringVar(&startDate, "sd", "", "start date short") flag.StringVar(&endDate, "enddate", "", "end date") flag.StringVar(&endDate, "ed", "", "end date short") flag.StringVar(&listCount, "listcount", "100", "list") flag.StringVar(&listCount, "lc", "100", "list short default 100") flag.StringVar(&listType, "listtype", "list", "list type default list") flag.StringVar(&listType, "lt", "list", "list type short") flag.StringVar(&sort, "sort", "release_date", "sort default release_date") flag.StringVar(&sort2, "sort2", "down", "sort2 default down") flag.StringVar(&search, "search", "search", "search default search") flag.StringVar(&search, "s", "search", "search short") flag.Parse() getchuURL := "http://www.getchu.com/php/nsearch.phtml" jar, _ := cookiejar.New(nil) var cookies []*http.Cookie cookie := &http.Cookie{ Name: "getchu_adalt_flag", Value: "getchu.com", Path: "/", Domain: "www.getchu.com", } cookies = append(cookies, cookie) u, _ := url.Parse(getchuURL) jar.SetCookies(u, cookies) client := &http.Client{ Jar: jar, } brand, _ = utf8ToEucjp(brand) title, _ = utf8ToEucjp(title) keyword, _ = utf8ToEucjp(keyword) person, _ = utf8ToEucjp(person) values := url.Values{} values.Set("search_keyword", keyword) values.Add("search_title", title) values.Add("search_brand", brand) values.Add("search_person", person) values.Add("search_isbn", isbn) values.Add("search_jan", jan) values.Add("start_date", startDate) values.Add("end_date", endDate) values.Add("sort", sort) values.Add("sort2", sort2) values.Add("list_count", listCount) values.Add("list_type", listType) values.Add("age", age) values.Add("genre", genre) values.Add("search", search) valuesEncoded := values.Encode() req, _ := http.NewRequest("POST", getchuURL, strings.NewReader(valuesEncoded)) req.Header.Add("Content-Type", "application/x-www-form-urlencoded") resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() root, err := html.Parse(resp.Body) if err != nil { panic(err) } req.Header.Add("Content-Type", "application/x-www-form-urlencoded") matcherTitle := func(n *html.Node) bool { if n.DataAtom == atom.Div { return scrape.Attr(n, "class") == "content_block" } return false } titles := scrape.FindAll(root, matcherTitle) for i, title := range titles { title, err := eucjpToUtf8(scrape.Text(title)) if err != nil { panic(err) } fmt.Printf("%d: %s\n", i, title) } }
げっちゅな屋でスクレイピング
なに
まだとりあえずタイトルが引っぱれるだけですが。golangでscrapeライブラリを使っています。
先達がコチラhttp://akb428.hatenablog.com/?page=1437903964。
追記(2016-11-10)
year、monthを引数にとってその年月の発売作品のタイトルを並べます。引数なしの場合、現在の月の発売作品を並べます。 respをCloseするようにしたのと、ブランド、発売日を表示するようにしました。
utf-8に変換してます Go言語で文字コード変換 - Qiita。
code
package main import ( "flag" "fmt" "net/http" "strings" "time" "io/ioutil" "net/http/cookiejar" "net/url" "github.com/yhat/scrape" "golang.org/x/net/html" "golang.org/x/net/html/atom" "golang.org/x/text/encoding/japanese" "golang.org/x/text/transform" ) const ( stdLongYear = "2006" stdNumMonth = "1" ) var ( year string month string ) func eucjpToUtf8(str string) (string, error) { ret, err := ioutil.ReadAll(transform.NewReader(strings.NewReader(str), japanese.EUCJP.NewDecoder())) if err != nil { return "", err } return string(ret), err } func main() { t := time.Now() flag.StringVar(&year, "year", t.Format(stdLongYear), "sell year") flag.StringVar(&month, "month", t.Format(stdNumMonth), "sell month") flag.Parse() getchuUrl := "http://www.getchu.com/all/price.html?genre=pc_soft&gage=adult" jar, _ := cookiejar.New(nil) var cookies []*http.Cookie cookie := &http.Cookie{ Name: "getchu_adalt_flag", Value: "getchu.com", Path: "/", Domain: "www.getchu.com", } cookies = append(cookies, cookie) u, _ := url.Parse(getchuUrl) jar.SetCookies(u, cookies) client := &http.Client{ Jar: jar, } postData := strings.NewReader("&year=" + year + "&month=" + month) req, _ := http.NewRequest("POST", getchuUrl, postData) req.Header.Add("Content-Type", "application/x-www-form-urlencoded") resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() root, err := html.Parse(resp.Body) if err != nil { panic(err) } matcherGame := func(n *html.Node) bool { if n.DataAtom == atom.A && n.Parent != nil && n.Parent.Parent != nil { return scrape.Attr(n.Parent, "align") == "left" } return false } matcherSellday := func(n *html.Node) bool { if n.DataAtom == atom.Td { return scrape.Attr(n, "class") == "black" && scrape.Attr(n, "align") == "center" } return false } matcherBrand := func(n *html.Node) bool { if n.DataAtom == atom.Td { return scrape.Attr(n, "class") == "black" && scrape.Attr(n, "align") == "left" } return false } games := scrape.FindAll(root, matcherGame) selldays := scrape.FindAll(root, matcherSellday) brands := scrape.FindAll(root, matcherBrand) selldayList := make(map[int]string) for i, sellday := range selldays { selldayList[i] = scrape.Text(sellday) } brandList := make(map[int]string) for i, brand := range brands { brandList[i], err = eucjpToUtf8(scrape.Text(brand)) if err != nil { panic(err) } } for i, game := range games { // sellday, err := eucjpToUtf8(scrape.Text(sellday)) game, err := eucjpToUtf8(scrape.Text(game)) if err != nil { panic(err) } fmt.Printf("%s: %s| %s\n", selldayList[i], game, brandList[i]) } }