2016/10/01(土) [n年前の日記]
#1 [nitijyou] 写真画像に線を引いて眺めてたり
ゲームに使えそうなキャラ画像を描きたい。横方向から見て走ってる感じのソレにしたいなと。しかし横顔がどうもうまく描けなくて。
Google画像検索で横顔写真っぽい画像をいくつか入手して、Inkscape を使って線を引きまくってじっと眺めて比率を確認してみたり、A・ルーミス著「やさしい人物イラスト」内で紹介されてる球と平面で構成される顔のソレと比較してみたりしてるところ。
この手のソレはあちこちで目にしてたけど、自分で比率を把握しようと思わない限り、あるいは実際に手を動かして確認しない限り、記憶にさっぱり残らないのだなと今更痛感。
Google画像検索で横顔写真っぽい画像をいくつか入手して、Inkscape を使って線を引きまくってじっと眺めて比率を確認してみたり、A・ルーミス著「やさしい人物イラスト」内で紹介されてる球と平面で構成される顔のソレと比較してみたりしてるところ。
この手のソレはあちこちで目にしてたけど、自分で比率を把握しようと思わない限り、あるいは実際に手を動かして確認しない限り、記憶にさっぱり残らないのだなと今更痛感。
[ ツッコむ ]
#2 [anime] Thunderbolt Fantasy 東離劍遊紀、最終回を視聴
虚淵脚本と現代布袋劇(台湾の人形劇)の組み合わせ、の作品。
面白かった…。映像がとにかくド派手で、ただ見ているだけでもゲラゲラ笑ってしまうぐらいに凄まじかったけど。映像のみならず、脚本がイイ…。キャラもそれぞれ立ってたし、会話のやりとりも時々ニヤリとしてしまうしで。かっこいいとは、こういうことさ。みたいな。
終わり方も実に上手い。あの繋げ方、イイな…。なんだか作品としてビシッと決まった感じがする。素晴らしい。
面白かった…。映像がとにかくド派手で、ただ見ているだけでもゲラゲラ笑ってしまうぐらいに凄まじかったけど。映像のみならず、脚本がイイ…。キャラもそれぞれ立ってたし、会話のやりとりも時々ニヤリとしてしまうしで。かっこいいとは、こういうことさ。みたいな。
終わり方も実に上手い。あの繋げ方、イイな…。なんだか作品としてビシッと決まった感じがする。素晴らしい。
[ ツッコむ ]
2016/10/02(日) [n年前の日記]
#1 [ruby] RubyのGUI関係のアレコレをググってる
FxRubyてのが、ちょっと気になるのでググって関連情報を眺めてるところ。
[ ツッコむ ]
2016/10/03(月) [n年前の日記]
#1 [prog] Tcl/Tkのteacupってなんじゃろ
Tcl/Tk関連ページを眺めてたら、teacup なる単語が目に入った。なんじゃろコレ。
_Teacup や _TEApot と TEAcup:Rainy Day Codings:So-net blog を眺めると…。ActiveTclをインストールしてある環境なら使えるらしいパッケージマネージャ、ということでいいのかな。
以下はWindows10 x64環境での話。ActiveTcl を C:\Tcl にインストールしたものとする。
DOS窓で tclsh と打つと Tcl のコマンド入力(?)ができる状態になる。そこで teacup list と打てば、インストールできるパッケージの一覧が表示されるらしい。
例えば、ファイルのドラッグアンドドロップができるようになる tkdnd をインストールしたければ、teacup install tkdnd と打てばいい。
インストールされたアレコレは、C:\Tcl\lib\teapot\package\win32-ix86\lib\ 以下に入る。確認したところ、tkdnd2.8 というフォルダが増えていた。
teacup のバージョン確認。
ヘルプ表示。
ちなみに tclsh から抜けるなら exit と打てばいいらしい。
_Teacup や _TEApot と TEAcup:Rainy Day Codings:So-net blog を眺めると…。ActiveTclをインストールしてある環境なら使えるらしいパッケージマネージャ、ということでいいのかな。
以下はWindows10 x64環境での話。ActiveTcl を C:\Tcl にインストールしたものとする。
DOS窓で tclsh と打つと Tcl のコマンド入力(?)ができる状態になる。そこで teacup list と打てば、インストールできるパッケージの一覧が表示されるらしい。
例えば、ファイルのドラッグアンドドロップができるようになる tkdnd をインストールしたければ、teacup install tkdnd と打てばいい。
インストールされたアレコレは、C:\Tcl\lib\teapot\package\win32-ix86\lib\ 以下に入る。確認したところ、tkdnd2.8 というフォルダが増えていた。
teacup のバージョン確認。
% teacup version 8.5.18.0.299124
ヘルプ表示。
% teacup help teacup.EXE is a tool to access package repositories teacup.EXE help cmds-by-group Grouped list of commands provided by teacup teacup.EXE help commands Alphabetical list of commands provided by teacup teacup.EXE help help How to use help teacup.EXE help options Describes the standard options teacup.EXE help queries Describe the syntax of complex queries
ちなみに tclsh から抜けるなら exit と打てばいいらしい。
[ ツッコむ ]
#2 [ruby] Ruby/GTK2をアップデートしようとしてハマった
Windows10 x64 + Ruby 2.2.5 p319 で、Ruby/GTK2 (
_gtk2
) 3.0.9 をインストールしようとしてハマった。
本来であれば、gem install gtk2 と打てば必要なものをインストールしてくれるはずだけど、現時点では _gio2 と _gobject-introspection もインストールしないといけないらしい。
_gdk_pixbuf2 3.0.9 lacks dependency - Issue #862 - ruby-gnome2/ruby-gnome2
_Detection of libgirepository-1.0 broken - Issue #900 - ruby-gnome2/ruby-gnome2
_gdk_pixbuf2: Fix runtime dependency by cosmo0920 - Pull Request #906 - ruby-gnome2/ruby-gnome2
本来であれば、gem install gtk2 と打てば必要なものをインストールしてくれるはずだけど、現時点では _gio2 と _gobject-introspection もインストールしないといけないらしい。
_gdk_pixbuf2 3.0.9 lacks dependency - Issue #862 - ruby-gnome2/ruby-gnome2
_Detection of libgirepository-1.0 broken - Issue #900 - ruby-gnome2/ruby-gnome2
@kou 3.0.9にgio2とgobject-introspectionがgdk_pixbuf2に必要とされているが、
gdk pixbuf に gobject-introspection と gio2 の gem が必要とされていません。
また、gobject-introspectionが必要とされていることで↑の様に
rsvg2などを使っている場合 heroku 度にビルドパックなしでデプロイが出来ない状況です。
今ビルドパックを作ろうとしていますが、
そもそもgdk_pixbuf2にgio2/gobject-introspectionが必要なければ除いた方が良いのでは?と思います。
もし必要であれば gdk_pixbuf2 の gemspec に gobject-introspection と gio2 を足した方が良さそうです。
_gdk_pixbuf2: Fix runtime dependency by cosmo0920 - Pull Request #906 - ruby-gnome2/ruby-gnome2
[ ツッコむ ]
#3 [ruby] RubyのGUI関連について調べてる
Windows上でRubyを使ってGUIアプリを書きたい。できればエクスプローラからファイルをD&D(ドラッグアンドドロップ)するとウインドウ内にファイルを読み込める仕様にしたい。
RubyでGUIアプリを書けるアレコレ、かつ、今もメンテナンスされてる気配があるソレと言うと、Ruby/Tk、 _Ruby/GTK2(Ruby-GNOME2?) 、 _FxRuby 等があるわけだけど。FxRuby がちょっと気になってググってみたものの、D&Dはサポートしてないぜ、てな情報を見かけた。
_FXRuby Users - Drag and drop from the filesystem
FxRuby が使っている FOX なるソレがそもそもサポートしてないから無理なんだぜ、と書いてあるように見える。そうか。FxRuby はダメか…。
Ruby/Tk でD&Dするなら、おそらく Tkdnd を使ってどうにかするのだろうと想像するけれど、ググってみても使用例がまったく出てこない。Ruby関連のドキュメントの中に Tkdnd という文字列はあるから、何かと絡めて実装されてるのかもしれんけど…。
Ruby/GTK2 は、ファイルのD&Dをサポートしてるっぽい。
_Ruby Window Drop: いち雑記
RubyでGUIアプリを書けるアレコレ、かつ、今もメンテナンスされてる気配があるソレと言うと、Ruby/Tk、 _Ruby/GTK2(Ruby-GNOME2?) 、 _FxRuby 等があるわけだけど。FxRuby がちょっと気になってググってみたものの、D&Dはサポートしてないぜ、てな情報を見かけた。
_FXRuby Users - Drag and drop from the filesystem
FxRuby が使っている FOX なるソレがそもそもサポートしてないから無理なんだぜ、と書いてあるように見える。そうか。FxRuby はダメか…。
Ruby/Tk でD&Dするなら、おそらく Tkdnd を使ってどうにかするのだろうと想像するけれど、ググってみても使用例がまったく出てこない。Ruby関連のドキュメントの中に Tkdnd という文字列はあるから、何かと絡めて実装されてるのかもしれんけど…。
Ruby/GTK2 は、ファイルのD&Dをサポートしてるっぽい。
_Ruby Window Drop: いち雑記
◎ その他のGUIのアレコレについて。 :
_Rubyist Magazine - Ruby de GUI
でいろいろ紹介されてるものの、2004年の古い記事だし、QTRuby、Ruby/FLTK、wxRuby、VisualuRuby は開発停止で死んでるし。
一時期 _Shoes なんてものも話題になったけど、 _Shoes - Wikipedia によると、これまた2009年に一度死んでいたらしい。有志がforkだかメンテナンスを続けて、Ruby/GTK2を利用した _green_shoes は2013年で止まってるし。
Qt を利用したソレは、 _qtbindings という形で使えるのかもしれない。もっとも、2015年の5月、つまり去年の5月から開発が止まってるようだけど。
_Ruby の GUI ライブラリ - メモ@wantora でも、2012年の時点での各フレームワークの死滅具合が列挙されてた。
Ruby、ボロボロやな。 *1
一時期 _Shoes なんてものも話題になったけど、 _Shoes - Wikipedia によると、これまた2009年に一度死んでいたらしい。有志がforkだかメンテナンスを続けて、Ruby/GTK2を利用した _green_shoes は2013年で止まってるし。
Qt を利用したソレは、 _qtbindings という形で使えるのかもしれない。もっとも、2015年の5月、つまり去年の5月から開発が止まってるようだけど。
_Ruby の GUI ライブラリ - メモ@wantora でも、2012年の時点での各フレームワークの死滅具合が列挙されてた。
Ruby、ボロボロやな。 *1
*1: いや、でも、Rubyに限った話じゃないよな。Go言語から使えるGUIフレームワークなどは、もっと酷い状況だし。
[ ツッコむ ]
2016/10/04(火) [n年前の日記]
#1 [cg_tools] Asepriteを試用
普段自分がドット絵を作る時は
_EDGE2
を使っているのだけど。最近は
_Aseprite
というドットエディタの評判がいいらしいので少し試用してみたり。
_Asepriteメモ - 茶ポーン
_EDGE と Aseprite と DXRuby と私 - あおたくノート
_asepriteというドット絵作成ソフトが結構良い感じです: ドット絵とアイデアと
_Aseprite - HaxeFlixel Wiki
_Blenderいいよたぶん: Aseprite
_Aseprite v1.1.3 - ドット絵ペイント&スプライトアニメーション制作が可能な高機能ピクセルアートツール!Win&Mac&Linux
Aseprite は有償ソフト。現行版のバージョンは 1.1.9。体験版(ファイル保存ができない)もあるので、試用だけならできる。また、昔のバージョン 0.9.5 ならフリーで使えるらしい。 _Aseprite - Download の下部の Older Versions を選べばフリー版を入手できる。
今現在は Steam でも購入できるようになってるそうで。Steamって使ったことないけど。
_Steam:Aseprite
1,480円だから、EDGE2 の4,000円よりも随分と安い。のかな。たぶん。
_Asepriteメモ - 茶ポーン
_EDGE と Aseprite と DXRuby と私 - あおたくノート
_asepriteというドット絵作成ソフトが結構良い感じです: ドット絵とアイデアと
_Aseprite - HaxeFlixel Wiki
_Blenderいいよたぶん: Aseprite
_Aseprite v1.1.3 - ドット絵ペイント&スプライトアニメーション制作が可能な高機能ピクセルアートツール!Win&Mac&Linux
Aseprite は有償ソフト。現行版のバージョンは 1.1.9。体験版(ファイル保存ができない)もあるので、試用だけならできる。また、昔のバージョン 0.9.5 ならフリーで使えるらしい。 _Aseprite - Download の下部の Older Versions を選べばフリー版を入手できる。
今現在は Steam でも購入できるようになってるそうで。Steamって使ったことないけど。
_Steam:Aseprite
1,480円だから、EDGE2 の4,000円よりも随分と安い。のかな。たぶん。
◎ タイルモードは便利っぽい。 :
現行版で実装されてるタイルモードが便利そう。View → Tiled Mode で使える。これならシームレス画像を作りやすい。フリーで使える 0.9.5にはついてない機能だけど。
_Aseprite - How to make Seamless Tiles - YouTube
ちなみに、無料で使えるお絵かきソフトの _Krita にも同様の機能がある。表示 → ラップアラウンドモード、を有効にすれば使える。
_Seamless stone texture using Krita - YouTube
また、 _Pyxel Edit というドットエディタも、キャンバスに同じ番号のタイルを敷き詰めることで、似たようなことができる。
_Pyxel Edit Tutorial Part 2/3: Tiling - YouTube
一応 EDGE2も、範囲をキャプチャフレームしてから、アニメーションプレイヤー → 表示 → タイル表示、を有効にすることで、マップ状に敷き詰めたような表示ができるけど。あくまで表示確認ができるだけ、でしかないので、上下左右が繋がるようにドットを打っていくのは面倒というか、正直ちょっとした拷問レベルの作業だったり。できれば Aseprite や Krita のような機能が欲しいところだけど…。
_Aseprite - How to make Seamless Tiles - YouTube
ちなみに、無料で使えるお絵かきソフトの _Krita にも同様の機能がある。表示 → ラップアラウンドモード、を有効にすれば使える。
_Seamless stone texture using Krita - YouTube
また、 _Pyxel Edit というドットエディタも、キャンバスに同じ番号のタイルを敷き詰めることで、似たようなことができる。
_Pyxel Edit Tutorial Part 2/3: Tiling - YouTube
一応 EDGE2も、範囲をキャプチャフレームしてから、アニメーションプレイヤー → 表示 → タイル表示、を有効にすることで、マップ状に敷き詰めたような表示ができるけど。あくまで表示確認ができるだけ、でしかないので、上下左右が繋がるようにドットを打っていくのは面倒というか、正直ちょっとした拷問レベルの作業だったり。できれば Aseprite や Krita のような機能が欲しいところだけど…。
◎ 日本語フォルダが一切表示されない。 :
Aseprite は英語圏のアプリだけあって、日本語フォルダが一切表示されないようで。マイピクチャ(Pictures)すら表示できないのは困った…。自分はえてして作業ファイルをそこに入れてしまってるので…。
◎ ビルドしてみた。 :
関連情報をググってたら、Aseprite はオープンソースなので github からソースをゲットして自分でビルドすることもできるよ、という情報を見かけたり。
_Asepriteのマウスポインタを固定する | 日々創作
_カクカンジメチル:ASEPRITE v1.1.0-devをビルド - livedoor Blog(ブログ)
面白そうなので自分も試してみたり。環境は Windows10 x64。必要になるのは、 _Git for Windows 、 _Visual Studio Community 2015 、 _CMake 。
前述の記事に従って作業してみたら、警告がやたらと出てきたけど一応ビルドできて exe が出来上がった。実行してみたら動いてしまった…。
もっとも、一見ビルドが通ったように見えても何か不具合があるのかもしれず。それに、Visual Studio をインストールするとHDDの空き容量が数GBほど減るわけで。自分などは昔の Visual Studio ほにゃらら Express なども入れてるから 12GB ぐらい使ってたり。ということで、Aseprite を使いたいがためにHDDを数GB使うぐらいならフツーに購入したほうがいいですよね、という気もしたり。
_Asepriteのマウスポインタを固定する | 日々創作
_カクカンジメチル:ASEPRITE v1.1.0-devをビルド - livedoor Blog(ブログ)
面白そうなので自分も試してみたり。環境は Windows10 x64。必要になるのは、 _Git for Windows 、 _Visual Studio Community 2015 、 _CMake 。
前述の記事に従って作業してみたら、警告がやたらと出てきたけど一応ビルドできて exe が出来上がった。実行してみたら動いてしまった…。
もっとも、一見ビルドが通ったように見えても何か不具合があるのかもしれず。それに、Visual Studio をインストールするとHDDの空き容量が数GBほど減るわけで。自分などは昔の Visual Studio ほにゃらら Express なども入れてるから 12GB ぐらい使ってたり。ということで、Aseprite を使いたいがためにHDDを数GB使うぐらいならフツーに購入したほうがいいですよね、という気もしたり。
[ ツッコむ ]
#2 [cg_tools] ドットエディタの購入方法が分からない
[ ツッコむ ]
#3 [cg_tools] EDGE2への不満
前述の Aseprite 等のタイルモード・ラップアラウンドモードが欲しい、てのはともかく。
触ってて思ったけど、EDGE2は、マウスホイールでキャンバスの表示倍率を変更できないのが地味に不便だなと。Zキー、Xキーに一々手を伸ばすのも面倒だし。
一応、Ctrl + ホイールで倍率変更できる、ということになってるけど、ビミョーにツライ。いやまあ、他のOffice系アプリもえてしてそういう操作ではあるけど、CGツール関係はそこらへん違う仕様になってる場合が多いよなと。何故なら、文書作成作業と、画像作成作業では、表示倍率を変更する頻度が全然違うわけで…。そりゃ少しでもサクッとできるようにしておいたほうが作業効率は上がるよなと。
もっとも、ペンタブレットで作業してるときはホイールを使いようもないから…。マウスで作業してるときは欲しい機能だけど、利用入力デバイスにもよるんだよな…。
ちなみに、過去にも要望としては出ていたらしいけど。
_edge2/要望/111 - ホイールスクロールで拡大縮小 - Takabo Soft Wiki*
2012年に要望が出されたまま放置状態らしい。
そういえば、マウスの中ボタンドラッグでもスクロールができたら…と思ったら、コレは開発版で実装済みらしい。
_edge2/要望/163 - 中ドラッグでハンドスクロール - Takabo Soft Wiki*
_edge2/ベータ版 - Takabo Soft Wiki*
試してみたら、たしかに中ボタンドラッグでキャンバスのスクロールができた。素晴らしい。
触ってて思ったけど、EDGE2は、マウスホイールでキャンバスの表示倍率を変更できないのが地味に不便だなと。Zキー、Xキーに一々手を伸ばすのも面倒だし。
一応、Ctrl + ホイールで倍率変更できる、ということになってるけど、ビミョーにツライ。いやまあ、他のOffice系アプリもえてしてそういう操作ではあるけど、CGツール関係はそこらへん違う仕様になってる場合が多いよなと。何故なら、文書作成作業と、画像作成作業では、表示倍率を変更する頻度が全然違うわけで…。そりゃ少しでもサクッとできるようにしておいたほうが作業効率は上がるよなと。
もっとも、ペンタブレットで作業してるときはホイールを使いようもないから…。マウスで作業してるときは欲しい機能だけど、利用入力デバイスにもよるんだよな…。
ちなみに、過去にも要望としては出ていたらしいけど。
_edge2/要望/111 - ホイールスクロールで拡大縮小 - Takabo Soft Wiki*
2012年に要望が出されたまま放置状態らしい。
そういえば、マウスの中ボタンドラッグでもスクロールができたら…と思ったら、コレは開発版で実装済みらしい。
_edge2/要望/163 - 中ドラッグでハンドスクロール - Takabo Soft Wiki*
_edge2/ベータ版 - Takabo Soft Wiki*
試してみたら、たしかに中ボタンドラッグでキャンバスのスクロールができた。素晴らしい。
[ ツッコむ ]
#4 [digital] RD-BZ710がフリーズ
HDDレコーダ TOSHIBA RD-BZ710がまたフリーズ。
状況としては、予約録画が終了して、画面右上に準備中の例のクルクル回るアイコンが出てきているタイミングで、うっかりタイニー番組ナビゲータからレコーダの予約情報を取得しようとしたら画面が固まってしまって。TV映像もピタリと止まってるし、アイコンのアニメも止まってるしで。参った。どうしよう。
リモコン操作も一切受け付けなくなっていたので、仕方なく本体電源ボタン長押しで電源を切ってから入れ直してみたけど、録画したばかりの番組は消滅していた。
ということで、録画終了時の準備中アイコンが出ているタイミングで、ネット経由で何かをしようとしたら、フリーズするようだなと…。まあ、「○○をしているタイミングで△△をするとフリーズする」なんてのは、ありがちなバグだし、噂によるとHDDレコーダって3つのOSが同時に動いている面倒臭い機器らしいから、色々と仕方ないところもあるのだろう…。
ていうか今はもう東芝はHDDレコーダを作ってないので今更な話ではあるなと。でも、液晶TVのREGZAシリーズも同種のバグが残ってたりしないのだろうか、などと余計な心配を。
いや、さすがにこの手のバグは、チェックリストの類を作ってテストして、潰してあるよな…。あるんだろうな…。どうかな…。東芝だもんな…。
状況としては、予約録画が終了して、画面右上に準備中の例のクルクル回るアイコンが出てきているタイミングで、うっかりタイニー番組ナビゲータからレコーダの予約情報を取得しようとしたら画面が固まってしまって。TV映像もピタリと止まってるし、アイコンのアニメも止まってるしで。参った。どうしよう。
リモコン操作も一切受け付けなくなっていたので、仕方なく本体電源ボタン長押しで電源を切ってから入れ直してみたけど、録画したばかりの番組は消滅していた。
ということで、録画終了時の準備中アイコンが出ているタイミングで、ネット経由で何かをしようとしたら、フリーズするようだなと…。まあ、「○○をしているタイミングで△△をするとフリーズする」なんてのは、ありがちなバグだし、噂によるとHDDレコーダって3つのOSが同時に動いている面倒臭い機器らしいから、色々と仕方ないところもあるのだろう…。
ていうか今はもう東芝はHDDレコーダを作ってないので今更な話ではあるなと。でも、液晶TVのREGZAシリーズも同種のバグが残ってたりしないのだろうか、などと余計な心配を。
いや、さすがにこの手のバグは、チェックリストの類を作ってテストして、潰してあるよな…。あるんだろうな…。どうかな…。東芝だもんな…。
[ ツッコむ ]
2016/10/05(水) [n年前の日記]
#1 [cg_tools] 基本パーツを組み合わせてドット絵を作成するドット絵バケーションを試用
ググってたら、ちょっと気になるソフトを見かけたわけで。
_ドット絵バケーション : Vector
基本パーツを自由に並べて、新たにドット絵を作っていくソフト、らしい。
なるほど、プラモ感覚でパーツを合体させて3Dモデルを作成する、 _DOGA-L1 のドット絵版、みたいなものかな…。あるいは、自分が以前、Ruby + DXRuby を使って書いた、 _8bit PC CG Editor に近いアプローチかもしれないなと。要は、パーツをひたすら“選んで”並べていけば誰でもそれっぽいモノを作れるだろう、みたいな。「『描く』のは難しいとしても、『選ぶ』ことならできるでしょ?」みたいな。…考えてみたら年賀状作成ソフトなどはどれもそういうアプローチなのだな。
2002年頃に作成されたソフトのようで、対応環境は Windows Me/2000/NT/98/95。かなり古い。が、幸いそのままでも Windows10 x64上で起動してくれた。ただし、下手に互換モードを有効にしてしまうと「ちゃんとしたexeじゃねえよ」と Windows10 に怒られて逆に動かなくなるので注意。
ウインドウの右側にプリセットなる基本パーツが並んでいるけど、クリックしても選択できなくて悩んだり。やはり古過ぎて Windows10 では動作しないのか…。と思ったが、何かの拍子にドラッグしたらキャンバス内に貼り付けられることに気づいたり。クリックしてブラシ選択、ではなくて、パーツをドラッグして並べる、てな操作仕様らしい。や、添付マニュアルでちゃんと説明されてたことに後から気づいたけど。
文章だけでは操作が分かりづらいだろうから、一応スクリーンショットも貼っておく。パーツをマウスでドラッグすると貼り付けられる様子がお分かりいただけるだろうか。
10年以上前のソフトなので、キャンバスが小さいのに拡大表示できなくて視認性が悪い上にキャンバスサイズも変更できない等、正直なところ使い勝手はよろしくないけれど。この発想は全然アリだよなと。開発終了してしまったのが惜しまれる。もっとも、2000年前後はドット絵がかなり迫害されて、この手のツールの需要がほとんどなかった時期のような気もするし、放置されてしまったのは仕方ないのかも、などと思ったりもする。
_ドット絵バケーション : Vector
基本パーツを自由に並べて、新たにドット絵を作っていくソフト、らしい。
なるほど、プラモ感覚でパーツを合体させて3Dモデルを作成する、 _DOGA-L1 のドット絵版、みたいなものかな…。あるいは、自分が以前、Ruby + DXRuby を使って書いた、 _8bit PC CG Editor に近いアプローチかもしれないなと。要は、パーツをひたすら“選んで”並べていけば誰でもそれっぽいモノを作れるだろう、みたいな。「『描く』のは難しいとしても、『選ぶ』ことならできるでしょ?」みたいな。…考えてみたら年賀状作成ソフトなどはどれもそういうアプローチなのだな。
2002年頃に作成されたソフトのようで、対応環境は Windows Me/2000/NT/98/95。かなり古い。が、幸いそのままでも Windows10 x64上で起動してくれた。ただし、下手に互換モードを有効にしてしまうと「ちゃんとしたexeじゃねえよ」と Windows10 に怒られて逆に動かなくなるので注意。
ウインドウの右側にプリセットなる基本パーツが並んでいるけど、クリックしても選択できなくて悩んだり。やはり古過ぎて Windows10 では動作しないのか…。と思ったが、何かの拍子にドラッグしたらキャンバス内に貼り付けられることに気づいたり。クリックしてブラシ選択、ではなくて、パーツをドラッグして並べる、てな操作仕様らしい。や、添付マニュアルでちゃんと説明されてたことに後から気づいたけど。
文章だけでは操作が分かりづらいだろうから、一応スクリーンショットも貼っておく。パーツをマウスでドラッグすると貼り付けられる様子がお分かりいただけるだろうか。
10年以上前のソフトなので、キャンバスが小さいのに拡大表示できなくて視認性が悪い上にキャンバスサイズも変更できない等、正直なところ使い勝手はよろしくないけれど。この発想は全然アリだよなと。開発終了してしまったのが惜しまれる。もっとも、2000年前後はドット絵がかなり迫害されて、この手のツールの需要がほとんどなかった時期のような気もするし、放置されてしまったのは仕方ないのかも、などと思ったりもする。
◎ 基本パーツを合成するソレ。 :
基本パーツを合成することでより複雑なドット絵を生成する、というアプローチは、色々なソフトやツールが取り入れてるようで。
例えば、ウディタ(WOLF RPGエディター)には、「グラフィック合成機」というソレがある、とググっていて今頃知った。
_WOLF RPGエディターのダウンロード
_グラフィック合成器を使ってみよう - はじめてのウディタ 挫折して再び Wiki*
_グラフィック合成器パーツ画像作成にPhotoshopCCの機能を活用! : ぴぽや
_ぴぽや32x32グラフィック合成器用パーツ 基本セット修正版 : ぴぽや
また、enchant.js にも、avatar.enchant.js なる、組み合わせでキャラ画像を作成できるソレがあるらしい。
_wise9 > avatar.enchant.jsが登場!2000万通りの中から君だけのキャラが作れる!?
どちらもキャラ画像の生成に特化してそうなあたりがちょっと気になるけど、2D RPG などはたくさんキャラ画像を作らないといかんだろうから自然とこうなったのかなと。
例えば、ウディタ(WOLF RPGエディター)には、「グラフィック合成機」というソレがある、とググっていて今頃知った。
_WOLF RPGエディターのダウンロード
_グラフィック合成器を使ってみよう - はじめてのウディタ 挫折して再び Wiki*
_グラフィック合成器パーツ画像作成にPhotoshopCCの機能を活用! : ぴぽや
_ぴぽや32x32グラフィック合成器用パーツ 基本セット修正版 : ぴぽや
また、enchant.js にも、avatar.enchant.js なる、組み合わせでキャラ画像を作成できるソレがあるらしい。
_wise9 > avatar.enchant.jsが登場!2000万通りの中から君だけのキャラが作れる!?
どちらもキャラ画像の生成に特化してそうなあたりがちょっと気になるけど、2D RPG などはたくさんキャラ画像を作らないといかんだろうから自然とこうなったのかなと。
[ ツッコむ ]
#2 [gimp][cg_tools] GIMPやPhotoshopのブラシ画像のフォーマットについてもやもや
ドット絵バケーションを試用しているうちに、もしかして、この基本パーツ画像を、GIMP や Photoshop のブラシファイルに変換して使えば、より使い勝手のいい作業環境が得られるのではと思えてきたわけで。
てなわけで、GIMPのブラシファイルのフォーマットについて調べていたのだけど。考えが甘かった。
まず、GIMP や Photoshop のブラシ画像は、グレースケール画像であることが前提で。黒い部分が不透明、白い部分が透明として扱われる。そしておそらく、アルファチャンネルは持てない。
この仕様では、思ったような描画結果を得られないはずで。
例えば、こういうブラシを作りたいと思って、画像モードをグレースケールにしてドットを打ったとして。
GIMPのブラシファイル(.gbr)として保存してから、ブラシフォルダ(~/.gimp-2.x/brushes/)にコピーして使ってみると、以下のような結果になる。
描画色はたしかに反映してくれたけど…。いやあ、そうじゃねえんだよ…。
ブラシファイル(.gbr)を画像として開いてみる。
透明だった部分は真っ白になっていた。予想通り、アルファチャンネルは残ってない。これではいかんのだ。
要は、こういう状態のブラシを作りたいわけで…。
そのためには、ブラシファイルがアルファチャンネルを持ってないと困るのだ。
調べた範囲では、Photoshop の場合、ブラシ画像 = グレースケール画像なので、ここで手詰まりらしい。
しかし、GIMP ならもう少し手段が残ってる。GIMP のブラシ画像には種類があって、グレースケール画像と、RGBAのフルカラー画像の2種類があるそうで。後者にすればアルファチャンネルを持てる。作り方は、画像をRGBモードにしてから .gbr として保存するだけ。
試してみたら、こうなった。
ちゃんと、白・黒・透明が出てる。
が、しかし、この種類のブラシ画像 ―― RGBAフルカラーブラシは、グレースケールのブラシ画像と違って、描画色が一切反映されない仕様だったりする。
さて、聡明な方なら、ここで疑問が湧くはず。
問題: RGBAフルカラーブラシを使いながら、描画色も変えたい場合、どのようにすればよいのだろう?
答え: 色を変えたブラシ画像をたくさん用意して頑張れ。
アホだ。いや、もう、どう考えてもアホとしか思えないのだけど。他に手はないのか。どうなんだ。
でもまあ、昔に比べたらまだマシで。昔のGIMPは、プログラム側でブラシサイズを変えることすらできなかったので、「ブラシサイズを変えたいなー」と思ったら、『異なるサイズのブラシ画像』を『たくさん用意して』頑張ってました。…そんな時代に比べたら、これでもまだ改善されたほうだったり。でも、やっぱりまだまだアホだ。
ということで、Photoshop だの GIMP だの、画像編集ソフトって結構完成度が高まって改良できる余地はそれほど無いような印象があったのだけど、こうして見るとブラシ機能一つとってもまだまだ発展できる余地がありそうだなと思い直した次第です。
と言っても、このあたり、ブラシ機能の範疇に入るのかな、別の機能として扱うべき話じゃないのか、などと疑問が湧いたりもするのですが。
てなわけで、GIMPのブラシファイルのフォーマットについて調べていたのだけど。考えが甘かった。
まず、GIMP や Photoshop のブラシ画像は、グレースケール画像であることが前提で。黒い部分が不透明、白い部分が透明として扱われる。そしておそらく、アルファチャンネルは持てない。
この仕様では、思ったような描画結果を得られないはずで。
例えば、こういうブラシを作りたいと思って、画像モードをグレースケールにしてドットを打ったとして。
GIMPのブラシファイル(.gbr)として保存してから、ブラシフォルダ(~/.gimp-2.x/brushes/)にコピーして使ってみると、以下のような結果になる。
描画色はたしかに反映してくれたけど…。いやあ、そうじゃねえんだよ…。
ブラシファイル(.gbr)を画像として開いてみる。
透明だった部分は真っ白になっていた。予想通り、アルファチャンネルは残ってない。これではいかんのだ。
要は、こういう状態のブラシを作りたいわけで…。
そのためには、ブラシファイルがアルファチャンネルを持ってないと困るのだ。
調べた範囲では、Photoshop の場合、ブラシ画像 = グレースケール画像なので、ここで手詰まりらしい。
しかし、GIMP ならもう少し手段が残ってる。GIMP のブラシ画像には種類があって、グレースケール画像と、RGBAのフルカラー画像の2種類があるそうで。後者にすればアルファチャンネルを持てる。作り方は、画像をRGBモードにしてから .gbr として保存するだけ。
試してみたら、こうなった。
ちゃんと、白・黒・透明が出てる。
が、しかし、この種類のブラシ画像 ―― RGBAフルカラーブラシは、グレースケールのブラシ画像と違って、描画色が一切反映されない仕様だったりする。
さて、聡明な方なら、ここで疑問が湧くはず。
問題: RGBAフルカラーブラシを使いながら、描画色も変えたい場合、どのようにすればよいのだろう?
答え: 色を変えたブラシ画像をたくさん用意して頑張れ。
アホだ。いや、もう、どう考えてもアホとしか思えないのだけど。他に手はないのか。どうなんだ。
でもまあ、昔に比べたらまだマシで。昔のGIMPは、プログラム側でブラシサイズを変えることすらできなかったので、「ブラシサイズを変えたいなー」と思ったら、『異なるサイズのブラシ画像』を『たくさん用意して』頑張ってました。…そんな時代に比べたら、これでもまだ改善されたほうだったり。でも、やっぱりまだまだアホだ。
ということで、Photoshop だの GIMP だの、画像編集ソフトって結構完成度が高まって改良できる余地はそれほど無いような印象があったのだけど、こうして見るとブラシ機能一つとってもまだまだ発展できる余地がありそうだなと思い直した次第です。
と言っても、このあたり、ブラシ機能の範疇に入るのかな、別の機能として扱うべき話じゃないのか、などと疑問が湧いたりもするのですが。
◎ 打開策は無いのだろうか。 :
[ ツッコむ ]
2016/10/06(木) [n年前の日記]
#1 [gimp][scheme] GIMPのScript-fuで文字列のゼロ埋め
GIMP の Script-fu というか TinyScheme で、数値から文字列に変換したものを桁揃え? ゼロ埋め? ゼロパディング? とにかくそういう感じの処理ができるか試したり。
GIMP起動後、フィルタ → Script-fu → Script-fuコンソール、を起動して、以下のように打ち込みながら動作確認。
要するに…。
ということで、できそうだなと。
一行で書くと、こうだろうか。
GIMP起動後、フィルタ → Script-fu → Script-fuコンソール、を起動して、以下のように打ち込みながら動作確認。
> (define cnt 3) cnt > cnt 3 > (number->string cnt) "3" > (string-append "0000" (number->string cnt)) "00003" > (define str (string-append "0000" (number->string cnt))) str > str "00003" > (substring str (- (string-length str) 3) (string-length str)) "003" > (substring str (- (string-length str) 4) (string-length str)) "0003" > (substring str (- (string-length str) 2) (string-length str)) "03"
要するに…。
- (number->string 数値) で、数値から文字列に変換。
- (string-append 文字列1 文字列2 文字列3) で、文字列を連結。
- (string-length 文字列) で、文字列の長さを取得。
- (substring 文字列 開始位置 終了位置) で、部分文字列(文字列の一部分)を取得。
ということで、できそうだなと。
一行で書くと、こうだろうか。
> (let* ((s (string-append "0000" (number->string cnt))) (n (string-length s))) (substring s (- n 2) n)) "03"
[ ツッコむ ]
#2 [gimp] GIMPのブラシ画像ファイルを作成する手順をメモ
GIMP用のブラシファイルを作成する手順をメモ。
◎ ブラシの種類。 :
まず前提として。GIMPのブラシ画像(一枚絵、.gbr)には2種類ある。
他にも、複数の画像を登録したパイプブラシ(.gih)や、ブラシエディターだけで作れる媒介変数つきブラシ(.vbr)、なるものもあるらしいけど。そのあたり自分は作ったことが無かったり。
_7. ブラシの追加
- グレースケール画像。白が透明で、黒が不透明(描画色)。描画色が反映される。アルファチャンネルは持てない。
- RGBA画像。アルファチャンネルを持てるが、描画色は反映されない。色は、画像の色がそのまま使われる。
他にも、複数の画像を登録したパイプブラシ(.gih)や、ブラシエディターだけで作れる媒介変数つきブラシ(.vbr)、なるものもあるらしいけど。そのあたり自分は作ったことが無かったり。
_7. ブラシの追加
◎ ブラシを一つ作成。 :
GIMPで、ブラシにしたい画像を作成するなり開くなりして、ファイル → 名前を付けてエクスポート → 拡張子を「.gbr」にして保存すればブラシファイルになる。
◎ ブラシを追加。 :
GIMPへブラシを追加する方法は、以下のページを見てもらったほうが分かりやすいかも。
_追加ブラシの使用方法
_GIMPにブラシを追加する方法 | GIMP2の使い方
_ゼロからのGIMP: ◆ブラシを追加する
ちなみに、brushes フォルダの中にサブフォルダを作って、その中にブラシファイルを追加すれば、それらのブラシにはサブフォルダ名でタグが付けられる。GIMPのブラシウインドウの上のほうに「タグで検索」てのがあるので、少しは有効に活用できるようになる、はず。
_2. GIMP
_3.6. タグづけ
_追加ブラシの使用方法
_GIMPにブラシを追加する方法 | GIMP2の使い方
_ゼロからのGIMP: ◆ブラシを追加する
ちなみに、brushes フォルダの中にサブフォルダを作って、その中にブラシファイルを追加すれば、それらのブラシにはサブフォルダ名でタグが付けられる。GIMPのブラシウインドウの上のほうに「タグで検索」てのがあるので、少しは有効に活用できるようになる、はず。
_2. GIMP
_3.6. タグづけ
◎ たくさんブラシを作りたい。 :
ブラシを1つ2つ作るだけなら、前述したように、一つ一つを手作業で保存して作ればいいのだけど。場合によっては、十数ファイルぐらいを一気にたくさん作りたい時もあって。
そういう時は、 _GIMPでPhotoshopのブラシを使おう の下のほうで紹介されてる、save-all-layers-as-brushes というスクリプトを使うと楽。コレを使うと、全レイヤーを1つ1つブラシファイルとして自動で保存してくれる。尚、件のページにはスクリプトの追加の仕方も書いてある。
例えば、ブラシにしたいpng画像がたくさんあったら、ひとまずGIMPのレイヤーにどんどん追加していく。
ただ、このスクリプト、ちと問題があって。十数ファイルほど保存すると、番号が、hoge1、hoge10、hoge12、hoge2、…みたいなことになってしまう。ブラシの順番がグチャグチャになるというか。
ということで、hoge01、hoge02、... hoge10、hoge11、となるように、スクリプトを少し修正してみたり。
_ブラシ保存スクリプト(Save All Layers as Brushes)で保存されるブラシ名の連番部分をゼロでパディングするように修正。
元のスクリプトのライセンスはGPLだから、改造版もソースを出しとけば問題ないだろう…。
そういう時は、 _GIMPでPhotoshopのブラシを使おう の下のほうで紹介されてる、save-all-layers-as-brushes というスクリプトを使うと楽。コレを使うと、全レイヤーを1つ1つブラシファイルとして自動で保存してくれる。尚、件のページにはスクリプトの追加の仕方も書いてある。
例えば、ブラシにしたいpng画像がたくさんあったら、ひとまずGIMPのレイヤーにどんどん追加していく。
- エクスプローラその他から、GIMPのレイヤーウインドウ?にドラッグして追加。
- または、GIMP上の、ファイル → レイヤーとして開く、でもOK。ファイル選択時に、Shift や Ctrlキーを押しながらクリックすれば複数のファイルを選んで一度にたくさん追加できる。
ただ、このスクリプト、ちと問題があって。十数ファイルほど保存すると、番号が、hoge1、hoge10、hoge12、hoge2、…みたいなことになってしまう。ブラシの順番がグチャグチャになるというか。
ということで、hoge01、hoge02、... hoge10、hoge11、となるように、スクリプトを少し修正してみたり。
_ブラシ保存スクリプト(Save All Layers as Brushes)で保存されるブラシ名の連番部分をゼロでパディングするように修正。
元のスクリプトのライセンスはGPLだから、改造版もソースを出しとけば問題ないだろう…。
[ ツッコむ ]
#3 [gimp] ドット絵用のGIMPブラシを作成
ドット絵バケーションの基本プリセット画像を参考にしながら、自分もドット絵用のパーツ画像を描いてみたり。
ちなみに、ライセンス的にドット絵バケーションのソレをコピペして使うわけにはいかないはずなので、全部自分でドットを打ち直しました。シルエットは同じでも、中のドットの打ち方やパレットの値は違うはず。
_pixelart_parts_a.png
各パーツは32x32ドット。画像のライセンスは CC0 / Public Domain ってことで。自由に使ってくださいな。
さて、この画像を、GIMPのブラシファイルに変換していきたいわけで。
ちなみに、ライセンス的にドット絵バケーションのソレをコピペして使うわけにはいかないはずなので、全部自分でドットを打ち直しました。シルエットは同じでも、中のドットの打ち方やパレットの値は違うはず。
_pixelart_parts_a.png
さて、この画像を、GIMPのブラシファイルに変換していきたいわけで。
◎ 画像を分割。 :
前述の画像を32x32ドット単位でバラバラに分割する。
今回は、Windows10 x64上で、 _PL_ImageConstructor というツールを使わせてもらって分割してみたり。このツール、透過png(アルファチャンネルを持ったpng)を対象にして色んな処理ができる。素晴らしい。
ちなみに、ImageMagick を使っても分割できるはず。 _Cutting and Bordering -- IM v6 Examples によると、-crop やら +repage やら +adjoin やらを使えばいいらしい。試してないけど。
さておき。これで、24ファイル、32x32ドットの透過pngができた。 → _split_images.zip
今回は、Windows10 x64上で、 _PL_ImageConstructor というツールを使わせてもらって分割してみたり。このツール、透過png(アルファチャンネルを持ったpng)を対象にして色んな処理ができる。素晴らしい。
ちなみに、ImageMagick を使っても分割できるはず。 _Cutting and Bordering -- IM v6 Examples によると、-crop やら +repage やら +adjoin やらを使えばいいらしい。試してないけど。
さておき。これで、24ファイル、32x32ドットの透過pngができた。 → _split_images.zip
◎ GIMPにレイヤーとして読み込む。 :
この大量の透過pngを、GIMPで読み込む。最初のファイルを開いたら、残りのファイルをレイヤーウインドウにドラッグ。これで全画像がレイヤーになってる画像を作れた。念のために一旦保存しておく。ファイル → 名前を付けて保存。.xcfファイルとして保存した。
◎ ブラシファイルとして書き出す。 :
Save All Layers as Brushes.scm を導入しておいて呼び出す。ファイル → レイヤーをブラシとして保存。ブラシファイルができた。
完成品はコチラ。
_gimp_brushes_pixelart_parts_a_20161006.zip (25KB)
CC0 / Public Domain ってことで。自由に使ってください。
ブラシとして追加すると、ブラシウインドウ内では、こんな感じの見た目になる。
完成品はコチラ。
_gimp_brushes_pixelart_parts_a_20161006.zip (25KB)
CC0 / Public Domain ってことで。自由に使ってください。
ブラシとして追加すると、ブラシウインドウ内では、こんな感じの見た目になる。
◎ 使い方。 :
[ ツッコむ ]
2016/10/07(金) [n年前の日記]
#1 [gimp] GIMPのブラシの謎
GIMP 2.8.18 Windows版を触ってて、ちょっと気になった点が。ブラシ名って変えられないのかな…。昨日作ったブラシの名前を変更しようとしても変更できなくて。謎。
_3.2. ブラシダイアログ によると、
ブラシファイル内の情報を書き換える専用ツールでもあれば…。しかしググってみてもそんなツールは存在しないようで。需要が無いのかな…。
ちなみに、.gbrのファイルフォーマット仕様は、gbr.txt なるファイルに書かれてるらしい。たぶんコレだろうけど。
_Gimp-Matting/gbr.txt at master - rggjan/Gimp-Matting
ブラシ名を変更するとブラシ名の文字列の長さが変わるので、その都度ヘッダサイズを変更しないといけない、ように見える。例えば事前に255文字まで登録できるように領域を固定で確保、とかそういうフォーマットではなかったようで。
_3.2. ブラシダイアログ によると、
一覧表に列挙して表示とあるのだけど…。
基本的には「並べて表示」と使い方に大差ありませんが、 次の点が異なります。
ブラシの名前はダブルクリックすると編集ができます。
ただし名前を変更できるのは自作のブラシや自前でインストールしたものに限られ、 GIMP 同梱でインストールされたブラシは対象外です。
仮に同梱版のブラシの名前を変えてみれば確かに編集はできますが、 確定しようとして Enter キーを押したりどこか他のところをクリックするとたちまち名前は元に戻されてしまいます。
GIMP と同時にインストールされるブラシ、 パターン、 グラデーションなどの資源は原則として変更不可です。
変更できるのは自作のものや自前のものだけです。
- 自作したブラシのはずだし、
- ユーザフォルダ内にブラシを追加してるし、
- 編集 → 設定 → フォルダー → ブラシ、で、ユーザフォルダの「書き込み可能フォルダー」にチェックも入れてある。
ブラシファイル内の情報を書き換える専用ツールでもあれば…。しかしググってみてもそんなツールは存在しないようで。需要が無いのかな…。
ちなみに、.gbrのファイルフォーマット仕様は、gbr.txt なるファイルに書かれてるらしい。たぶんコレだろうけど。
_Gimp-Matting/gbr.txt at master - rggjan/Gimp-Matting
ブラシ名を変更するとブラシ名の文字列の長さが変わるので、その都度ヘッダサイズを変更しないといけない、ように見える。例えば事前に255文字まで登録できるように領域を固定で確保、とかそういうフォーマットではなかったようで。
[ ツッコむ ]
#2 [gimp] GIMPでGIFアニメを作成する際のwait値を変更するスクリプトその2
GIMP でGIFアニメを作る際、レイヤー名に (100ms) 等の指定を描いておけば、そのwait値でそのレイヤー(というかフレーム)を表示してくれるわけだけど。再生速度を変更したい際は、全レイヤー名を一括変更できるスクリプトがあるとありがたいわけで。
一応、 _2015/11/28の日記 で一度探してはいたのだけど、今回探したら他にもヨサゲなスクリプトを見かけたので感謝しつつメモ。
一応、 _2015/11/28の日記 で一度探してはいたのだけど、今回探したら他にもヨサゲなスクリプトを見かけたので感謝しつつメモ。
◎ framerate-change.scm :
◎ rename_layers_for_animation.py :
◎ 前回探した時に見かけたスクリプトも再掲。 :
_Animation Frame Delay - GIMP Scripts
ファイル名は、layer_names.py。
_Ofnuts' Gimp Tools - Browse /scripts at SourceForge.net
ファイル名は、retime-linked-layers-0.0.py。
ファイル名は、layer_names.py。
_Ofnuts' Gimp Tools - Browse /scripts at SourceForge.net
ファイル名は、retime-linked-layers-0.0.py。
[ ツッコむ ]
#3 [pc] NVIDIA GeForce Experience 3.xが酷い
自分のメインPCに積んでいるビデオカードは、NVIDIA GeForce GTX 750 Ti モノなのだけど。NVIDIA製GPUを使ったビデオカードで色々なことができるようにしてくれる、NVIDIA GeForce Experience というユーティリティがあって。
その、NVIDIA GeForce Experience 3.0.7.34 が出たよ、てな通知が表示されたので、試しに入れてみたり。
うむ。酷い。これはちょっと酷い。
まず、前バージョンの GeForce Experience をアンインストールする段階で、いきなりランタイムエラーが出た。インストール処理でエラー出すような作りはダメ過ぎだろ…。結局、最新ドライバーをDLしてきて前バージョンの GeForce Experience まで入れ直す羽目に。
ググったところ、他のアプリが動いてる状態ではその手のエラーが出ることがあるらしい。ので、色々停止させた状態で再度インストールを試したら、今度はエラーが出なかった。何が原因なのやら。
更に、使うためには NVIDIAアカント or Googleアカウント or facebookアカウントが必要になるようで。…迂闊に個人情報なんか集めたら後々流出問題云々で大変なことになるだろうに、どうしてわざわざ集めるんだ。NVIDIA は馬鹿なんじゃないのか。
でもまあ、とりあえず、NVIDIAアカウントを取ってみようかと思ったら。入力内容が不適切だった際の警告表示のフォントが、小さくて細くて薄くて何が書いてあるのか読めない。コレ、たぶん、英語圏に合わせてフォントサイズを決めちゃったんじゃないのか…。そのフォントサイズ使って日本語・漢字で表示したら読めなくなるんだよ分かってねえなあ。仕方なくWindows10標準のルーペ機能で拡大して推測しながら読むことに。こんなUIデザインにしたヤツは一体どこのどいつだ。馬鹿なんじゃないのか。
生年月日の入力欄の、月の入力が英語。どうしてそこは素直に数字にしとかないのか…。こんなところも英語圏の人間だけを意識して作ってやがる。馬鹿なんじゃないのか。
そして、ShadowPlayの設定項目が見当たらないのだけど…。どこに行った…。まさか、機能削除されちゃったのかコレ…。
ということで、あちらこちらに馬鹿じゃないのかと思える箇所がチラホラと。まあ、一番馬鹿なのは、対応ゲームを1本も持ってないのにわざわざインストールした自分なんですけど。
とりあえずアンインストールして、前バージョンに戻したり。
しかしコレ、3.x が正式公開になったらしいから、そのうち差し替えられてしまうのだろうな…。せめてもうちょっと改善してほしいのだけど。
その、NVIDIA GeForce Experience 3.0.7.34 が出たよ、てな通知が表示されたので、試しに入れてみたり。
うむ。酷い。これはちょっと酷い。
まず、前バージョンの GeForce Experience をアンインストールする段階で、いきなりランタイムエラーが出た。インストール処理でエラー出すような作りはダメ過ぎだろ…。結局、最新ドライバーをDLしてきて前バージョンの GeForce Experience まで入れ直す羽目に。
ググったところ、他のアプリが動いてる状態ではその手のエラーが出ることがあるらしい。ので、色々停止させた状態で再度インストールを試したら、今度はエラーが出なかった。何が原因なのやら。
更に、使うためには NVIDIAアカント or Googleアカウント or facebookアカウントが必要になるようで。…迂闊に個人情報なんか集めたら後々流出問題云々で大変なことになるだろうに、どうしてわざわざ集めるんだ。NVIDIA は馬鹿なんじゃないのか。
でもまあ、とりあえず、NVIDIAアカウントを取ってみようかと思ったら。入力内容が不適切だった際の警告表示のフォントが、小さくて細くて薄くて何が書いてあるのか読めない。コレ、たぶん、英語圏に合わせてフォントサイズを決めちゃったんじゃないのか…。そのフォントサイズ使って日本語・漢字で表示したら読めなくなるんだよ分かってねえなあ。仕方なくWindows10標準のルーペ機能で拡大して推測しながら読むことに。こんなUIデザインにしたヤツは一体どこのどいつだ。馬鹿なんじゃないのか。
生年月日の入力欄の、月の入力が英語。どうしてそこは素直に数字にしとかないのか…。こんなところも英語圏の人間だけを意識して作ってやがる。馬鹿なんじゃないのか。
そして、ShadowPlayの設定項目が見当たらないのだけど…。どこに行った…。まさか、機能削除されちゃったのかコレ…。
ということで、あちらこちらに馬鹿じゃないのかと思える箇所がチラホラと。まあ、一番馬鹿なのは、対応ゲームを1本も持ってないのにわざわざインストールした自分なんですけど。
とりあえずアンインストールして、前バージョンに戻したり。
しかしコレ、3.x が正式公開になったらしいから、そのうち差し替えられてしまうのだろうな…。せめてもうちょっと改善してほしいのだけど。
[ ツッコむ ]
2016/10/08(土) [n年前の日記]
#1 [python] wxPyhonを勉強中
ちょっとやってみたい処理があって、GUIアプリを作れそうなフレームワークについてググって調べてたり。…やっぱり wxPython が楽かな、と思えてきたのでサンプルソースを眺めてるところ。
ググってみた感じでは…。CG業界は PyQt を使うことが多いらしい。まずは Python がCG業界のアレコレに浸透していて、更に Python 3.x でも使えるとしたら、となると PyQt になるようで。ライセンス的には PyQt より PySide のほうがいいけれど、PyQt は Qt5 にも対応してるけど、PySide は Qt4 までの対応、らしいので…。
ググってみた感じでは…。CG業界は PyQt を使うことが多いらしい。まずは Python がCG業界のアレコレに浸透していて、更に Python 3.x でも使えるとしたら、となると PyQt になるようで。ライセンス的には PyQt より PySide のほうがいいけれど、PyQt は Qt5 にも対応してるけど、PySide は Qt4 までの対応、らしいので…。
[ ツッコむ ]
#2 [neta] ラスボスは居なかった設定とヒロインは別人だった設定
寝ていたら、夢の中に名探偵コナンの映像が出てきたのだけど。そこで出てきた設定が、目が覚めてからもなんだか引っ掛かったので、なんとなくメモ。妄想メモ。
一つは、黒の組織にラスボスは居なかった、という設定。
一つは、蘭姉ちゃんは本物と偽物(FBIから派遣されたコナン君の身辺警護をする人物)が居て時々入れ替わってた、あるいは、物語の早い段階で蘭姉ちゃんは組織から殺されていてずっと別人が蘭姉ちゃんを演じてた、という設定。
目が覚めてから、なんじゃその設定、訳分からん、と思ったけど、もしかしてアレンジすれば何かに使えたりもするのかなと。
一つは、黒の組織にラスボスは居なかった、という設定。
一つは、蘭姉ちゃんは本物と偽物(FBIから派遣されたコナン君の身辺警護をする人物)が居て時々入れ替わってた、あるいは、物語の早い段階で蘭姉ちゃんは組織から殺されていてずっと別人が蘭姉ちゃんを演じてた、という設定。
目が覚めてから、なんじゃその設定、訳分からん、と思ったけど、もしかしてアレンジすれば何かに使えたりもするのかなと。
◎ ラスボス居ない設定。 :
漫画やアニメに出てくる悪の組織にはえてしてラスボスが居るもんだけど。悪の組織のメンバー全員が、自分達にはボスが居るもんだろうと思い込んで行動してたけど、実はボスなんて居なかった、皆で居るような気がしていただけだった、というのは展開としてちょっとビックリ、しないかな。どうかな。どうなんだろう。なんだか、「ルパンなんて実は居なかった」をテーマにする予定だった押井ルパンをちょっと思い出したりもするけど。
考えてみたら、現実世界では時々そういう場面があるよなと。例えば、太平洋戦争中のアレコレは旧日本軍が行ったとか、軍の命令で泣く泣く実行したとかそういう話があったりするけど。よくよく調べてみると軍がそういう命令を出したという記録が無かったり、たまたま組織の長が精神論を振りかざして実行させたとかそういう事実が発掘されたりもするわけで。沖縄の自決強要のアレコレとか、上野動物園の大型動物の殺処分とか。上はそこまで命令出してないのに、どこかで誰かが話を捻じ曲げて、みたいな。
北朝鮮の将軍様だって、どこまでラスボス扱いが妥当なのかちょっと分からんところがあるよなと。太平洋戦争中の昭和天皇みたいなポジションだったりしないのかと。あの国ではなんでもかんでも将軍様の命令ってことにされてるけど、後になってから「俺そんなこと言ってねえ」てな話になる可能性だってあるよなと。戦時中の日本がそうだったのだし。
こういうのは、ラスボスなんて居なかったけど皆でなんとなくラスボスが居るような気になってた、てな状況に近いのかもなと。空気に支配されて行動してた、強いて言えば空気がラスボス相当だった、みたいな。ということで、現実世界ではあり得る話なのだから、娯楽作品内でもそういう設定があったら妙なところでリアルだな、という印象になりそうな予感も。まあ、空気云々はガッチャマンクラウズで描いてた記憶もあるけど。
もっとも、娯楽作品でそういう設定が出てきてしまうと読者視聴者はストレスが溜まりそうでもあるなと。ラスボス倒したぞ、コレでハッピーエンドだ、てなスッキリした話にならないわけで。皆が皆、アレは仕方なかったんだ、俺は与えられた仕事を忠実にこなしてただけだ、などと言い訳し始めるだろうし。戦犯は誰だよと問い詰めてみても口を揃えて俺じゃない俺じゃないの大合唱。これは見ていてかなりイライラするはず。A級戦犯のソレをちょっと連想しないでもない。てなわけで、ちと使いどころが難しい設定だったりするのかもしれず。
考えてみたら、現実世界では時々そういう場面があるよなと。例えば、太平洋戦争中のアレコレは旧日本軍が行ったとか、軍の命令で泣く泣く実行したとかそういう話があったりするけど。よくよく調べてみると軍がそういう命令を出したという記録が無かったり、たまたま組織の長が精神論を振りかざして実行させたとかそういう事実が発掘されたりもするわけで。沖縄の自決強要のアレコレとか、上野動物園の大型動物の殺処分とか。上はそこまで命令出してないのに、どこかで誰かが話を捻じ曲げて、みたいな。
北朝鮮の将軍様だって、どこまでラスボス扱いが妥当なのかちょっと分からんところがあるよなと。太平洋戦争中の昭和天皇みたいなポジションだったりしないのかと。あの国ではなんでもかんでも将軍様の命令ってことにされてるけど、後になってから「俺そんなこと言ってねえ」てな話になる可能性だってあるよなと。戦時中の日本がそうだったのだし。
こういうのは、ラスボスなんて居なかったけど皆でなんとなくラスボスが居るような気になってた、てな状況に近いのかもなと。空気に支配されて行動してた、強いて言えば空気がラスボス相当だった、みたいな。ということで、現実世界ではあり得る話なのだから、娯楽作品内でもそういう設定があったら妙なところでリアルだな、という印象になりそうな予感も。まあ、空気云々はガッチャマンクラウズで描いてた記憶もあるけど。
もっとも、娯楽作品でそういう設定が出てきてしまうと読者視聴者はストレスが溜まりそうでもあるなと。ラスボス倒したぞ、コレでハッピーエンドだ、てなスッキリした話にならないわけで。皆が皆、アレは仕方なかったんだ、俺は与えられた仕事を忠実にこなしてただけだ、などと言い訳し始めるだろうし。戦犯は誰だよと問い詰めてみても口を揃えて俺じゃない俺じゃないの大合唱。これは見ていてかなりイライラするはず。A級戦犯のソレをちょっと連想しないでもない。てなわけで、ちと使いどころが難しい設定だったりするのかもしれず。
◎ ヒロインは別人だった設定。 :
ヒロイン的ポジションと思ってたキャラが実は知らないところで別人とすり替わってた、てのはビックリ、しないかな。どうかな。どうなんだろう。
事前に「別人ですよ」と提示しておくなら、アリなのかな。例えば、∀ガンダムがソレだった気もするし。
実はヒロインが既に死んでいて、別人がそこに居た、というのは…。もしかするとEVAの綾波もその系統になったりするのだろうか。EVAの場合は、ヒロインがそうなる場面が分かりやすかったけど、もし、終盤で、「えっ? あそこでそうなってたの? …あー、言われてみれば」的な見せ方をしてたら更にビックリ、したのだろうか。したのかなあ。
名探偵コナンで、蘭姉ちゃんは既に死んでいた、とかだったらちょっとビックリ、どころじゃないだろうな。ソレを知った時のコナン君の気持ちを想像すると…。今まで散々、「俺が蘭を守る!」とか言ってたのに最初から全然守れてなかったとかどう考えてもキツイ。まあ、あの作品でそういう展開にするのは無理があるけど。
ヒロインじゃないけれど、俺は主役だ、主役級のキャラだ、と、主役が思っていたけど実はそうじゃなかった、てな感じの設定のRPGがあったような気も。 *1
読者視聴者は、このキャラは主役だろう、ヒロインだろう、などと思いながらその手の娯楽作品を楽しんでるはずだけど。そこを一旦何かしらでひっくり返すのは、なんだか面白くなりそうでもあるなと。
まあ、どれもこれも寝言です。ていうか夢の中で出てきた設定なので正真正銘の寝言ですが。
事前に「別人ですよ」と提示しておくなら、アリなのかな。例えば、∀ガンダムがソレだった気もするし。
実はヒロインが既に死んでいて、別人がそこに居た、というのは…。もしかするとEVAの綾波もその系統になったりするのだろうか。EVAの場合は、ヒロインがそうなる場面が分かりやすかったけど、もし、終盤で、「えっ? あそこでそうなってたの? …あー、言われてみれば」的な見せ方をしてたら更にビックリ、したのだろうか。したのかなあ。
名探偵コナンで、蘭姉ちゃんは既に死んでいた、とかだったらちょっとビックリ、どころじゃないだろうな。ソレを知った時のコナン君の気持ちを想像すると…。今まで散々、「俺が蘭を守る!」とか言ってたのに最初から全然守れてなかったとかどう考えてもキツイ。まあ、あの作品でそういう展開にするのは無理があるけど。
ヒロインじゃないけれど、俺は主役だ、主役級のキャラだ、と、主役が思っていたけど実はそうじゃなかった、てな感じの設定のRPGがあったような気も。 *1
読者視聴者は、このキャラは主役だろう、ヒロインだろう、などと思いながらその手の娯楽作品を楽しんでるはずだけど。そこを一旦何かしらでひっくり返すのは、なんだか面白くなりそうでもあるなと。
まあ、どれもこれも寝言です。ていうか夢の中で出てきた設定なので正真正銘の寝言ですが。
*1: や、自分は途中までプレイして放置しちゃったから本当にそういう設定だったのか分かりませんが、伝え聞くところによるとそういう感じの設定だったらしい。
[ ツッコむ ]
2016/10/09(日) [n年前の日記]
#1 [cg_tools] JTrimが便利そう
プログラミングをする際の実験用画像を作成する際に、えてして画像をリサイズしてトリミングしたりするのだけど。たったそれだけの作業をしたいがために、GIMPを起動するのはシンドイなと。何せ自分の環境では、GIMPが起動するまで1分以上かかるわけで。ブラシ、フォント、スクリプト、プラグインを山ほど入れまくってるせいだと思うけど。
一応、 _PixBuilder Studio というフリーの画像編集ソフトも併用していて、コレなら結構早く起動してくれるのだけど。これはこれで、トリミング時の調整作業が難しくて。
起動時間が短くて、かつ、目的を果たせるツールはないものか…。と思ったところで、JTrim の存在を思い出して。試用してみたところ、圧倒的に起動が早かった。リサイズとトリミングぐらいなら、コレで十分だなと。
一応、 _PixBuilder Studio というフリーの画像編集ソフトも併用していて、コレなら結構早く起動してくれるのだけど。これはこれで、トリミング時の調整作業が難しくて。
起動時間が短くて、かつ、目的を果たせるツールはないものか…。と思ったところで、JTrim の存在を思い出して。試用してみたところ、圧倒的に起動が早かった。リサイズとトリミングぐらいなら、コレで十分だなと。
◎ PhotoScapeも試してみたけど。 :
PhotoScapeというソフトの評判もいいみたいなので少し試用してみたけれど。リサイズ時のアルゴリズムが選べない上に結果がボケボケになるのが厳しいなと。機能豊富なあたりはヨサゲなのだけど。
[ ツッコむ ]
#2 [prog] Visual Studio Codeを試用中
Visual Studio Code は、Microsoftが開発したエディタ。気になってきたので、インストールして少し触ってみたり。
_Visual Studio Code - Wikipedia
_Visual Studio Code - Code Editing. Redefined
Windows、Mac、Linux、どのOSでも動くらしい。
Electron を使ってるとのことで、 _Atomエディタ と似たようなものだろうかと思ったら全然起動が早くて驚いた。かなりイイ感じ。
Visual Studio Code にPython用の拡張を入れて、Pythonスクリプトを書いてみたけど、そこそこ補完が効いてくれる、ような気がする。イイ感じ。
_Visual Studio Code - Wikipedia
_Visual Studio Code - Code Editing. Redefined
Windows、Mac、Linux、どのOSでも動くらしい。
Electron を使ってるとのことで、 _Atomエディタ と似たようなものだろうかと思ったら全然起動が早くて驚いた。かなりイイ感じ。
Visual Studio Code にPython用の拡張を入れて、Pythonスクリプトを書いてみたけど、そこそこ補完が効いてくれる、ような気がする。イイ感じ。
[ ツッコむ ]
#3 [python] wxPythonを再勉強中
wxPythonで表示したウインドウの中でマウスを動かすと何かが描ける、ようなことをしてみたい。
◎ ウインドウ内がちらつく版。 :
最初に書いたのはコレ。
_drawing_test.py
しかしこのスクリプトは画面がちらつく。
_drawing_test.py
""" 描画テスト。 マウスボタンを押した時だけ画面に何かを描画する。 ただし、この書き方では画面がちらつく。 VerySimpleDrawing - wxPyWiki https://wiki.wxpython.org/VerySimpleDrawing wxPythonのPaintDCでアンチエイリアスや透過を使う :右京web http://hujimi.seesaa.net/article/161079355.html """ import wx bg_image = "images/bg.jpg" class DrawPanel(wx.Frame): def __init__(self, *args, **kwargs): """初期化""" wx.Frame.__init__(self, *args, **kwargs) # ワーク確保 self.mouseLeftFlag = False self.pos = wx.Point(0, 0) # イベント割り当て self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown) self.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp) self.Bind(wx.EVT_MOTION, self.OnMouseMove) # 背景bitmap画像読み込み image = wx.Image(bg_image) self.bitmap = image.ConvertToBitmap() # 画像サイズでフレームサイズを設定し直し self.SetSize(image.GetSize()) def OnMouseLeftDown(self, e): """ 左ボタンを押した時の処理 """ pos = e.GetPosition() self.pos = pos self.mouseLeftFlag = True self.Refresh() def OnMouseMove(self, e): """ マウスカーソルを動かした時の処理 """ if self.mouseLeftFlag: pos = e.GetPosition() self.pos = pos self.Refresh() def OnMouseLeftUp(self, e): """ 左ボタンを離した時の処理 """ pos = e.GetPosition() self.pos = pos self.mouseLeftFlag = False self.Refresh() def OnPaint(self, event=None): """ 描画処理 """ pdc = wx.PaintDC(self) try: # アンチエイリアスをかける dc = wx.GCDC(pdc) except: dc = pdc dc.Clear() dc.DrawBitmap(self.bitmap, 0, 0, True) # 背景ビットマップ画像を描画 if self.mouseLeftFlag: # 円を描画 dc.SetBrush(wx.Brush(wx.Colour(255, 0, 0, 64))) dc.SetPen(wx.Pen("RED", 2)) x = self.pos.x - 50 y = self.pos.y - 50 dc.DrawEllipse(x, y, 100, 100) if __name__ == '__main__': app = wx.App(False) frame = DrawPanel(parent=None, title=u"ウインドウ内でマウスボタンを押してみるべし") frame.Show() app.MainLoop()
しかしこのスクリプトは画面がちらつく。
◎ ウインドウ内がちらつかない版。 :
画面がちらつかないようにするには、wx.BufferedDC() を使うといいらしい。
_drawing_test2.py
たしかにちらつかなくなった。
_drawing_test2.py
""" 描画テスト。 マウスボタンを押した時だけ画面に何かを描画する。 ちらつきを少なくする。 VerySimpleDrawing - wxPyWiki https://wiki.wxpython.org/VerySimpleDrawing wxPythonのPaintDCでアンチエイリアスや透過を使う :右京web http://hujimi.seesaa.net/article/161079355.html wxPython の画面に色々描く(+マウスのイベントを処理する) - 見切り発車 http://d.hatena.ne.jp/uyamae/20090305/1236261541 """ import wx class DrawPanel(wx.Frame): def __init__(self, *args, **kwargs): """初期化""" wx.Frame.__init__(self, *args, **kwargs) # ワーク確保 self.mouseLeftFlag = False self.pos = wx.Point(0, 0) # イベント割り当て self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown) self.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp) self.Bind(wx.EVT_MOTION, self.OnMouseMove) # 画像読み込み image = wx.Image("images/bg.jpg") self.bitmap = image.ConvertToBitmap() # 画像サイズでフレームサイズを設定し直し self.SetSize(image.GetSize()) def OnMouseLeftDown(self, e): """ 左ボタンを押した時の処理 """ pos = e.GetPosition() self.pos = pos self.mouseLeftFlag = True self.Refresh(False) def OnMouseMove(self, e): """ マウスカーソルを動かした時の処理 """ if self.mouseLeftFlag: pos = e.GetPosition() self.pos = pos self.Refresh(False) def OnMouseLeftUp(self, e): """ 左ボタンを離した時の処理 """ pos = e.GetPosition() self.pos = pos self.mouseLeftFlag = False self.Refresh(False) def OnPaint(self, event=None): """ 描画処理 """ pdc = wx.BufferedDC(wx.PaintDC(self)) try: # アンチエイリアスをかける dc = wx.GCDC(pdc) except: dc = pdc dc.Clear() dc.DrawBitmap(self.bitmap, 0, 0, True) # ビットマップ画像を描画 if self.mouseLeftFlag: # 円を描画 dc.SetBrush(wx.Brush(wx.Colour(255, 0, 0, 64))) dc.SetPen(wx.Pen("RED", 2)) x = self.pos.x - 50 y = self.pos.y - 50 dc.DrawEllipse(x, y, 100, 100) if __name__ == '__main__': app = wx.App(False) frame = DrawPanel(parent=None, title=u"ウインドウ内でマウスボタンを押してみるべし") frame.Show() app.MainLoop()
たしかにちらつかなくなった。
◎ スクロールできる版。 :
調子に乗って、ウインドウ内をスクロールできるソレにしてみた。ついでにブラシ相当をビットマップ画像にして描画。
_drawing_test3.py
実験に使った画像は以下。スクリプトと同じ場所に images というフォルダを作成して、その中に入れて使った。
_bg.jpg
_ball.png
_drawing_test3.py
""" 画面にマウスで円を描画する。 スクロールバーでウインドウをスクロールできる版。 """ import wx draw_bitmap_brsuh = True bitmap_brush_image = "images/ball.png" class DrawPanel(wx.ScrolledWindow): def __init__(self, parent): wx.ScrolledWindow.__init__(self, parent, -1) self.maxWidth = 1024 self.maxHeight = 768 self.rate = wx.Point(8, 8) self.brushBitmap = None if draw_bitmap_brsuh: image = wx.Image(bitmap_brush_image) self.brushBitmap = image.ConvertToBitmap() self.SetVirtualSize((self.maxWidth, self.maxHeight)) self.SetScrollRate(self.rate.x, self.rate.y) # 空のビットマップを確保。以後はこれに描画していく self.buffer = wx.EmptyBitmap(self.maxWidth, self.maxHeight) self.buttonFlag = False self.DrawFirst() # 初期描画 # イベント割り当て self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftButtonEvent) self.Bind(wx.EVT_LEFT_UP, self.OnLeftButtonEvent) self.Bind(wx.EVT_MOTION, self.OnLeftButtonEvent) def OnPaint(self, event=None): dc = wx.BufferedPaintDC(self, self.buffer, wx.BUFFER_VIRTUAL_AREA) def OnLeftButtonEvent(self, event): if self.IsAutoScrolling(): self.StopAutoScrolling() pos = event.GetPosition() if event.LeftDown(): # マウスの左ボタンを押した self.DrawMiniCircle(pos.x, pos.y) self.buttonFlag = True elif event.Dragging() and self.buttonFlag: # マウスカーソルを動かした if self.buttonFlag: self.DrawMiniCircle(pos.x, pos.y) elif event.LeftUp() and self.buttonFlag: # マウスの左ボタンを離した self.buttonFlag = False def DrawMiniCircle(self, x, y): """ 指定座標に小さい円を描画 """ pdc = wx.BufferedDC(None, self.buffer) try: # アンチエイリアスをかける dc = wx.GCDC(pdc) except: dc = pdc # スクロールを考慮した座標値を取得 nx, ny = self.CalcUnscrolledPosition(x, y) if draw_bitmap_brsuh: # ビットマップ画像をブラシにして描画 nx -= self.brushBitmap.GetWidth() / 2 ny -= self.brushBitmap.GetHeight() / 2 dc.DrawBitmap(self.brushBitmap, nx, ny, True) else: # 円をブラシにして描画 dc.SetBrush(wx.Brush(wx.Colour(192, 192, 255))) dc.SetPen(wx.Pen("BLACK", 0)) dc.DrawCircle(nx, ny, 16) del dc self.Refresh(False) def DrawFirst(self): """ 初期描画 """ pdc = wx.BufferedDC(None, self.buffer) try: dc = wx.GCDC(pdc) except: dc = pdc dc.SetBackground(wx.Brush(self.GetBackgroundColour())) dc.Clear() # 円を描画 dc.SetBrush(wx.Brush(wx.Colour(128, 128, 255))) dc.SetPen(wx.Pen("GREEN", 1)) dc.DrawCircle(100, 100, 100) dc.SetBrush(wx.Brush(wx.Colour(128, 255, 128))) dc.SetPen(wx.Pen("RED", 3)) dc.DrawCircle(self.maxWidth - 100, 100, 100) del dc class MyApp(wx.App): def OnInit(self): frame = wx.Frame(None, -1, "Draw Test 3", size=(640, 480)) DrawPanel(frame) frame.Show() self.SetTopWindow(frame) return True if __name__ == '__main__': app = MyApp() app.MainLoop()
実験に使った画像は以下。スクリプトと同じ場所に images というフォルダを作成して、その中に入れて使った。
_bg.jpg
_ball.png
この記事へのツッコミ
[ ツッコミを読む(1) | ツッコむ ]
#4 [pc] 画面をキャプチャするソフトの調子がよろしくない
今まで、Windows のデスクトップ画面をキャプチャしてアニメGIFで保存する際、GifCam 5.1 を使っていたのだけど。どうもここ最近、途中で緑一色のアニメGIFになってしまうことが多くて、ちと困ったなと。
代わりのソフトを探してみたり。とりあえず、ScreenToGif 2.2 を使ってみた。
これも一部の表示がおかしくなるな…。でも、GifCam より、マシな結果が得られそう。しばらくこちらを試用してみるか…。
しかし、どうして GifCam が正常動作しないのだろう。何か常駐ソフトの類が悪さをしてるんだろうか。
代わりのソフトを探してみたり。とりあえず、ScreenToGif 2.2 を使ってみた。
これも一部の表示がおかしくなるな…。でも、GifCam より、マシな結果が得られそう。しばらくこちらを試用してみるか…。
しかし、どうして GifCam が正常動作しないのだろう。何か常駐ソフトの類が悪さをしてるんだろうか。
[ ツッコむ ]
2016/10/10(月) [n年前の日記]
#1 [python] Pylintの設定ファイルについて
Windows10 x64上で、PySide という、Python と Qt4 を使ってGUIアプリを作れるフレームワークについて勉強しようとして Visual Studio Code でサンプルソースを開いてみたら、やたらめったら警告だかなんだかが表示されて。「こんな名前知らねえ」とかなんとか。
どうやら Visual Studio Code は、裏で Pylint というPythonのソースをチェックしてくれるツールが走るようで。つまり Pylint が文句を言いまくってる状態、だと思うのだけど。その Pylint に、「PySideってのを使うからよろしくな」と伝えてやらないといかんようだなと。で、ググった感じでは、
さて、これをどこで指定してやれば…。
以下のページで解説されてた。
_Pythonの主要なLint(pep8, pylint, flake8)の設定方法まとめ - Qiita
_[Python]pep8とpylintの設定ファイルを作成して一部の警告を非表示にする - dackdive's blog
_Pythonの開発環境をプロジェクト単位にWindows環境で用意する(VSCode+virtualEnvWrapper+Pylint) - Qiita
例えば、カレントフォルダに pylintrc なるファイルを作成して、そこに色々指定してやれば設定ができるっぽい。
pylintrc の作り方は、
これで、DOS窓上で pylint hoge.py と打つ分にはそれほど怒られなくなった。また、Visual Studio Code 上でもソースが真っ赤にならなくなった。
$HOME/.config/pylintrc を置いとけば、各フォルダに一々作らなくてもいいのだろうか。一応自分の環境では環境変数 HOME を設定済みなので、そのフォルダの下に .config/pylintrc を置いてみた。…DOS窓上では、ちゃんと設定が読み込まれてるように見える。どうやら Windows上でも、該当ファイルが共通設定として使われるらしい。
どうやら Visual Studio Code は、裏で Pylint というPythonのソースをチェックしてくれるツールが走るようで。つまり Pylint が文句を言いまくってる状態、だと思うのだけど。その Pylint に、「PySideってのを使うからよろしくな」と伝えてやらないといかんようだなと。で、ググった感じでは、
pylint --extension-pkg-whitelist=PySide hoge.pyみたいな指定をしてやると怒られなくなる、ということらしく。
さて、これをどこで指定してやれば…。
以下のページで解説されてた。
_Pythonの主要なLint(pep8, pylint, flake8)の設定方法まとめ - Qiita
_[Python]pep8とpylintの設定ファイルを作成して一部の警告を非表示にする - dackdive's blog
_Pythonの開発環境をプロジェクト単位にWindows環境で用意する(VSCode+virtualEnvWrapper+Pylint) - Qiita
例えば、カレントフォルダに pylintrc なるファイルを作成して、そこに色々指定してやれば設定ができるっぽい。
pylintrc の作り方は、
pylint --generate-rcfile > pylintrcで雛形ができるから、後はソレを開いて修正を。今回は、以下の修正を加えてみた。
extension-pkg-whitelist= ↓ extension-pkg-whitelist=PySide
これで、DOS窓上で pylint hoge.py と打つ分にはそれほど怒られなくなった。また、Visual Studio Code 上でもソースが真っ赤にならなくなった。
$HOME/.config/pylintrc を置いとけば、各フォルダに一々作らなくてもいいのだろうか。一応自分の環境では環境変数 HOME を設定済みなので、そのフォルダの下に .config/pylintrc を置いてみた。…DOS窓上では、ちゃんと設定が読み込まれてるように見える。どうやら Windows上でも、該当ファイルが共通設定として使われるらしい。
◎ Pylintのインストール方法。 :
Windows 10 x64 + Python 2.7.11 では、以下でインストールできるっぽい?
バージョン確認。
pip install pylintアップデートは以下。
pip install -U pylint
バージョン確認。
> pylint --version pylint 1.6.4, astroid 1.4.8 Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec 5 2015, 20:32:19) [MSC v.1500 32 bit (Intel)]
[ ツッコむ ]
2016/10/11(火) [n年前の日記]
#1 [python] PySide勉強中
Python + PySide を使って、マウスボタンを押してドラッグするとウインドウ内に何かを描く、みたいな処理をしてみたい。
こんな感じだろうか…。
_drawing_pyside_3.py
_ball.png
こんな感じだろうか…。
_drawing_pyside_3.py
""" PySideでウインドウに描画。 空の QPixmap を作ってそこに描画する例。 マウス左ボタンを押して動かすとその位置に円を描画する。 参考ページ: 「プログラムでシダを描画する」をPythonで描画過程まで出力する - Qiita http://qiita.com/tatuno/items/23d291dd3bf01693bde4 [Python][PySide] 簡単なメニュー付きウィンドウを表示する | unlinked log http://log.noiretaya.com/?p=250 PyQtでのグラフィックス その1 (QWidgetに直接描画する) - bravo's blog http://bravo.hatenablog.jp/entry/2016/02/07/084048 """ import sys from PySide.QtCore import * from PySide.QtGui import * width = 480 height = 360 brush_use = True brush_filename = "ball.png" class MyWidget(QWidget): """描画担当ウィジェット""" def __init__(self, parent): super(MyWidget, self).__init__(parent) self.mouseOnFlag = False # 空のQPixmapを生成。以後はここに描画していく self.pixmap = QPixmap(width, height) self.pixmap.fill() # ブラシ画像を読み込み self.brush_pixmap = QPixmap(brush_filename) def paintEvent(self, event): qp = QPainter() qp.begin(self) qp.drawPixmap(0, 0, self.pixmap) qp.end() def mousePressEvent(self, event): """ マウスボタンを押した """ if event.button() == Qt.LeftButton: self.mouseOnFlag = True self.mydraw(event) def mouseMoveEvent(self, event): """ マウスを動かした """ if self.mouseOnFlag: self.mydraw(event) def mouseReleaseEvent(self, event): """ マウスボタンを離した """ if event.button() == Qt.LeftButton: self.mouseOnFlag = False def mydraw(self, event): """ 描画処理 """ qp = QPainter() qp.begin(self.pixmap) # マウス座標取得 x = event.pos().x() y = event.pos().y() if brush_use: # ブラシ画像で描画 x -= self.brush_pixmap.width() / 2 y -= self.brush_pixmap.height() / 2 qp.drawPixmap(x, y, self.brush_pixmap) else: # 円を描画 qp.setBrush(QColor(0, 0, 128)) qp.setPen(QColor(0, 64, 255)) qp.drawEllipse(event.pos(), 20, 20) # 点を描画する例 # qp.drawPoint(x, y) qp.end() self.repaint() class MainWindow(QMainWindow): """ メインウインドウ """ def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.resize(width, height) # self.setFixedSize(width, height) # self.refresh_rate = 200 # メニューバー作成 menubar = QMenuBar() file_menu = QMenu("&File", self) exit_action = file_menu.addAction("&Exit") exit_action.setShortcut("Ctrl+Q") exit_action.triggered.connect(qApp.quit) menubar.addMenu(file_menu) self.setMenuBar(menubar) # ステータスバー作成 self.statusBar() # 描画するウィジェットを作成して真ん中に配置 widget = MyWidget(self) self.setCentralWidget(widget) def main(): app = QApplication(sys.argv) window = MainWindow() app.setActiveWindow(window) window.show() sys.exit(app.exec_()) if __name__ == '__main__': main()使ったブラシ画像は以下。
_ball.png
[ ツッコむ ]
#2 [nitijyou] 市の健康診断に行ってきた
AM09:30-AM10:40まで。それほど混雑してる感じではなかったけど、血圧測定と血液検査で待たされて、1時間以上かかった感じ。
毎年、北団地の集会所で受けてたけど、今年は期日を把握してなくてうっかり機会を逃してしまい、もう少し遠い、森宿区民会館で受けることに。場所も把握してなければ中に入ったこともなかったけど、結構綺麗な建物だなと感心(?)を。
親父さんの電動自転車を借りて行ってきたけど…。区民会館が面してる道路が、歩道が無いぐらいに細いのに何故か異様に車の通行量が多く、しかもどの車もビュンビュン飛ばすので、自転車で通るのも一苦労。あの調子だといつか事故が起きそうな気がする。かといってどう見ても道路を広げる等の工事ができそうにない状態だし。一般住宅に加えて工場までギリギリに建ってるし。どうするんだろ。どうしようもないか。
毎年、北団地の集会所で受けてたけど、今年は期日を把握してなくてうっかり機会を逃してしまい、もう少し遠い、森宿区民会館で受けることに。場所も把握してなければ中に入ったこともなかったけど、結構綺麗な建物だなと感心(?)を。
親父さんの電動自転車を借りて行ってきたけど…。区民会館が面してる道路が、歩道が無いぐらいに細いのに何故か異様に車の通行量が多く、しかもどの車もビュンビュン飛ばすので、自転車で通るのも一苦労。あの調子だといつか事故が起きそうな気がする。かといってどう見ても道路を広げる等の工事ができそうにない状態だし。一般住宅に加えて工場までギリギリに建ってるし。どうするんだろ。どうしようもないか。
[ ツッコむ ]
2016/10/12(水) [n年前の日記]
#1 [python] PySideをまだ勉強中
Python + PySide には、QGraphicsView、QGraphicsScene、QGraphicsItem 等の便利そうなソレがあるので、そのあたりを使ってマウスを動かすと何か描ける、みたいなソレを試しているところ。
考え方としては、空のビットマップ(QPixmap) を作って、QGraphicsPixmapItem として QGraphicsScene に追加登録してやればいいのではないか、後は空のビットマップの上に QPainter を使って色々描いていけばいいのでは、と思って試してるのだけど、描画後に画面というかウインドウ内にそのビットマップを再描画する方法が分からず。update() や refresh() じゃダメなのか…?
考え方としては、空のビットマップ(QPixmap) を作って、QGraphicsPixmapItem として QGraphicsScene に追加登録してやればいいのではないか、後は空のビットマップの上に QPainter を使って色々描いていけばいいのでは、と思って試してるのだけど、描画後に画面というかウインドウ内にそのビットマップを再描画する方法が分からず。update() や refresh() じゃダメなのか…?
[ ツッコむ ]
2016/10/13(木) [n年前の日記]
#1 [ruby] Windows10 + Ruby/Tk でエクスプローラからファイルをD&Dしてファイルパスを取得
Windows10 x64 + Ruby 2.2.5 p319 + Ruby/Tk + TkDND 2.8 で、エクスプローラからファイルをD&D(ドラッグアンドドロップ)して、ファイルパスを取得できるか実験。
参考ページは以下。
_[ruby-list:49771] TkDND での日本語名の扱い
_DebianでRubyからTcl/TkのTkDNDを利用してドラッグアンドドロップを実装する -- ぺけみさお
_tkdnd_test.rb
スクリプトを実行して表示されたウインドウに、エクスプローラからファイルをD&Dしてみた。
できたっぽい。
が、日本語ファイル名は、たしかに化けてるな…。
_[ruby-list:49771] TkDND での日本語名の扱い で紹介されてる変換処理を入れてみた。ついでに、複数ファイルを渡した時に全部処理するようにしてみた。
_tkdnd_test2.rb
文字化けしてないように見える。
が。 _[ruby-list:50353] [再]Re: TkDND での日本語名の扱い によると、空白が入ったファイル名を渡したり、\が入ったファイル名を渡すとおかしくなるそうで。試してみたところ、たしかにエラーが表示された。このあたり、なかなか厳しいものがあるようで。
参考ページは以下。
_[ruby-list:49771] TkDND での日本語名の扱い
_DebianでRubyからTcl/TkのTkDNDを利用してドラッグアンドドロップを実装する -- ぺけみさお
_tkdnd_test.rb
# Ruby/Tk + tkDND でファイルのドロップを受け付けるかテスト # Tk拡張を導入していないと動作しない。 # # [ruby-list:49771] TkDND での日本語名の扱い # http://ruby-list.ruby-lang.narkive.com/lx7VFWDo/ruby-list-49771-tkdnd # # DebianでRubyからTcl/TkのTkDNDを利用してドラッグアンドドロップを実装する -- ぺけみさお # https://www.xmisao.com/2013/07/25/ruby-tkdnd-linux.html require 'tk' require "tkextlib/tkDND" Tk::TkDND::DND label = TkLabel.new { text "Please File Drop" pack } txt = TkText.new(nil){ dnd_bindtarget('text/uri-list','<Drop>', "%D") { |d| p d insert('end',d[0]) insert('end',"\n") } pack } TkButton.new { text "Exit" command "exit" pack } Tk.mainloop
スクリプトを実行して表示されたウインドウに、エクスプローラからファイルをD&Dしてみた。
できたっぽい。
が、日本語ファイル名は、たしかに化けてるな…。
_[ruby-list:49771] TkDND での日本語名の扱い で紹介されてる変換処理を入れてみた。ついでに、複数ファイルを渡した時に全部処理するようにしてみた。
_tkdnd_test2.rb
require 'tk' require "tkextlib/tkDND" require 'nkf' Tk::TkDND::DND label = TkLabel.new { text "Please File Drop" pack } txt = TkText.new(nil) { dnd_bindtarget('text/uri-list','<Drop>', "%D") { |d| d.each { |s| # 日本語ファイル名を渡した時におかしくなるので変換処理をする u8str = s.encode("iso-8859-1","utf-8").encode("iso-8859-1","utf-8") u8str.encode!('cp932', 'utf-8') puts u8str insert('end',u8str) insert('end',"\n") } } pack } TkButton.new { text "Exit" command "exit" pack } Tk.mainloop
文字化けしてないように見える。
が。 _[ruby-list:50353] [再]Re: TkDND での日本語名の扱い によると、空白が入ったファイル名を渡したり、\が入ったファイル名を渡すとおかしくなるそうで。試してみたところ、たしかにエラーが表示された。このあたり、なかなか厳しいものがあるようで。
◎ TkDNDの導入方法。 :
Windows10 x64 + Ruby 2.2.5 p319 + Ruby/Tk の環境で、TkDND も含めたTk拡張(?)を使うには…。
とりあえず、ActiveTcl が必要。 _Download Tcl | ActiveState から入手してインストールする。たしか、自分の環境では、Windows x86(32bit版)、8.6.4.1 をインストールしたような。 セットアップファイルは、ActiveTcl8.6.4.1.299124-win32-ix86-threaded.exe、だった気がする。
次に、ActiveTcl に、TkDND をインストールする。tclsh と打つとプロンプトが「%」になるので、ActiveTcl についてきた teacup なるパッケージマネージャを使ってネット経由でインストール。
最後に、Ruby/Tk からTk拡張を使えるようにする。
このあたりは色々やり方があるらしいけど、自分の環境ではこの方法でやってたり。昔試した時は、この方法なら ocra を使ってRubyスクリプトをexe化する時も問題が出なかったはず。
_2016/10/03の日記 や、 _2015/12/10の日記 にもそのへんメモしてあった、とメモ。
とりあえず、ActiveTcl が必要。 _Download Tcl | ActiveState から入手してインストールする。たしか、自分の環境では、Windows x86(32bit版)、8.6.4.1 をインストールしたような。 セットアップファイルは、ActiveTcl8.6.4.1.299124-win32-ix86-threaded.exe、だった気がする。
次に、ActiveTcl に、TkDND をインストールする。tclsh と打つとプロンプトが「%」になるので、ActiveTcl についてきた teacup なるパッケージマネージャを使ってネット経由でインストール。
% teacup install tkdndインストールできたら、exit と打って抜ける。
最後に、Ruby/Tk からTk拡張を使えるようにする。
ActiveTclインストールフォルダ\lib\teapot\package\win32-ix86\lib\の中に入ってるファイルやフォルダを、
Ruby2.2インストールフォルダ\lib\tcltk\の中にごっそりコピー。
このあたりは色々やり方があるらしいけど、自分の環境ではこの方法でやってたり。昔試した時は、この方法なら ocra を使ってRubyスクリプトをexe化する時も問題が出なかったはず。
_2016/10/03の日記 や、 _2015/12/10の日記 にもそのへんメモしてあった、とメモ。
[ ツッコむ ]
#2 [python] PySideでマウスを動かしてお絵かき
Windows10 x64 + Python 2.7.11 + PySide 1.2.4 で、ウインドウ上でマウスを動かすと何かを描ける、てな処理を QGraphics* を使って試してみたり。
_drawing_pyside_4.py
_ball.png
これで一応できた、のかな。
Qtには、ビットマップデータ相当として使える QPixmap てのがあるわけだけど。その QPixmap に対しては、QPainter を使って何か描き込むことができるわけで。
しかし、その QPixmap を渡して生成した QGraphicsPixmapItem の見た目を更新する方法がどうにも分からず。
結局、生成時に作った QPixmap を更新するたびに、QGraphicsPixmapItem の setPixmap() で設定し直してみたら、見た目も更新されるようになったけど…。果たしてコレでいいのだろうか…?
もしかして、QGraphicsPixmapItem が持ってる QPixmap は、QGraphicsPixmapItem の生成時、あるいは setPixmap() を呼んだ時に渡された QPixmap の内容を丸々コピーして持ってたりするのだろうかと。仮にそうであれば、生成時に渡した QPixmap を後から更新したところで、見た目も即座に更新されるわけでは無い、てのも分かる気もする。が、実際はどういう仕組みになっているのやら。
それと、どうせ QGraphicsPixmapItem が QPixmap を持っているなら、その QPixmap に直接描き込んでしまえばいいのではないか、とも思ったのだけど。試してみたところ、Pythonスクリプトが強制終了してしまって。となると…。
よく分からないと言えば…。QGraphicsView を使うとスクロールバーがなんだか中途半端な長さで出てくるのだけど、コレって何をどうやって設定したり使用したりするのだろう…。今後の課題。
_drawing_pyside_4.py
_ball.png
""" PySideでウインドウに描画。 マウスを動かしてお絵かきできる。 QGraphics* を使う。 ヲドリテヒヅル PyQtでイメージビューワ http://melpystudio.blog82.fc2.com/blog-entry-138.html """ import sys from PySide.QtCore import * from PySide.QtGui import * width = 640 height = 480 brushPath = 'ball.png' class ImageViewScene(QGraphicsScene): """ メインビューと関連付けられる Scene """ def __init__(self, *argv, **keywords): super(ImageViewScene, self).__init__(*argv, **keywords) self.buttonFlag = False self.pixmap = QPixmap(width, height) self.pixmap.fill() self.brushImage = QPixmap(brushPath) # Scene に Item を追加 self.imgItem = QGraphicsPixmapItem(self.pixmap) self.addItem(self.imgItem) def mouseDoubleClickEvent(self, event): pass def mousePressEvent(self, event): """ マウスボタンが押された際の処理 """ if event.button() == Qt.LeftButton: self.buttonFlag = True self.drawing(event) elif event.button() == Qt.RightButton: self.pixmap.fill() self.imgItem.setPixmap(self.pixmap) def mouseMoveEvent(self, event): """ マウスカーソル移動中の処理 """ if self.buttonFlag: self.drawing(event) def mouseReleaseEvent(self, event): """ マウスボタンが離されたときの処理 """ if event.button() == Qt.LeftButton: self.buttonFlag = False def drawing(self, event): """ ブラシで描画 """ x = event.scenePos().x() y = event.scenePos().y() x -= self.brushImage.width() / 2 y -= self.brushImage.height() / 2 qp = QPainter() qp.begin(self.pixmap) qp.drawPixmap(x, y, self.brushImage) qp.end() del qp # 描画更新する方法が分からない… # 仕方なく、pixmap を再設定してるけど…これでいいの? self.imgItem.setPixmap(self.pixmap) # self.imgItem.update() # self.update() class ImageViewer(QGraphicsView): """ メインとなるビュー """ def __init__(self): super(ImageViewer, self).__init__() self.setCacheMode(QGraphicsView.CacheBackground) self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing ) scene = ImageViewScene(self) self.setScene(scene) scene.setSceneRect(QRectF(self.rect())) def resizeEvent(self, event): """ ビューをリサイズ時にシーンの矩形を更新 """ super(ImageViewer, self).resizeEvent(event) self.scene().setSceneRect(QRectF(self.rect())) if __name__ == '__main__': app = QApplication(sys.argv) viewer = ImageViewer() viewer.show() sys.exit(app.exec_())
これで一応できた、のかな。
Qtには、ビットマップデータ相当として使える QPixmap てのがあるわけだけど。その QPixmap に対しては、QPainter を使って何か描き込むことができるわけで。
しかし、その QPixmap を渡して生成した QGraphicsPixmapItem の見た目を更新する方法がどうにも分からず。
結局、生成時に作った QPixmap を更新するたびに、QGraphicsPixmapItem の setPixmap() で設定し直してみたら、見た目も更新されるようになったけど…。果たしてコレでいいのだろうか…?
もしかして、QGraphicsPixmapItem が持ってる QPixmap は、QGraphicsPixmapItem の生成時、あるいは setPixmap() を呼んだ時に渡された QPixmap の内容を丸々コピーして持ってたりするのだろうかと。仮にそうであれば、生成時に渡した QPixmap を後から更新したところで、見た目も即座に更新されるわけでは無い、てのも分かる気もする。が、実際はどういう仕組みになっているのやら。
それと、どうせ QGraphicsPixmapItem が QPixmap を持っているなら、その QPixmap に直接描き込んでしまえばいいのではないか、とも思ったのだけど。試してみたところ、Pythonスクリプトが強制終了してしまって。となると…。
- QGraphicsPixmapItem が持ってる QPixmap は、デスクトップ上の描画にせっせと使ったりしてる関係で、中身を変更しちゃダメだよ、読み出しはともかく書き込みはNGだよ、ということになっている、とか?
- あるいは、中身を変更したいならしかるべき手順を踏んでから更新しないとダメだよ、ということになっている、とか?
よく分からないと言えば…。QGraphicsView を使うとスクロールバーがなんだか中途半端な長さで出てくるのだけど、コレって何をどうやって設定したり使用したりするのだろう…。今後の課題。
[ ツッコむ ]
#3 [neta][anime] BS朝日とBSフジはいっそアニメを放送しないでくれないものか
BS朝日とBSフジは、どうしてアニメ番組の放送時間がガンガンずれるのか…。何かの嫌がらせですか。HDDレコーダの予約録画がグチャグチャだよ…。
多少ずれても問題を起こさない時間帯や曜日が他にあるのに、どうしてわざわざ、あの曜日・時間帯に…。都市圏の地上波放送と照らし合わせるとあそこの曜日・時間帯になっちゃう、みたいなことなんだろうか。
多少ずれても問題を起こさない時間帯や曜日が他にあるのに、どうしてわざわざ、あの曜日・時間帯に…。都市圏の地上波放送と照らし合わせるとあそこの曜日・時間帯になっちゃう、みたいなことなんだろうか。
[ ツッコむ ]
2016/10/14(金) [n年前の日記]
#1 [python] PySideのレイアウトについて勉強中
GUIアプリを作ろうとした際に、GUI部品(ウィジェット)を配置するやり方・考え方には、大別して2種類あって。
以下を参考にして、スクリプトの動作確認をしていたり。
_PySideメモ-レイアウト方法
- 部品を置く位置を座標で指定する。ドット単位で位置を決められるが、位置が固定されてるので、ウインドウサイズが変わった時に追従できない。
- 左から右、上から下等、部品を順々に追加すると勝手に並ぶように指定する。大雑把な位置になるが、ウインドウサイズが変わっても追従できる。
以下を参考にして、スクリプトの動作確認をしていたり。
_PySideメモ-レイアウト方法
[ ツッコむ ]
#2 [nitijyou] 自転車で買い物に
ダイソー、ホームセンターサンデー、ザ・ビッグに寄って、ストップウォッチ、保冷材、夜食等を購入。
◎ ダイソーのストップウォッチとは何故か相性が悪い。 :
ダイソーでストップウォッチを買ってみたのだけど、帰宅後、使おうとしてみたら何度ボタンを押してもピクリとも動かない。電池を交換したりアレをソレしたりしてみたけど変化無し。初期不良品に当たってしまった、のかな。
以前もこういうことあったな…。ダイソーでストップウォッチを買ったらやっぱり使えなくて…。どうも自分、ダイソーのストップウォッチとは相性が悪い…。2回連続で不良品を引き当てるとは…。
以前もこういうことあったな…。ダイソーでストップウォッチを買ったらやっぱり使えなくて…。どうも自分、ダイソーのストップウォッチとは相性が悪い…。2回連続で不良品を引き当てるとは…。
[ ツッコむ ]
#3 [anime] 「ルパン三世 カリオストロの城」を視聴
TV放送されてたので途中から見てみたり。やっぱり凄い。昔の宮崎駿監督は凄い。
それにしても…。前にも書いた記憶があるけど、子供の頃、街中に貼られてるカリ城のポスターを見て、「なんだこのパチモンのルパンは」と思ってしまったことが…。当時ルパンと言えば赤ジャケルパンしか知らなかったから、ジャケットが緑というだけで「これはニセモノに違いない」と思い込んでしまったという。おそらくスタッフの中では、一番最初にルパンを手掛けたのは俺達だ俺達が作るルパンが本物だ、てな自負もあっただろうし、緑ジャケは絶対外せないポイントだったのだろうけど。もし、ジャケットが赤かったら、それだけでも興行成績の類がもうちょっとマシに…。などと想像したりもするけど今更な話ではあるよなと。
今はもう、世間一般では、ルパンと言えばカリ城のルパンでしょう、みたいなイメージになってるところもあるような、ないような。
それにしても…。前にも書いた記憶があるけど、子供の頃、街中に貼られてるカリ城のポスターを見て、「なんだこのパチモンのルパンは」と思ってしまったことが…。当時ルパンと言えば赤ジャケルパンしか知らなかったから、ジャケットが緑というだけで「これはニセモノに違いない」と思い込んでしまったという。おそらくスタッフの中では、一番最初にルパンを手掛けたのは俺達だ俺達が作るルパンが本物だ、てな自負もあっただろうし、緑ジャケは絶対外せないポイントだったのだろうけど。もし、ジャケットが赤かったら、それだけでも興行成績の類がもうちょっとマシに…。などと想像したりもするけど今更な話ではあるよなと。
今はもう、世間一般では、ルパンと言えばカリ城のルパンでしょう、みたいなイメージになってるところもあるような、ないような。
[ ツッコむ ]
2016/10/15(土) [n年前の日記]
#1 [python] PySideのQMainWindow内のレイアウトについて悩んだり
QWidget 内で QHBoxLayout や QVBoxLayout を使ってレイアウトするところまでは動作確認できたのだけど。QMainWindow 内で、同じノリでレイアウトできないことに気が付いて悩んだり。
ググってみたら、以下のサンプルを見かけた。
_python - PySide (Qt) - Layout not working - Stack Overflow
どうやら QMainWindow は、事前にウインドウ内がいくつかの領域に分けられてるようで。上、下、左、右、真ん中、みたいな。で、一旦 QWidget を作ってその中に各ウィジェットをレイアウトしてやって、その QWidget を QMainWindow の真ん中に配置(setCentralWidget()を使って設定)、みたいなことをすれば配置できなくもない、ようだなと。
ググってみたら、以下のサンプルを見かけた。
_python - PySide (Qt) - Layout not working - Stack Overflow
どうやら QMainWindow は、事前にウインドウ内がいくつかの領域に分けられてるようで。上、下、左、右、真ん中、みたいな。で、一旦 QWidget を作ってその中に各ウィジェットをレイアウトしてやって、その QWidget を QMainWindow の真ん中に配置(setCentralWidget()を使って設定)、みたいなことをすれば配置できなくもない、ようだなと。
[ ツッコむ ]
#2 [nitijyou] 自転車でダイソーまで
昨日購入したストップウォッチが不良品だったので、犬の散歩のついでにダイソーによって交換してもらってきた。
店頭に並んでる品が全部不良品だったら面白いことになりそうだなと少し期待しながら店員さんの振舞いを見守ったけど、ちゃんと動作するモノも陳列されていたようで。やっぱり自分はダイソーのストップウォッチと相性が悪い。どうして2回も、初期不良品を引き当てるのか…。
店頭に並んでる品が全部不良品だったら面白いことになりそうだなと少し期待しながら店員さんの振舞いを見守ったけど、ちゃんと動作するモノも陳列されていたようで。やっぱり自分はダイソーのストップウォッチと相性が悪い。どうして2回も、初期不良品を引き当てるのか…。
[ ツッコむ ]
2016/10/16(日) [n年前の日記]
#1 [python] PySideのQMainWindow上に色々配置する例
こんな感じかな…。
_mainwdwlayout.py
QMainWindowは、上、下、左、右に、ドックウィジェット(QDockWidget)なるものを配置することができるらしいので、そのあたりにRGB値を設定するアレコレを置いてみたり。
QDockWidget は、タイトルバーをドラッグすればメインウインドウから切り離したり、またくっつけたり、左じゃなくて右に再配置したりできる。しかし、デフォルト設定では閉じることも可能で…。閉じてしまうと、再復活させる方法が…。なので、今回は設定を変えて閉じるボタンを無効にしてみたり。
QDockWidget を一度メインウインドウから切り離して(フロート状態にして)、またメインウインドウに戻そうとしても戻ってくれなくて悩んだけれど。どうやらメインウインドウのサイズより、ドックウィジェットのほうがサイズが大きいとくっついてくれないようで。メインウインドウのサイズを大きくしてからドラッグしたらくっついてくれた。気づくまで時間がかかった…。
_mainwdwlayout.py
""" PySideを使ってQMainWindow上にレイアウトする事例 """ import sys from PySide.QtCore import * from PySide.QtGui import * color_info = None class MyColorInfo(QPushButton): """ 色を表示するウィジェット """ def __init__(self, parent=None): super(MyColorInfo, self).__init__(parent) self.color = QColor(128, 128, 128) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setMinimumSize(48, 48) def paintEvent(self, e): qp = QPainter() qp.begin(self) qp.setPen(QColor(0, 0, 0)) qp.setBrush(self.color) qp.drawRect(2, 2, 44, 44) qp.end() def updateColor(self, r, g, b): """ 色を更新 """ self.color.setRgb(r, g, b) self.update() class MySlider(QWidget): """ RGB値指定スライダー部分 """ def __init__(self, parent=None): super(MySlider, self).__init__(parent) gb = QGridLayout() # 升目上に並べる gb.setContentsMargins(0, 0, 0, 0) # 外のマージン(隙間)を極力無くす # 色表示部分 global color_info color_info = MyColorInfo(self) gb.addWidget(color_info, 0, 0, 1, 3) # スライダーやスピンボックス部分 self.value = [] self.sld = [] self.spb = [] # RGBの3つ分、Slider や SpinBox を確保 for (i, s) in enumerate(["R", "G", "B"]): lbl = QLabel(s) sld = QSlider(Qt.Orientation.Horizontal, self) spb = QSpinBox() # レイアウト gb.addWidget(lbl, i + 1, 0) gb.addWidget(sld, i + 1, 1) gb.addWidget(spb, i + 1, 2) # 値の範囲を 0-255 に設定 sld.setRange(0, 255) spb.setRange(0, 255) # 現在値を初期化 v = 128 sld.setValue(v) spb.setValue(v) # 後で使うので記録しておく self.value.append(v) self.sld.append(sld) self.spb.append(spb) # 自身のレイアウトとして登録 self.setLayout(gb) # Slider や SpinBox 値が変えられた時に呼ばれるメソッドを設定 for i in range(3): self.sld[i].valueChanged[int].connect(self.sliderChangeValue) self.spb[i].valueChanged[int].connect(self.spinBoxChangeValue) def sliderChangeValue(self, value): """ Slider の値が変わった時に呼ばれる処理 """ for (i, sld) in enumerate(self.sld): self.spb[i].setValue(sld.value()) self.updateColor() def spinBoxChangeValue(self, value): """ SpinBox の値が変わった時に呼ばれる処理 """ for (i, spb) in enumerate(self.spb): self.sld[i].setValue(spb.value()) self.updateColor() def updateColor(self): """ 色表示部分を更新 """ v = [] for spb in self.spb: v.append(spb.value()) global color_info color_info.updateColor(v[0], v[1], v[2]) class MyBrushWidget(QWidget): """ メインウインドウ左側に配置するウィジェット """ def __init__(self, parent=None): super(MyBrushWidget, self).__init__(parent) layout = QVBoxLayout() # 縦に並べる # ブラシ画像選択部分 self.cb = QComboBox() self.cb.addItem("default.png") self.cb.addItem("extra.png") layout.addWidget(self.cb) # ブラシ画像表示部分 self.scene_brush = QGraphicsScene() self.gview_brush = QGraphicsView(self.scene_brush, self) self.gview_brush.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.gview_brush.setMinimumSize(256, 256) layout.addWidget(self.gview_brush) # 色選択部分 self.rgb_area = MySlider(self) layout.addWidget(self.rgb_area) # スペーシング spc = QSpacerItem(16, 16, QSizePolicy.Expanding, QSizePolicy.Expanding) layout.addSpacerItem(spc) # 自身のレイアウトとして設定 self.setLayout(layout) class MyMainWindow(QMainWindow): """ メインウインドウ """ def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) # メニューバー mb = QMenuBar() file_menu = QMenu("&File", self) exit_action = file_menu.addAction("&Close") exit_action.setShortcut('Ctrl+Q') exit_action.triggered.connect(qApp.quit) mb.addMenu(file_menu) self.setMenuBar(mb) # ステータスバー self.status = QStatusBar(self) self.status.showMessage("Status Bar") self.setStatusBar(self.status) # 左側のドックウィジェット self.leftDock = QDockWidget("Left Dock Widget", self) self.brushw = MyBrushWidget(self) self.leftDock.setWidget(self.brushw) # 移動とフローティングは有効にするが閉じるボタンは無効にする # 注意: # メインウインドウが十分大きくないと、フローティング後、元に戻せない self.leftDock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.leftDock.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable \ # | QDockWidget.DockWidgetVerticalTitleBar ) self.addDockWidget(Qt.LeftDockWidgetArea, self.leftDock) # 中央ウィジェット self.scene_image = QGraphicsScene() self.gview_image = QGraphicsView(self.scene_image, self) self.setCentralWidget(self.gview_image) def main(): app = QApplication(sys.argv) # app.setStyle(QStyleFactory.create('Cleanlooks')) w = MyMainWindow() w.setWindowTitle("PySide Layout on QMainWindow") w.resize(640, 480) w.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
QMainWindowは、上、下、左、右に、ドックウィジェット(QDockWidget)なるものを配置することができるらしいので、そのあたりにRGB値を設定するアレコレを置いてみたり。
QDockWidget は、タイトルバーをドラッグすればメインウインドウから切り離したり、またくっつけたり、左じゃなくて右に再配置したりできる。しかし、デフォルト設定では閉じることも可能で…。閉じてしまうと、再復活させる方法が…。なので、今回は設定を変えて閉じるボタンを無効にしてみたり。
QDockWidget を一度メインウインドウから切り離して(フロート状態にして)、またメインウインドウに戻そうとしても戻ってくれなくて悩んだけれど。どうやらメインウインドウのサイズより、ドックウィジェットのほうがサイズが大きいとくっついてくれないようで。メインウインドウのサイズを大きくしてからドラッグしたらくっついてくれた。気づくまで時間がかかった…。
◎ 参考ページ。 :
[ ツッコむ ]
2016/10/17(月) [n年前の日記]
#1 [zatta] 何がどう山なのかが分からない
「不気味の谷」に対する「人形劇の山」、なる言葉をどこかで見かけたのだけど。何がどう山なのか、分からない…。
_不気味の谷現象 - Wikipedia
グラフにしてみると落ち込むところが出現するから「谷」なんだけど…。その「人形劇の山」の「山」って、どこらへんが山に見えるという話なのか。モヤモヤする…。どういうグラフを想定してるのか…。そもそもグラフを想定していないのか…。
どうも「不気味の谷」がどういう現象なのか分かってない人が単に言葉のイメージだけで造語を、てな状況だったりしないかと邪推してしまったり。「なるほど、この形はたしかに山ですね」と納得してみたい…。
それはともかく。人形劇に見えるソレは何故か視聴者側の許容度が広くなる、という現象はたしかにありそうな気もするのだけど。カリ城の作画面と共通するところがあるような気もして。カリ城の映像は今のアニメ映像と比べると全然話にならないぐらいに線が少ない。影がついてるわけでもなく、服の皺を細かく描いてるわけでもないのに、魅力的な映像に見えてくるのは何故か。みたいな。
と思ったけど、ソレたぶん違うな…。カリ城の場合は動きによるところが大きいような。人形劇は動きどうこうじゃないんだよな…。人形劇は、一体どの部分で、何を許されてしまうのか…。分からん…。
関係ないけど、「不気味の谷」でググってたら気になる記事が。
_ソフトとハードの交差点:『不気味の谷』についての批判と提案 - livedoor Blog(ブログ)
_不気味の谷現象 - Wikipedia
グラフにしてみると落ち込むところが出現するから「谷」なんだけど…。その「人形劇の山」の「山」って、どこらへんが山に見えるという話なのか。モヤモヤする…。どういうグラフを想定してるのか…。そもそもグラフを想定していないのか…。
どうも「不気味の谷」がどういう現象なのか分かってない人が単に言葉のイメージだけで造語を、てな状況だったりしないかと邪推してしまったり。「なるほど、この形はたしかに山ですね」と納得してみたい…。
それはともかく。人形劇に見えるソレは何故か視聴者側の許容度が広くなる、という現象はたしかにありそうな気もするのだけど。カリ城の作画面と共通するところがあるような気もして。カリ城の映像は今のアニメ映像と比べると全然話にならないぐらいに線が少ない。影がついてるわけでもなく、服の皺を細かく描いてるわけでもないのに、魅力的な映像に見えてくるのは何故か。みたいな。
と思ったけど、ソレたぶん違うな…。カリ城の場合は動きによるところが大きいような。人形劇は動きどうこうじゃないんだよな…。人形劇は、一体どの部分で、何を許されてしまうのか…。分からん…。
関係ないけど、「不気味の谷」でググってたら気になる記事が。
_ソフトとハードの交差点:『不気味の谷』についての批判と提案 - livedoor Blog(ブログ)
[ ツッコむ ]
2016/10/18(火) [n年前の日記]
#1 [python] Atomエディタ、落ちまくり
Visual Studio Code より、Atomエディタのほうが、Pythonスクリプトの補完をガンガンしてくれることに気が付いて、今現在 Atom 1.11.2 でPythonスクリプトのソースを書いてるのだけど。
Atomエディタ、落ちるな…。ガンガン落ちる…。何かの拍子にフッと落ちる。何が原因なのやら。
Windowsのイベントビューアで確認したけど、ログが残ってるようには見えなかった。
Atomエディタ、落ちるな…。ガンガン落ちる…。何かの拍子にフッと落ちる。何が原因なのやら。
Windowsのイベントビューアで確認したけど、ログが残ってるようには見えなかった。
[ ツッコむ ]
2016/10/19(水) [n年前の日記]
#1 [python] Python + PySideでお絵かきウインドウを作成
Python + PySide + Pillow(PIL) を使って、お絵かきウインドウモドキを作成。動作確認環境は、Windows10 x64 + Python 2.7.11 + PySide 1.2.4 + Pillow 3.4.2。
今のところこんな感じに。左側でブラシを選んで、右側でマウスをカチカチすれば描ける。
ソースが長くなってきたので、ちょっとココに貼りづらいな…。とりあえず、ファイルだけ置いておこう…。
_drawing_pyside_5.py
スクリプトと同じフォルダに、brushes というフォルダを作って、中に、 _default.png と _extra.png を置いておくと、ブラシ画像を読み込んでくれる。
ひとまず、ここまでできれば、Python + PySide (あるいは PyQt)を使ってお絵かきソフトやドットエディタの類を作れそうではあるなと。
スクリプトソースとブラシ画像は CC0 / Public Domain ってことで。
今のところこんな感じに。左側でブラシを選んで、右側でマウスをカチカチすれば描ける。
ソースが長くなってきたので、ちょっとココに貼りづらいな…。とりあえず、ファイルだけ置いておこう…。
_drawing_pyside_5.py
スクリプトと同じフォルダに、brushes というフォルダを作って、中に、 _default.png と _extra.png を置いておくと、ブラシ画像を読み込んでくれる。
C:. | drawing_pyside_5.py | \---brushes default.png extra.png
ひとまず、ここまでできれば、Python + PySide (あるいは PyQt)を使ってお絵かきソフトやドットエディタの類を作れそうではあるなと。
スクリプトソースとブラシ画像は CC0 / Public Domain ってことで。
◎ ライセンス問題についてメモ。 :
上記のソレは、スクリプトソースと画像を公開してるだけなので、ライセンスは自由に決められるだろうと思っているのだけど。これがもし、バイナリ化(exe化)して配布するという話になると、ライセンスがちと面倒臭くなる予感。
仮に、 _PyQt を使って実装した場合は、同梱するPyQtのライセンスがGPLと商用ライセンスしか許されてないので、個人が趣味で作るソレはGPLにせざるを得ない。GPLが嫌いな人、GPL汚染を嫌がる人達は、ちと手を出しにくい。
ただ、 _PySide を使えば、 PySide はLGPLで使えるので、自分で書いた部分についてはGPL以外のライセンスにもできるんじゃないかと。たぶん。
しかし、PySide は Qt4 までの対応で Qt5 に対応してなくて。PyQt は Qt5 にも対応してるらしい。「ワシは Qt5 を Python から使いたいんじゃ」という人は、PyQt を選択するしか無いんだろうなと。
仮に、 _PyQt を使って実装した場合は、同梱するPyQtのライセンスがGPLと商用ライセンスしか許されてないので、個人が趣味で作るソレはGPLにせざるを得ない。GPLが嫌いな人、GPL汚染を嫌がる人達は、ちと手を出しにくい。
ただ、 _PySide を使えば、 PySide はLGPLで使えるので、自分で書いた部分についてはGPL以外のライセンスにもできるんじゃないかと。たぶん。
しかし、PySide は Qt4 までの対応で Qt5 に対応してなくて。PyQt は Qt5 にも対応してるらしい。「ワシは Qt5 を Python から使いたいんじゃ」という人は、PyQt を選択するしか無いんだろうなと。
◎ PySide のインストール方法。 :
ネットに繋がってるWindows環境で、Python がインストール済みなら、DOS窓を開いて以下を打てば PySide がインストールできる。
既に PySide がインストールされていて、アップデートしたい場合は、以下。
アンインストールしたい場合は、以下。
しかし、Pillow (画像処理ライブラリ) のインストールは、pip を使ってネット経由でやるとエラーが出ちゃったので…。 _Python Extension Packages for Windows - Christoph Gohlke から、自分の環境にあった .whl を一旦ローカルにダウンロードして、以下のように指定してインストールしてやったらエラーが出なかった、とメモ。
上記のサイトでは PySide の whlファイルも公開されてるけど、バージョンが 1.2.2 なのでちょっと古いみたい。PySide の現行版は 1.2.4 なので。
pip install pyside
既に PySide がインストールされていて、アップデートしたい場合は、以下。
pip install -U pyside
アンインストールしたい場合は、以下。
pip uninstall pyside
しかし、Pillow (画像処理ライブラリ) のインストールは、pip を使ってネット経由でやるとエラーが出ちゃったので…。 _Python Extension Packages for Windows - Christoph Gohlke から、自分の環境にあった .whl を一旦ローカルにダウンロードして、以下のように指定してインストールしてやったらエラーが出なかった、とメモ。
pip install Pillow-3.4.2-cp27-cp27m-win32.whlちなみに上記の例では、cp27 = Python2.7用、win32 = 32bit版、というファイル名のルールになってる。
上記のサイトでは PySide の whlファイルも公開されてるけど、バージョンが 1.2.2 なのでちょっと古いみたい。PySide の現行版は 1.2.4 なので。
◎ 色を反映させる処理で悩んでたり。 :
ブラシ画像がグレースケール画像の場合は、色を簡単に反映させられることが分かったのだけど。処理としては、元画像の明度をアルファチャンネルとして使って、RGB値は選択色をそのまま使えばいいわけで。
ただ、RGBAフルカラー画像のブラシ画像に、色を反映させる処理で悩んでたり。元画像のRGB値が128の時に、現在の色がそのまま出るように、と考えて、今のところ2つの方法を試してるけど…。
ガンマ補正っぽい処理をしたほうがいいのか、それとも、RGBではなくて _HLS(色相、輝度、彩度) にして計算するべきか…。何にせよ今の処理では、結果が望んでるものとはビミョーに違う感じが。
ただ、RGBAフルカラー画像のブラシ画像に、色を反映させる処理で悩んでたり。元画像のRGB値が128の時に、現在の色がそのまま出るように、と考えて、今のところ2つの方法を試してるけど…。
ガンマ補正っぽい処理をしたほうがいいのか、それとも、RGBではなくて _HLS(色相、輝度、彩度) にして計算するべきか…。何にせよ今の処理では、結果が望んでるものとはビミョーに違う感じが。
[ ツッコむ ]
#2 [cg_tools] JTrimはアルファチャンネルを扱えなかったのか
Inkscape でエクスポートしたpng画像をJTrimで読み込んでみたらなんだか妙な表示に。
ググってみたら…。
_JTrimは予めアルファチャンネルの設定された透過画像はきちんと読み込めないらしい(「透過色設定」はできるが) | さまようけんばん
なるほど。JTrim はアルファチャンネルを持った画像を開けないのか。起動が早くて便利そうと思ってたけど、ちと残念。
ググってみたら…。
_JTrimは予めアルファチャンネルの設定された透過画像はきちんと読み込めないらしい(「透過色設定」はできるが) | さまようけんばん
なるほど。JTrim はアルファチャンネルを持った画像を開けないのか。起動が早くて便利そうと思ってたけど、ちと残念。
[ ツッコむ ]
#3 [prog] マルチカーソルって便利そう
Windows10上で、Atomエディタを使ってPythonスクリプトを書いてるのだけど。マルチカーソルなる機能がなんだか便利そうだなと。
文字列を選択すると「他にもこのあたりに同じ文字列があるよ」と点線で枠が表示されるので、Ctrl+D を押していくとどんどん選択されてマルチカーソルモードに入る。その状態で編集すると、複数の場所を一気に編集できる。ESCキーを押すとマルチカーソルモードから抜ける。
Ctrl+マウス操作でもマルチカーソルモードになるらしい。
文字列を選択すると「他にもこのあたりに同じ文字列があるよ」と点線で枠が表示されるので、Ctrl+D を押していくとどんどん選択されてマルチカーソルモードに入る。その状態で編集すると、複数の場所を一気に編集できる。ESCキーを押すとマルチカーソルモードから抜ける。
Ctrl+マウス操作でもマルチカーソルモードになるらしい。
[ ツッコむ ]
2016/10/20(木) [n年前の日記]
#1 [python] PySideのWidgetに入ったり出たりする時のイベント
enterEvent() や leaveEvent() を書けば、Widget内にマウスカーソルが入ったり出たりした時に処理ができるらしい。
_enterevent_test1.py
たしかに処理されてる。ように見える。
アレ? このスクリーンショットだと反映されてるように見えないな…。ちょっと変なタイミングでキャプチャしてしまったようで。まあいいや。こういう感じの画面が出るスクリプトだよ、ぐらいは伝わるだろう…。
_enterevent_test1.py
""" PySideのWidget内にマウスカーソルが出たり入ったりした時のイベント動作を確認 Windows10 x64 + Python 2.7.11 + PySide """ import sys from PySide.QtCore import * from PySide.QtGui import * class MyLabel(QLabel): def __init__(self, *argv, **keywords): super(MyLabel, self).__init__(*argv, **keywords) self.setFrameStyle(QFrame.Box | QFrame.Raised) self.setFixedSize(240, 64) self.enterCount = 0 self.leaveCount = 0 def enterEvent(self, event): self.enterCount += 1 self.setText("enterEvent %d" % self.enterCount) def leaveEvent(self, event): self.leaveCount += 1 self.setText("leaveEvent %d" % self.leaveCount) class MyWidget(QWidget): def __init__(self, *argv, **keywords): super(MyWidget, self).__init__(*argv, **keywords) layout = QVBoxLayout(self) layout.addWidget(MyLabel("Please move mouse cursor")) layout.addWidget(MyLabel("Please move mouse cursor")) layout.addWidget(MyLabel("Please move mouse cursor")) self.setLayout(layout) def main(): app = QApplication(sys.argv) w = MyWidget() w.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
たしかに処理されてる。ように見える。
アレ? このスクリーンショットだと反映されてるように見えないな…。ちょっと変なタイミングでキャプチャしてしまったようで。まあいいや。こういう感じの画面が出るスクリプトだよ、ぐらいは伝わるだろう…。
[ ツッコむ ]
#2 [cg_tools] PhotoFiltreを試用
JTrimが、アルファチャンネルを持った画像を開けないことに気が付いて、ちょっとガックリ来たわけで。圧倒的に起動が早いのに、惜しい…。
似たようなことができるツールは無いのかなとググっていたら、PhotoFiltre というフリーソフトがあることに気が付いて。PhotoFiltre Studio という有償版の機能削減版、という位置づけらしいけど。
_PhotoFiltre 7 - k本的に無料ソフト・フリーソフト
_Photofiltreダウンロード&日本語化(ver7.x以降)
試しにインストールして試用してみたところ、JTrim ほどではないけれど起動は比較的早くて、かつ、トリミングその他も似たような感じでできたので、しばらくはコレを使ってみようかなと。
似たようなことができるツールは無いのかなとググっていたら、PhotoFiltre というフリーソフトがあることに気が付いて。PhotoFiltre Studio という有償版の機能削減版、という位置づけらしいけど。
_PhotoFiltre 7 - k本的に無料ソフト・フリーソフト
_Photofiltreダウンロード&日本語化(ver7.x以降)
試しにインストールして試用してみたところ、JTrim ほどではないけれど起動は比較的早くて、かつ、トリミングその他も似たような感じでできたので、しばらくはコレを使ってみようかなと。
◎ PixBuilder Studioでもトリミングはできた。 :
_PixBuilder Studio
ではトリミング作業がちょっとアレだな、矩形の選択範囲を作ってもサイズを後から調整できないし、と思っていたのだけど。改めて確認してみたら、別途 Crop ツールが用意されてることに気が付いて。
Cropツールを使えば後からサイズ調整もできたじゃないか、何故見落としたのか…。自分の注意力の無さにガックリ。
Cropツールを使えば後からサイズ調整もできたじゃないか、何故見落としたのか…。自分の注意力の無さにガックリ。
◎ 2016/10/28追記。 :
やっぱり PixBuilder Studio は、ちょっと使いづらかった。Cropツールで縦横比を指定して矩形選択しても、何かの拍子に選択範囲がヒョコッと勝手に小さくなったり大きくなったりしてしまう。そこからサイズ調整してトリミングして画像を縮小しても、望みの画像サイズにならない…。何かしら計算誤差でもあるんだろうか。
[ ツッコむ ]
2016/10/21(金) [n年前の日記]
#1 [cg_tools] StylePixを試用
StylePix なる、Windows上で動作する画像編集ソフトがあることを知ったので試用してみたり。1.14.5.0 が Stable版(安定板)だけど、2.0.0.5 beta版もあるらしい。開発した Hornil社は、公式サイトを眺めた感じでは韓国にあるソフトウェア会社っぽい。
_Hornil - StylePix - Free Photo Editor and Image Editor
_Hornil - StylePix - Download Free Lightweight and Powerful Image Editor.
_高機能で軽量な画像編集ソフト「Hornil StylePix」
_クールなデザインで高機能な画像編集フリーソフト 『StylePix』 軽量軽快でミニチュア化など面白い | PCあれこれ探索
_無料で利用できるグラフィックソフト
そこそこ機能豊富なのに、起動が比較的早くて、なんだかイイ感じ。言語設定で Japanese を選べばメニュー等も日本語化される。
しかし、メニューの日本語があちこち怪しい…。「出口」って何だ? ああ、「Exit」か…。「○○の地域」は…「region」かな。regionって日本語ではどう書くべきなのか。「作物の選択」は…作物って何だろ…。ひょっとしてGoogle翻訳そのままだったりするのだろうか。なかなかイイ感じのソフトなのに、ちと惜しい。
_Hornil - StylePix - Free Photo Editor and Image Editor
_Hornil - StylePix - Download Free Lightweight and Powerful Image Editor.
_高機能で軽量な画像編集ソフト「Hornil StylePix」
_クールなデザインで高機能な画像編集フリーソフト 『StylePix』 軽量軽快でミニチュア化など面白い | PCあれこれ探索
_無料で利用できるグラフィックソフト
そこそこ機能豊富なのに、起動が比較的早くて、なんだかイイ感じ。言語設定で Japanese を選べばメニュー等も日本語化される。
しかし、メニューの日本語があちこち怪しい…。「出口」って何だ? ああ、「Exit」か…。「○○の地域」は…「region」かな。regionって日本語ではどう書くべきなのか。「作物の選択」は…作物って何だろ…。ひょっとしてGoogle翻訳そのままだったりするのだろうか。なかなかイイ感じのソフトなのに、ちと惜しい。
◎ 日本語メニューをキャプチャしてみた。 :
CGソフトの類ではメニューの各単語をどのように翻訳すべきなのか、なんだか疑問が湧いてきた。試しに、画面をキャプチャして、一つ一つ自分なりに検討してみたり。
こういう感じに修正すれば、まだ伝わるだろうか…。どうなんだろ。
「整列」「配置」のあたりはどう書くべきか悩んでしまうなと。そのあたり、以前自分もソレ系のツールを作った時に項目名で悩んだ記憶が。
こういう感じに修正すれば、まだ伝わるだろうか…。どうなんだろ。
「整列」「配置」のあたりはどう書くべきか悩んでしまうなと。そのあたり、以前自分もソレ系のツールを作った時に項目名で悩んだ記憶が。
◎ 言語ファイルが別途存在することに気が付いた。 :
キャプチャ画像をせっせと撮ってアレコレ作業した後で気が付いたけど。Languageフォルダの中に Japanese.txt というファイルがあって、どうやらコレが言語ファイルだった模様。キャプチャ画像を作る意味は無かった…。Japanese.txt を勝手に書き換えれば済む話だった…。
テキスト形式でずらずらと記述してあるので、各自勝手に修正すれば怪しい日本語を減らせそう。エンコードは、xyzzy で開いたところ UTF-16LE BOM付き、と表示されてる。
テキスト形式でずらずらと記述してあるので、各自勝手に修正すれば怪しい日本語を減らせそう。エンコードは、xyzzy で開いたところ UTF-16LE BOM付き、と表示されてる。
[ ツッコむ ]
#2 [cg_tools] PictBearやAzPainter2を試用
起動が早い画像編集ソフトを探して、
_PictBear
と
_AzPainter2
を試用。どちらも開発終了してしまったソフトだけど、その分軽いはず。
PictBear は一瞬で起動して驚いた。しかし、選択範囲のサイズを後から調整することができない。トリミングをするのも一苦労。
AzPainter2 も圧倒的に起動が早く。かつ、選択範囲のサイズを後から調整することも可能なので、これならトリミング作業もフツーにできそうだなと。
ちょっとした作業なら、あえて昔の、動作が軽いソフトを使う、てのも全然アリだなと思えてきたり。
PictBear は一瞬で起動して驚いた。しかし、選択範囲のサイズを後から調整することができない。トリミングをするのも一苦労。
AzPainter2 も圧倒的に起動が早く。かつ、選択範囲のサイズを後から調整することも可能なので、これならトリミング作業もフツーにできそうだなと。
ちょっとした作業なら、あえて昔の、動作が軽いソフトを使う、てのも全然アリだなと思えてきたり。
[ ツッコむ ]
#3 [prog] GIMPの「着色」ってどんな処理をしてるのだろう
GIMPの、色 → 着色、ってどんな処理をしているのか気になって、GIMPのソースをDLして眺めていたり。しかし、分からん…。
以下のような処理をしてるのかなと想像するのだけど、どうなんだろう。
以下のような処理をしてるのかなと想像するのだけど、どうなんだろう。
- 元画像のRGB値から輝度を算出。
- 着色ダイアログで指定された、色相、彩度、輝度、のうち、輝度を元画像から求めた輝度にも反映。
- HLS(色相、輝度、彩度)からRGBに変換。
◎ RGBからグレースケールに変換。 :
RGBからグレースケールへの変換は、GIMPの場合は3種類の式があって。以下のページが分かりやすいような気がするのでメモ。
_Converting color to grayscale
_More on colors and grayscale
_明るさとコントラストの調整 < 色の調整 < 知っておきたい機能 | GIMP入門(2.8版)
もっとも、今回は輝度を求めたいのだから、0.21 * R + 0.72 * G + 0.07 * B の式でいいのだろうけど。
ただ、ググってみたら掛ける値は色々あるようで。
_osakana.factory - HSB 値と輝度の求め方 によると、0.298912 * R + 0.586611 * G + 0.114478 * B となっていた。また、 _画像のモノクロ化は輝度で変換しないとヒドイことになる - 知らなきゃ絶対損するPCマル秘ワザ では、0.299 * R + 0.587 * G + 0.114 * B となってた。掛ける値を足せば 1.0 になるのは同じだけど、それぞれ違う値だな…。
_YUV - Wikipedia によると、GIMPのソレは ITU-R BT.709 で、他は ITU-R BT.601、ということだったらしい。
_色空間の変換 (4) によると、
_第36回:カラーマネジメント Rec.709は3種類ある? | PERCH長尾の知っ得!デザインビズ必読ポイント! | AREA JAPAN によると、BT.709 にもいくつか種類があるようで。
_Converting color to grayscale
_More on colors and grayscale
_明るさとコントラストの調整 < 色の調整 < 知っておきたい機能 | GIMP入門(2.8版)
もっとも、今回は輝度を求めたいのだから、0.21 * R + 0.72 * G + 0.07 * B の式でいいのだろうけど。
ただ、ググってみたら掛ける値は色々あるようで。
_osakana.factory - HSB 値と輝度の求め方 によると、0.298912 * R + 0.586611 * G + 0.114478 * B となっていた。また、 _画像のモノクロ化は輝度で変換しないとヒドイことになる - 知らなきゃ絶対損するPCマル秘ワザ では、0.299 * R + 0.587 * G + 0.114 * B となってた。掛ける値を足せば 1.0 になるのは同じだけど、それぞれ違う値だな…。
_YUV - Wikipedia によると、GIMPのソレは ITU-R BT.709 で、他は ITU-R BT.601、ということだったらしい。
_色空間の変換 (4) によると、
- BT.709 : HDTV(ハイビジョンテレビ)の規格。Y = 0.2126 * R + 0.7152 * G + 0.0722 * B
- BT.601 : SDTV(標準テレビ)の規格。Y = 0.299 * R + 0.587 * G + 0.114 * B
_第36回:カラーマネジメント Rec.709は3種類ある? | PERCH長尾の知っ得!デザインビズ必読ポイント! | AREA JAPAN によると、BT.709 にもいくつか種類があるようで。
[ ツッコむ ]
#4 [python] PySideでQMainWindowのレイアウト方法を再確認
PySide(PyQt)のQMainWindowは、レイアウトの仕方がちょっと違うのでメモ。
_dockwidgetlayout.py
上下左右にドックウィジェットを配置して、真ん中にメインとなるウィジェットを配置できる、のが QMainWindow のレイアウト、なのかなと。
ドックウィジェットは、タイトルバー?部分をマウスでドラッグしてやれば、切り離して任意の場所に置くことも可能。例えば以下のような配置にもできるので、その手のツールを作成する時は便利かもしれない。
_dockwidgetlayout.py
""" PySideでQMainWindow上にDockWidgetその他をレイアウト 動作確認環境 : Windows10 x64 + Python 2.7.11 + PySide 1.2.4 """ import sys from PySide.QtCore import * from PySide.QtGui import * class MyVWidget(QWidget): """ メインウインドウ周辺に配置するWidget。縦長タイプ """ def __init__(self, parent=None): super(MyVWidget, self).__init__(parent) l = QVBoxLayout() # 縦に並べる l.addWidget(QLabel("Dummy")) l.addWidget(QLabel("Dummy")) self.setLayout(l) class MyHWidget(QWidget): """ メインウインドウ周辺に配置するWidget。横長タイプ """ def __init__(self, parent=None): super(MyHWidget, self).__init__(parent) l = QHBoxLayout() # 横に並べる l.addWidget(QLabel("Dummy")) l.addWidget(QLabel("Dummy")) self.setLayout(l) class DrawAreaScene(QGraphicsScene): """ 描画ウインドウ用Scene """ def __init__(self, *argv, **keywords): super(DrawAreaScene, self).__init__(*argv, **keywords) self.buttonFlag = False self.pixmap = QPixmap(800, 600) self.pixmap.fill(QColor(0, 0, 0, 0)) # Scene に Item を追加 self.imgItem = QGraphicsPixmapItem(self.pixmap) self.addItem(self.imgItem) class DrawAreaView(QGraphicsView): """ メインになるQGraphicsView """ def __init__(self, *argv, **keywords): super(DrawAreaView, self).__init__(*argv, **keywords) self.setCacheMode(QGraphicsView.CacheBackground) self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing) self.setBackgroundBrush(Qt.darkGray) # 背景色を設定 # Sceneを登録 scene = DrawAreaScene(self) self.setScene(scene) scene.setSceneRect(QRectF(self.rect())) def resizeEvent(self, event): """ リサイズ時に呼ばれる処理 """ super(DrawAreaView, self).resizeEvent(event) self.scene().setSceneRect(QRectF(self.rect())) # Sceneの矩形も更新 class MyMainWindow(QMainWindow): """ メインウインドウ """ def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) # メニューバー mb = QMenuBar() file_menu = QMenu("&File", self) exit_action = file_menu.addAction("&Close") exit_action.setShortcut('Ctrl+Q') exit_action.triggered.connect(qApp.quit) mb.addMenu(file_menu) self.setMenuBar(mb) # ステータスバー status = QStatusBar(self) self.setStatusBar(status) status.showMessage("Status Bar") # 上のDockWidget self.topDock = QDockWidget("Top Dock", self) self.topDock.setWidget(MyHWidget(self)) self.addDockWidget(Qt.TopDockWidgetArea, self.topDock) # 下 self.bottomDock = QDockWidget("Bottom Dock", self) self.bottomDock.setWidget(MyHWidget(self)) self.addDockWidget(Qt.BottomDockWidgetArea, self.bottomDock) # 左 self.leftDock = QDockWidget("Left Dock", self) self.leftDock.setWidget(MyVWidget(self)) self.addDockWidget(Qt.LeftDockWidgetArea, self.leftDock) # 右 self.rightDock = QDockWidget("Right Dock", self) self.rightDock.setWidget(MyVWidget(self)) self.addDockWidget(Qt.RightDockWidgetArea, self.rightDock) # 中央Widget self.gview_image = DrawAreaView(self) self.setCentralWidget(self.gview_image) def main(): app = QApplication(sys.argv) w = MyMainWindow() w.setWindowTitle("DockWidget Layout") w.resize(800, 600) w.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
上下左右にドックウィジェットを配置して、真ん中にメインとなるウィジェットを配置できる、のが QMainWindow のレイアウト、なのかなと。
ドックウィジェットは、タイトルバー?部分をマウスでドラッグしてやれば、切り離して任意の場所に置くことも可能。例えば以下のような配置にもできるので、その手のツールを作成する時は便利かもしれない。
[ ツッコむ ]
2016/10/22(土) [n年前の日記]
#1 [cg_tools] StylePixの日本語化ファイルを修正していたり
Windows上で動作する軽量画像編集ソフト、
_Hornil StylePix
。日本語化できるものの、なんだか怪しい日本語ばかりなので、言語ファイルの修正作業を試してみたり。
言語ファイルは、StylePixインストールフォルダ\Language に入ってる。Japanese.txt が日本語化ファイル。別名コピーしてそちらを修正していけば、新しい言語ファイルが作れて、StylePix のオプションで選ぶことができる。
言語ファイルの文字エンコードは UTF-16LE +BOM。とりあえず xyzzy で開いて修正できることを確認。
英語化ファイル(English.txt)その他と比較してみたところ、どうも Japanese.txt はID種類が一部不足してるようで。比較用に、全ファイルを読んでIDをまとめてCSV出力するRubyスクリプトを書き始めたのだけど、UTF-16LEのファイルを読んで正規表現を適用する方法がよく分からなくて、ググってアレコレ試していたり。
言語ファイルは、StylePixインストールフォルダ\Language に入ってる。Japanese.txt が日本語化ファイル。別名コピーしてそちらを修正していけば、新しい言語ファイルが作れて、StylePix のオプションで選ぶことができる。
言語ファイルの文字エンコードは UTF-16LE +BOM。とりあえず xyzzy で開いて修正できることを確認。
英語化ファイル(English.txt)その他と比較してみたところ、どうも Japanese.txt はID種類が一部不足してるようで。比較用に、全ファイルを読んでIDをまとめてCSV出力するRubyスクリプトを書き始めたのだけど、UTF-16LEのファイルを読んで正規表現を適用する方法がよく分からなくて、ググってアレコレ試していたり。
[ ツッコむ ]
2016/10/23(日) [n年前の日記]
#1 [cg_tools] StylePixの日本語言語ファイルをそこそこ修正
少なくとも、メニュー項目の中に「出口」「作物」「地域」等の怪しい訳は無くなった…と思うので、一応置いておくのです。まだ怪しいところが残ってるけど、目立つところは直せたはず。
*1
_Jp_m256_20161023_txt.zip (StylePix 1.14.5.0 用)
Languageフォルダに入れて StylePix を起動すれば、オプションから言語を切り替えて使える。ファイル名が言語名として扱われるようで。
ちなみに、StylePix 2.0.0.5 の言語ファイルは、1.14.5.0 より微妙に項目数が増えていて、その増えた分が Japanese.txt に反映されてないように見えた。
_Jp_m256_20161023_txt.zip (StylePix 1.14.5.0 用)
Languageフォルダに入れて StylePix を起動すれば、オプションから言語を切り替えて使える。ファイル名が言語名として扱われるようで。
ちなみに、StylePix 2.0.0.5 の言語ファイルは、1.14.5.0 より微妙に項目数が増えていて、その増えた分が Japanese.txt に反映されてないように見えた。
◎ チェック作業に使ったRubyスクリプト。 :
StylePix の言語ファイルを読み込んで、CSVファイルとして出力するRubyスクリプトを書いた。出力された CSV を、Excel や LibreOffice Calc 等で開けば視認性が良くなるので、抜けがないかチェックしやすくなる。というか抜けてるところだけリストアップするスクリプトにしたほうがいいのかもしれないけど。
動作確認環境は、Windows10 x64 + Ruby 2.2.5 p319。
使い方は、Languageフォルダの中に id_dump.rb を置いて、ruby id_dump.rb と打って実行。__tmp.csv が出力される。出力内容には、英語、日本語(オリジナル)、日本語(修正版)だけを並べている。
ちなみに、言語化ファイル群の中にはハングル文字で書かれたファイルがあるけど、そのままだとアクセスすらできないだろうから、そのファイルだけkorean.txt にリネームしてから作業した。
_id_dump.rb
Excel や LibreOffice Calc に渡す CSV は、UTF-16LE + BOM じゃないといかんらしいので、スクリプト内でやたらと encode("UTF-16LE") を呼んでいたり。
一応、出力されたCSVも置いてみたりして。
___tmp_csv.zip
動作確認環境は、Windows10 x64 + Ruby 2.2.5 p319。
使い方は、Languageフォルダの中に id_dump.rb を置いて、ruby id_dump.rb と打って実行。__tmp.csv が出力される。出力内容には、英語、日本語(オリジナル)、日本語(修正版)だけを並べている。
ちなみに、言語化ファイル群の中にはハングル文字で書かれたファイルがあるけど、そのままだとアクセスすらできないだろうから、そのファイルだけkorean.txt にリネームしてから作業した。
_id_dump.rb
# StylePix Language file check. # output __tmp.csv (UTF-16LE + BOM) output_file = "__tmp.csv" # StylePix Language files filelist = [ 'English.txt', 'Japanese.txt', 'Jp_m256_20161023.txt', 'Arabic.txt', 'ChineseSimplified.txt', 'ChineseTraditional.txt', 'French.txt', 'German.txt', 'Italian.txt', 'Welsh.txt', 'korean.txt', # please rename ] # pickup language files pickuplist = [ 'English.txt', 'Japanese.txt', 'Jp_m256_20161023.txt', ] # UTF-16LE string re_comment = Regexp.new( '^\/\/'.to_s.encode( "UTF-16LE" )) re_blankline = Regexp.new( '^\s+$'.to_s.encode( "UTF-16LE" )) re_word_tab_word = Regexp.new( '^(\S+)\s+\"(.+)\"$'.to_s.encode( "UTF-16LE" )) re_start_quot = Regexp.new( '^"'.to_s.encode( "UTF-16LE" )) re_end_quot = Regexp.new( '\"$'.to_s.encode( "UTF-16LE" )) nullstr = "".encode("UTF-16LE") sep = "\t".encode("UTF-16LE") # File read data = {} id_lst = {} filelist.each do |fn| dt = {} f = File.open(fn, 'rb:BOM|UTF-16LE') while l = f.gets l.chomp! next if l =~ re_comment # skip comment next if l =~ re_blankline # skip blank line if l =~ re_word_tab_word id, value = $1, $2 dt[id] = value if id_lst.has_key?(id) id_lst[id] += 1 else id_lst[id] = 1 end end end f.close data[fn] = dt end # make csv res = [] header = [] header.push("ID".encode("UTF-16LE")) pickuplist.each do |fn| header.push(fn.encode("UTF-16LE")) end res.push(header) id_lst.keys.each do |id| dt = [] dt.push(id) pickuplist.each do |fn| v = data[fn] dt.push((v.has_key?(id))? v[id] : nullstr) end res.push(dt) end # output csv (UTF-16LE + BOM) f = open(output_file, 'wb:UTF-16LE') f.write "\uFEFF" # BOM res.each do |l| f.puts l.join(sep) end f.close
Excel や LibreOffice Calc に渡す CSV は、UTF-16LE + BOM じゃないといかんらしいので、スクリプト内でやたらと encode("UTF-16LE") を呼んでいたり。
一応、出力されたCSVも置いてみたりして。
___tmp_csv.zip
◎ 余談。StylePixの動作がちょっと怪しい気がする。 :
StylePix起動時の動作が、なんだかちょっと怪しい感じがする。OS起動直後に起動する分には素早く起動してくれるけど、何度か StylePix の終了と起動を繰り返しているうちに、デスクトップ画面全体を巻き込んで、しばらく操作できない場面が出てくる…。一体何が起きてるんだろう…。ちなみに環境は Windows10 x64。
◎ 余談その2。StylePix 2.xの起動は遅い。 :
StylePix 1.x は起動が比較的早いけど、2.x はめっきり起動が遅い感じで。
ただ、起動と終了を何度も繰り返した状況で確認したので、インストールした直後なら起動が早かったりするのかもしれないけど、そこまで確認していない。
ただ、起動と終了を何度も繰り返した状況で確認したので、インストールした直後なら起動が早かったりするのかもしれないけど、そこまで確認していない。
◎ 2016/10/28追記。 :
最初は txt ファイルを置いていたのだけど、サーバにアップロードしてみたら途中で切れてた…。zipファイルにして置き直したり。
*1: 公式のソレに反映してもらえたらいいのだけど、自分、英語が全く分からんから交渉しようもなく。
[ ツッコむ ]
#2 [ruby] Ruby でUTF-16LEのテキストファイルにアクセス
せっかくテストしたのでメモ。動作確認環境は、Windows10 x64 + Ruby 2.2.5 p319。
テストに使った UTF-16LE のテキストは以下。
_text_utf16le_bom.txt
テストに使った UTF-16LE のテキストは以下。
_text_utf16le_bom.txt
◎ 読み込み。 :
まずは読み込んでみる。
_open_utf16le.rb
結果。
_open_utf16le.rb
# UTF-16LE + BOM のテキストファイルにアクセス infile = "text_utf16le_bom.txt" File.open(infile, 'rb:BOM|UTF-16LE') {|f| while l = f.gets l.chomp! puts l.encoding # => UTF-16LE end }
- File.open() に 'rb:BOM|UTF-16LE' を指定すれば UTF-16LE + BOM として開ける。
- さらに、gets で読み込めば、 string が UTF-16LE として扱われる。
- フツーは、ファイルを開いたら close で閉じないといけないが、File.open() にブロック({ } とか do end とか)をつけた場合は close を省略できる。
結果。
> open_utf16le.rb UTF-16LE UTF-16LE UTF-16LE UTF-16LE UTF-16LE UTF-16LE UTF-16LE UTF-16LE「文字列(String)のタイプは UTF-16LEだよ」と表示された。
◎ 正規表現。 :
UTF-16LE + BOM の文字列に対して正規表現を使う例。
_open_utf16le_regexp.rb
結果。
_open_utf16le_regexp.rb
# UTF-16LE + BOM の文字列に対して正規表現を使う infile = "text_utf16le_bom.txt" re0 = Regexp.new( '^\/\/'.to_s.encode("UTF-16LE") ) re1 = Regexp.new( '^(.+)\t(.+)$'.to_s.encode("UTF-16LE") ) f = File.open(infile, 'rb:BOM|UTF-16LE') while l = f.gets if l =~ re0 puts "comment" elsif l =~ re1 puts "data" end end f.closeソースコードの文字コード(この場合はUTF-8)、とは異なっている文字コードの文字列(UTF-16LE)に対して正規表現を使いたい場合、Regexp.new() を使う。いつもの調子で l =~ /^(.+)/ とか書いてしまうと UTF-16LE と UTF-8 が混在してるので「おいコラ、違う文字コードが混ざってるぞ」と怒られる
結果。
> open_utf16le_regexp.rb comment comment data data comment comment data dataUTF-16LEの文字列に対して正規表現を使って判別処理ができてる。
◎ 書き込み。 :
UTF-16LE + BOM でテキストファイルを出力してみる。
_output_utf16le.rb
_output_utf16le.rb
# UTF-16LE + BOM の文字列をテキストファイルとして出力 outfile = "_tmp.txt" File.open(outfile, 'wb:UTF-16LE') { |f| f.write "\uFEFF" # BOMを出力 DATA.each do |l| f.puts l.encode("UTF-16LE") end } __END__ ABCDEFG 0123456 日本語を記述
- f = open(outfile, 'wb:UTF-16LE') で、UTF-16LE で出力できる。
- f.write "\uFEFF" で、BOMを出力。
- DATA.each {|l| puts l } を使えば、__END__ 以降に書かれた文字列を1行ずつ読み込める。
◎ 参考ページ。 :
_ruby - Replacing string in UTF-16LE encoded file - Stack Overflow
_Excelですぐ開けるUnicodeなCSVをRubyで生成する | 秋山ブログ
_Rubyのエンコーディングその2 - @tmtms のメモ
_異なるエンコーディングでのファイル書き出しと読み込み - Qiita
_Rubyist Magazine - Ruby M17N の設計と実装
_constant Object::DATA (Ruby 2.3.0)
_RubyのDATAという特殊なグローバル定数 - yarbの日記
_たまに便利な、Rubyの組み込み定数 - Qiita
_Excelですぐ開けるUnicodeなCSVをRubyで生成する | 秋山ブログ
_Rubyのエンコーディングその2 - @tmtms のメモ
_異なるエンコーディングでのファイル書き出しと読み込み - Qiita
_Rubyist Magazine - Ruby M17N の設計と実装
_constant Object::DATA (Ruby 2.3.0)
_RubyのDATAという特殊なグローバル定数 - yarbの日記
_たまに便利な、Rubyの組み込み定数 - Qiita
[ ツッコむ ]
#3 [windows] やっぱりWindows10がスリープから復帰できない
NVIDIA GeForecドライバが何度か更新されたので、実は GTX 750 Ti のドライバも少しは中身が変わっているのではと期待してしまって。Windows10 をスリープさせて復帰させようと試してみたところ、やっぱりスリープ復帰に失敗してブルースクリーンに。DPC_WATCHDOG_VIOLATION と表示されてる…。
GTX 750 Ti は、スリープ関連については、もうダメかもしれん。省電力化を進めたことで不具合を起こすようになってしまったんだろう…。もっとも、Windows7時代の古いドライバなら一応スリープ復帰できていたので、ドライバ側で行える回避策があるのだろうけど…。
GTX 750 Ti は、スリープ関連については、もうダメかもしれん。省電力化を進めたことで不具合を起こすようになってしまったんだろう…。もっとも、Windows7時代の古いドライバなら一応スリープ復帰できていたので、ドライバ側で行える回避策があるのだろうけど…。
[ ツッコむ ]
#4 [anime] ウルトラマンオーブ、べリアルさんの回
怪獣を倒すためとは言え、
街をガンガン破壊するウルトラマン…。イイな…。
ビルを引き抜いて怪獣をタコ殴りしたり、
八つ裂き光輪で怪獣の尻尾を切断した上にその
尻尾を凶器代わりにしてタコ殴りしたり。ウルトラマンは正義のヒーロー、という思い込みがあるので、乱暴なソレは見ていてクラクラしてきて、なんだかイイ感じ。もっともこのへん進めていくと、平成ライダーのようなギスギスシリーズになって差別化が難しい気もするけど。たまにはこういうのもいいよなと。
まあ、劇場版その他ではべリアルさんがそういう役として活躍してる印象もあるのでアレですが。
まあ、劇場版その他ではべリアルさんがそういう役として活躍してる印象もあるのでアレですが。
[ ツッコむ ]
2016/10/24(月) [n年前の日記]
#1 [ruby] WindowsとRubyとRsenseのgem
Windows10上に Ruby 2.3 をインストールしたついでに、gem install rsense で、Rsense をインストールしてみたのだけど。
_rsense | RubyGems.org | your community gem host
_rsense/rsense: Rsense Can See All
Rsenseというのは、エディタ上でRubyのアレコレを補完してくれるツール。昔、 Javaで実装されてた時期があるんだけど、そこから放置されちゃって、数年前におそらくは別の方が再実装し始めて、また放置、みたいな。
_RSense - EmacsやVimなどに特化したRubyのための優れた開発援助ツール
_m2ym/rsense
さておき、インストール後に rsense start でRseneサーバが起動するはずなのだけど。
_headius/spoon: A fork/exec replacement for FFI-capable implementations を眺めると…。 _spoon/spoon.rb の中で、Windows と UNIX で使うファイルを分けてて。 _spoon/unix.rb には FileActionsクラスどころか他にも色んなクラスやメソッドがあるんだけど、 _spoon/windows.rb はガラガラで。そもそも Spoon って何をしてくれるライブラリなのかそこからして分からんけど、おそらくこれじゃ動かないよなと。
なんとなく、以下の記事を思い出したりもして。
_依存関係をなくそう : Rubyアプリ・Gemの開発者への提言 | プログラミング | POSTD
_NPMとleft-pad : 私たちはプログラミングのやり方を忘れてしまったのか? | プログラミング | POSTD
_本の虫: npmからkikとその他諸々が消されたまとめ
_npm パッケージの unpublish に関するゴタゴタの大まかなまとめ - ヤルキデナイズド
ちなみに、Ruby 2.2 + Rsense 0.3(オリジナル版)は、一応 Windows10x 64上でも動いていて。NTEmacs 24.5.1 を使いながら Rubyスクリプトを書く際には補完も効いてはいるのですけれど。
_rsense | RubyGems.org | your community gem host
_rsense/rsense: Rsense Can See All
Rsenseというのは、エディタ上でRubyのアレコレを補完してくれるツール。昔、 Javaで実装されてた時期があるんだけど、そこから放置されちゃって、数年前におそらくは別の方が再実装し始めて、また放置、みたいな。
_RSense - EmacsやVimなどに特化したRubyのための優れた開発援助ツール
_m2ym/rsense
さておき、インストール後に rsense start でRseneサーバが起動するはずなのだけど。
> rsense start D:/Ruby/Ruby23/lib/ruby/gems/2.3.0/gems/rsense-0.5.18/lib/rsense/client/runner.rb:112:in `start': uninitialized constant Spoon::FileActions (NameError) Did you mean? FileUtils from C:/Ruby/Ruby23/lib/ruby/gems/2.3.0/gems/rsense-0.5.18/bin/rsense:12:in `<top (required)>' from C:/Ruby/Ruby23/bin/rsense:22:in `load' from C:/Ruby/Ruby23/bin/rsense:22:in `<main>'予想はしてたけど、Windows上ではエラーが出て動かない。 _Spoon というライブラリが FileActions という名前の何かを持ってるはずだからソレを使おうと思ったけど見つからねえよ、と怒られてる。
_headius/spoon: A fork/exec replacement for FFI-capable implementations を眺めると…。 _spoon/spoon.rb の中で、Windows と UNIX で使うファイルを分けてて。 _spoon/unix.rb には FileActionsクラスどころか他にも色んなクラスやメソッドがあるんだけど、 _spoon/windows.rb はガラガラで。そもそも Spoon って何をしてくれるライブラリなのかそこからして分からんけど、おそらくこれじゃ動かないよなと。
なんとなく、以下の記事を思い出したりもして。
_依存関係をなくそう : Rubyアプリ・Gemの開発者への提言 | プログラミング | POSTD
_NPMとleft-pad : 私たちはプログラミングのやり方を忘れてしまったのか? | プログラミング | POSTD
_本の虫: npmからkikとその他諸々が消されたまとめ
_npm パッケージの unpublish に関するゴタゴタの大まかなまとめ - ヤルキデナイズド
ちなみに、Ruby 2.2 + Rsense 0.3(オリジナル版)は、一応 Windows10x 64上でも動いていて。NTEmacs 24.5.1 を使いながら Rubyスクリプトを書く際には補完も効いてはいるのですけれど。
[ ツッコむ ]
#2 [ruby] UbuntuとRubyとRsenseのgem
VMware上でUbuntu 16.04 を動かして、その上で Rsense をgemを使ってインストールできるのか試してみたり。
まず、Ruby 2.3 をインストール。
ググったところ、PPAだかリポジトリだかを追加して Ruby 2.3 をインストールする事例ばかりが出てきたけど。Ubuntu 16.04 はひょっとすると標準リポジトリに Ruby2.3 が既に入ってるようで。少なくとも /etc/apt/sources.list.d/ を眺めた感じでは、昔の自分はPPAを追加してなかった。が、インストールできた。たぶん。
RSense は、sudo gem install rsense でインストール。その後 rsense start と打ってみたらサーバが動いてくれたようで、接続すべき port が表示された。rsense stop でサーバを停止。
まず、Ruby 2.3 をインストール。
sudo apt-get install ruby2.3 ruby2.3-devruby2.3-dev を入れておかないと、ネイティブ(?)ライブラリがビルドできないので入れておく。
ググったところ、PPAだかリポジトリだかを追加して Ruby 2.3 をインストールする事例ばかりが出てきたけど。Ubuntu 16.04 はひょっとすると標準リポジトリに Ruby2.3 が既に入ってるようで。少なくとも /etc/apt/sources.list.d/ を眺めた感じでは、昔の自分はPPAを追加してなかった。が、インストールできた。たぶん。
RSense は、sudo gem install rsense でインストール。その後 rsense start と打ってみたらサーバが動いてくれたようで、接続すべき port が表示された。rsense stop でサーバを停止。
◎ EmacsやVimでは使えない。 :
ググったところ、Emacs や Vim から RSense を使おうとした場合、オリジナル版の 0.3 を使った事例ばかりが出てきてしまって。gem経由でインストールできる版は、Atom や Sublime Text等の拡張しか用意されてないっぽい。
ということは、Emacs や Vim で使いたいならオリジナル版を、Atom や Sublime Text 等で使いたい場合は gem経由版を、ということになるのだろうかと。
Vim側でも問題が。 _Rsense(rsense/rsense)を利用してVimでRubyの補完を実現する - Qiita によると、Vim + gem経由版 Rsense で使えなくもないようだけど。
てなわけで、*NIXだったらすんなり使える、というわけでもなさそうだなと…。上手くいきそうな組み合わせを考えないといけないようで。ちと面倒。
ということは、Emacs や Vim で使いたいならオリジナル版を、Atom や Sublime Text 等で使いたい場合は gem経由版を、ということになるのだろうかと。
Vim側でも問題が。 _Rsense(rsense/rsense)を利用してVimでRubyの補完を実現する - Qiita によると、Vim + gem経由版 Rsense で使えなくもないようだけど。
補完プラグインであるneocomplecacheは、すでに後継のShougo/neocomplete.vimに開発が移行して久しいですが、rsenseと組み合わせて使うプラグインは、neocompleteだと現在無く、neocomplecacheだとあるためです。という話も。自分の ~/.vimrc を眺めたら neocomplete を使ってたので、neocomplecache と競合しそうな気もする。
てなわけで、*NIXだったらすんなり使える、というわけでもなさそうだなと…。上手くいきそうな組み合わせを考えないといけないようで。ちと面倒。
◎ Atomで試してみる。 :
とりあえず Atom をインストールして試してみる。
_atomをUbuntuにPPA経由でインストールする - Qiita
Ctrl+, を叩いて、設定画面を表示。 _japanese-menu と _autocomplete-ruby をインストール。autocomplete-ruby の設定で、rsense のパスを指定。ターミナルで which rsense と打てば、rsense のパスが分かる。
ここまでやってから、AtomでRubyスクリプトを書いてみたけど、補完が効いてるように見えた。Atom を使う分には、gem経由版 Rsense も使える、と捉えてもよさそう。
ついでに、Rubyスクリプトのソース整形もできるように、rubocop を gem install rubocop でインストールしたり、 _atom-beautify をインストールしてみたけど。Ubuntu の場合、atom-beautify のデフォルトキー割り当て、Ctrl + Alt + B が、スクリーンキーボード(仮想キーボード)の表示で既に使われているようで。
Ubuntu側の設定を変えて、仮想キーボード表示のショートカットキーを無効に設定。Ubuntuのデスクトップの上のほうにあるキーボードのアイコンをクリックして、設定 → 全体の設定 → 拡張オプションの表示 → 仮想キーボード、の割り当てを空に(ボタンをクリックしてからESCキーを押す)、みたいな。
_atomをUbuntuにPPA経由でインストールする - Qiita
sudo add-apt-repository ppa:webupd8team/atom sudo apt-get update sudo apt-get install atomインストールできた。ターミナルから atom と打ったら起動した。…関係ないけど、Atom は *NIX上でも、やっぱりちょっと起動が遅い。
Ctrl+, を叩いて、設定画面を表示。 _japanese-menu と _autocomplete-ruby をインストール。autocomplete-ruby の設定で、rsense のパスを指定。ターミナルで which rsense と打てば、rsense のパスが分かる。
ここまでやってから、AtomでRubyスクリプトを書いてみたけど、補完が効いてるように見えた。Atom を使う分には、gem経由版 Rsense も使える、と捉えてもよさそう。
ついでに、Rubyスクリプトのソース整形もできるように、rubocop を gem install rubocop でインストールしたり、 _atom-beautify をインストールしてみたけど。Ubuntu の場合、atom-beautify のデフォルトキー割り当て、Ctrl + Alt + B が、スクリーンキーボード(仮想キーボード)の表示で既に使われているようで。
Ubuntu側の設定を変えて、仮想キーボード表示のショートカットキーを無効に設定。Ubuntuのデスクトップの上のほうにあるキーボードのアイコンをクリックして、設定 → 全体の設定 → 拡張オプションの表示 → 仮想キーボード、の割り当てを空に(ボタンをクリックしてからESCキーを押す)、みたいな。
[ ツッコむ ]
#3 [ruby] Rubyのgemが使えない
Windows10 x64 + Ruby 2.2 / 2.3 で gem を使おうとしたら、SSL証明書が古くなったから使えないよ、みたいなメッセージが表示されて。ググった感じでは、AddTrustExternalCARoot-2048.pem を更新しないといけないらしいが…。rubygemsを更新することで対策する手段が現段階では用意されているようで。
_AddTrustExternalCARoot-2048.pem が not found 。また証明書が更新されたらしい --rails - ミスターFのいろいろプログラミング
_SSL Certificate Update - RubyGems Guides
rubygems-update-2.6.7.gem をDLして、以下を実行。
たしか以前も、こういうことがあったな…。その時は .pem とやらを更新して対応したような…。どうだったかな…。
_AddTrustExternalCARoot-2048.pem が not found 。また証明書が更新されたらしい --rails - ミスターFのいろいろプログラミング
_SSL Certificate Update - RubyGems Guides
rubygems-update-2.6.7.gem をDLして、以下を実行。
gem install --local rubygems-update-2.6.7.gem update_rubygems --no-ri --no-rdoc gem --version gem uninstall rubygems-update -xgem が使えるようになった。
たしか以前も、こういうことがあったな…。その時は .pem とやらを更新して対応したような…。どうだったかな…。
[ ツッコむ ]
#4 [anime] 放映に間に合わないTVアニメが少し増えてきたような
ロボットアニメの「レガリア」、自転車アニメの「ろんぐらいだぁす」、フィギュアスケートアニメの「ユーリ」、魔法飛行少女アニメの「ブレイブウィッチーズ」等、制作が間に合わなくて放映が延期されるアニメがチラホラ増えてきたような。
そもそも本数が多過ぎるのだろうけど…。総集編を何度か入れたあげく最終回も間に合わなかった戦車アニメの「ガルパン」が大ヒットしたので、ある意味勇気づけられてるところもありそうだなと想像したりもして。
放映にはちょくちょく間に合わないけれど、しっかり作られてるアニメと。放映にはどうにか無理矢理かろうじて間に合わせたけど、ネット上ではやれ作画崩壊と騒がれてしまうアニメと。どちらがヒットする確率が高くなりそうかと考えたら…。そりゃ、再放送でも総集編でもとにかく入れて、一発でちゃんとした映像を作ったほうがまだマシかもと思えてきたりもするわけで。ということで個人的には、無理矢理間に合わせるより違う策を取れるなら取ったほうが、と思わないでもないですが、そこはそれぞれ色々な事情があるんだろうと…。
今はもう、TVアニメと呼ばれているOVAを作ってるようなもんだし…。映像のクオリティがとんでもないことになってるし…。玩具を売るために放映してるわけでもないし…。本数は無茶苦茶なことになってるし…。昔とは色々と違うのだから、昔のように、TVアニメは毎週新作が放送されるもの、などと思い込むのもおかしな話。どこぞのスタジオでは制作進行さんが過労死してるけど、リアルに人を殺してまで作るものでもないだろう、とも思うし。裾野が広くないと山は高くならないものだけど、制作リソースが限られている状況で裾野を無闇に広げたら逆に低くなっちゃうよな、とも思うし。
てなことをもやもやと思ってしまったのでメモ。思考メモです。
そもそも本数が多過ぎるのだろうけど…。総集編を何度か入れたあげく最終回も間に合わなかった戦車アニメの「ガルパン」が大ヒットしたので、ある意味勇気づけられてるところもありそうだなと想像したりもして。
放映にはちょくちょく間に合わないけれど、しっかり作られてるアニメと。放映にはどうにか無理矢理かろうじて間に合わせたけど、ネット上ではやれ作画崩壊と騒がれてしまうアニメと。どちらがヒットする確率が高くなりそうかと考えたら…。そりゃ、再放送でも総集編でもとにかく入れて、一発でちゃんとした映像を作ったほうがまだマシかもと思えてきたりもするわけで。ということで個人的には、無理矢理間に合わせるより違う策を取れるなら取ったほうが、と思わないでもないですが、そこはそれぞれ色々な事情があるんだろうと…。
今はもう、TVアニメと呼ばれているOVAを作ってるようなもんだし…。映像のクオリティがとんでもないことになってるし…。玩具を売るために放映してるわけでもないし…。本数は無茶苦茶なことになってるし…。昔とは色々と違うのだから、昔のように、TVアニメは毎週新作が放送されるもの、などと思い込むのもおかしな話。どこぞのスタジオでは制作進行さんが過労死してるけど、リアルに人を殺してまで作るものでもないだろう、とも思うし。裾野が広くないと山は高くならないものだけど、制作リソースが限られている状況で裾野を無闇に広げたら逆に低くなっちゃうよな、とも思うし。
てなことをもやもやと思ってしまったのでメモ。思考メモです。
[ ツッコむ ]
2016/10/25(火) [n年前の日記]
#1 [python] PySideでマウス座標を常に取得
PySideを使って、QGraphicsScene の中でマウス座標を常に取得することができるか実験。要は、マウスカーソルを動かすとその位置に追従して画像も表示される、みたいなことをしたい。お絵かきソフトではブラシ枠がマウスカーソル位置に表示されてたりするけど、おおよそあんな感じで。
_gview_mousecursor.py
一応できたっぽい。
ブラシ画像は、 _brush.png を使った。
_gview_mousecursor.py
""" PySide + QGraphicsView上でマウスカーソルに何かを追従させる 動作確認環境 : Windows10 x64 + Python 2.7.11 + PySide 1.2.4 """ import sys from PySide.QtCore import * from PySide.QtGui import * brushFile = "brush.png" canvasSize = (640, 480) padding = 48 status = None class DrawAreaScene(QGraphicsScene): """ 描画ウインドウ用Scene """ def __init__(self, *argv, **keywords): super(DrawAreaScene, self).__init__(*argv, **keywords) global brushFile global canvasSize global padding # Scene に 空QPixmap を追加 w, h = canvasSize self.pixmap = QPixmap(w, h) self.pixmap.fill(QColor(192, 192, 192, 255)) self.imgItem = QGraphicsPixmapItem(self.pixmap) self.addItem(self.imgItem) self.imgItem.setX(padding) self.imgItem.setY(padding) # Scene にブラシ画像を追加 self.brushPixmap = QPixmap(brushFile) self.brushImgItem = QGraphicsPixmapItem(self.brushPixmap) self.addItem(self.brushImgItem) def mousePressEvent(self, event): """ マウスボタンを押した """ x, y = self.getMousePos(event, "Click") def mouseReleaseEvent(self, event): """ マウスボタンを離した """ x, y = self.getMousePos(event, "Release") def mouseMoveEvent(self, event): """ マウスを動かしてる時に呼ばれる処理。 デフォルトではマウスボタンを押してる間(ドラッグ中)しか呼ばれないが、 親のQGraphicsView で viewport() の mouseTracking を True にすれば マウスを動かした際に常時呼ばれるようになる。 """ x, y = self.getMousePos(event, "Move") # ブラシが非表示なら表示を有効化 if not self.brushImgItem.isVisible(): self.setVisibleBrush(True) # ブラシの表示位置を変更 pm = self.brushImgItem.pixmap() xd = pm.width() / 2 yd = pm.height() / 2 self.brushImgItem.setOffset(int(x - xd), int(y - yd)) def getMousePos(self, event, msg): """ マウス座標を取得 """ x = event.scenePos().x() y = event.scenePos().y() global status status.showMessage("(%d , %d) %s" % (x, y, msg)) return (x, y) def setVisibleBrush(self, flag): """ ブラシ表示の有効無効切り替え """ self.brushImgItem.setVisible(flag) class DrawAreaView(QGraphicsView): """ メインになるQGraphicsView """ def __init__(self, *argv, **keywords): super(DrawAreaView, self).__init__(*argv, **keywords) self.setBackgroundBrush(QColor(64, 64, 64, 255)) # 背景色を設定 self.setCacheMode(QGraphicsView.CacheBackground) # self.setRenderHints(QPainter.Antialiasing | # QPainter.SmoothPixmapTransform | # QPainter.TextAntialiasing) # Sceneを登録 scene = DrawAreaScene(self) self.setScene(scene) self.setSceneNewRect() # 子のSceneに対してマウストラッキングを有効に vp = self.viewport().setMouseTracking(True) def resizeEvent(self, event): """ リサイズ時に呼ばれる処理 """ super(DrawAreaView, self).resizeEvent(event) self.setSceneNewRect() def scrollContentsBy(self, dx, dy): """ スクロールバー操作時に呼ばれる処理 """ # スクロール中、Scene内にブラシがあると # 何故かゴミが残るので、ブラシを非表示にしている self.scene().setVisibleBrush(False) super(DrawAreaView, self).scrollContentsBy(dx, dy) def setSceneNewRect(self): """ Sceneの矩形を更新 """ # 以下は、Sceneのアイテム群境界ボックスを取得する例 # rect = self.scene().itemsBoundingRect() # 以下は、viewport のサイズを指定する例 # rect = QRectf(self.viewport().rect()) global canvasSize global padding w, h = canvasSize # キャンバス周辺に余白を設けたサイズを求める w += padding * 2 h += padding * 2 rect = QRectF(0, 0, w, h) # Sceneの矩形を更新。自動でスクロールバーの長さも変わってくれる self.scene().setSceneRect(rect) class MyVWidget(QWidget): """ メインウインドウ周辺に配置するWidget """ def __init__(self, parent=None): super(MyVWidget, self).__init__(parent) l = QVBoxLayout() # 縦に並べる l.addWidget(QLabel("Dummy")) self.setLayout(l) class MyMainWindow(QMainWindow): """ メインウインドウ """ def __init__(self, *argv, **keywords): super(MyMainWindow, self).__init__(*argv, **keywords) self.setWindowTitle("Mouse Tracking Test") self.resize(640, 480) # メニューバー mb = QMenuBar() file_menu = QMenu("&File", self) exit_action = file_menu.addAction("&Close") exit_action.setShortcut('Ctrl+Q') exit_action.triggered.connect(qApp.quit) mb.addMenu(file_menu) self.setMenuBar(mb) # ステータスバー global status status = QStatusBar(self) self.setStatusBar(status) status.showMessage("Status Bar") # 左ドック self.leftDock = QDockWidget("Left Dock", self) self.leftDock.setWidget(MyVWidget(self)) self.addDockWidget(Qt.LeftDockWidgetArea, self.leftDock) # 中央Widget self.gview_image = DrawAreaView(self) self.setCentralWidget(self.gview_image) def main(): """ メイン処理 """ # このあたりを指定すると描画が速くなるという話を見かけたが、 # "native"、"raster"、"opengl" を指定しても結果は変わらなかった… QApplication.setGraphicsSystem("raster") app = QApplication(sys.argv) w = MyMainWindow() w.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
一応できたっぽい。
ブラシ画像は、 _brush.png を使った。
◎ mouseTracking が肝らしい。 :
QGraphicsScene には、mouseMoveEvent() という、マウスカーソルを動かした時に呼ばれるメソッドがあらかじめ用意されているのだけど。この mouseMoveEvent() は、デフォルトでは「マウスボタンを押してる間」しか呼ばれない。要は、ドラッグ操作を前提としているわけで。
しかし今回は、マウスボタンの状態に関係なく、マウスカーソルが動いたらとにかく座標を取得したい。
その場合は、QGraphicsScene の親に相当する、QGraphicsView の viewport() に対して、setMouseTracking(True) をしてやるといいらしい。
_シーンでマウストラッキング - TB-code
試してみたところ、常にマウスカーソル座標が取得できるようになった。
他にも、全てのイベントを一旦受け付けて、イベント種類でフィルタリングして、マウスカーソルが動いたかどうかを検出する、というやり方もあるらしい。
しかし今回は、マウスボタンの状態に関係なく、マウスカーソルが動いたらとにかく座標を取得したい。
その場合は、QGraphicsScene の親に相当する、QGraphicsView の viewport() に対して、setMouseTracking(True) をしてやるといいらしい。
_シーンでマウストラッキング - TB-code
試してみたところ、常にマウスカーソル座標が取得できるようになった。
他にも、全てのイベントを一旦受け付けて、イベント種類でフィルタリングして、マウスカーソルが動いたかどうかを検出する、というやり方もあるらしい。
◎ スクロールバーの長さ。 :
今まで QGraphicsView を使った際に、スクロールバーの長さが妙な感じになっていて悩んでたけど。self.scene().setSceneRect() で、ちゃんとした QRectf を渡してやればそれっぽいスクロールバーの長さになってくれることが分かった。
例えば、Sceneのアイテム群境界ボックスを取得してやれば、それらしくなるし。
あるいは、QGraphicsView の viewport のサイズを指定してやれば、QGraphicsView のスクロール領域サイズ = Sceneのサイズになるのでスクロールバーが消えてくれるし。
今回は、Scene が持ってる空のQPixmap(キャンバス相当)サイズ+余白を指定して、キャンバスの端の部分もある程度表示できるようにしてみたり。
例えば、Sceneのアイテム群境界ボックスを取得してやれば、それらしくなるし。
rect = self.scene().itemsBoundingRect() self.scene().setSceneRect(rect)
あるいは、QGraphicsView の viewport のサイズを指定してやれば、QGraphicsView のスクロール領域サイズ = Sceneのサイズになるのでスクロールバーが消えてくれるし。
rect = QRectf(self.viewport().rect()) self.scene().setSceneRect(rect)
今回は、Scene が持ってる空のQPixmap(キャンバス相当)サイズ+余白を指定して、キャンバスの端の部分もある程度表示できるようにしてみたり。
w += padding * 2 h += padding * 2 rect = QRectF(0, 0, w, h) self.scene().setSceneRect(rect)ただし、この場合は、空のQPixmap の offset を余白分ずらしておく必要有。
◎ 描画速度が遅い。 :
一応処理はできたけど、別の問題が出てきた。マウスを素早く動かすと、追従してる画像がちらついてしまう。どうも描画が遅いというか、パフォーマンスが出ないというか。
アプリの開始時に QApplication.setGraphicsSystem("opengl") を呼ぶことで描画速度が変わってくるという話も見かけたけど、自分の手元の環境では特に変化は見られなかった。まあ、仮に変化があったとしても、環境によって、opengl を指定するとむしろ遅くなるとか、native と raster の速度が変わらんとかあるようで。改善してくれることを期待しちゃダメ、ってことだろうなと。
また、「QGraphics* は複数のアイテムを登録してアレコレできる分、色々と処理が遅い。処理速度を求めるなら使うべきではない」という主張も見かけたし、あるいは、「最低限の再描画領域をその都度求めてクリッピングしてやれば速度が稼げる」という話も見かけた。
もっとも、考えてみれば…。マウスを素早く動かしてる時に正確な画像描画を目にしないと作業ができないというわけでもないだろうし。このくらいは目を瞑るのもアリかもしれないなと。
あるいは、お絵かきソフトの類は大量のアイテムを登録して描画したいわけでもないだろうから、別のWidgetを使ってどうにかできないか検討するのもアリかもしれず。レイヤーに相当する QPixmap を何枚か上書きしていって、最後にブラシ枠画像を描画すればいいのだろうし。であれば、QGraphics* を持ち出すほどの処理ではない、かもしれない。
アプリの開始時に QApplication.setGraphicsSystem("opengl") を呼ぶことで描画速度が変わってくるという話も見かけたけど、自分の手元の環境では特に変化は見られなかった。まあ、仮に変化があったとしても、環境によって、opengl を指定するとむしろ遅くなるとか、native と raster の速度が変わらんとかあるようで。改善してくれることを期待しちゃダメ、ってことだろうなと。
また、「QGraphics* は複数のアイテムを登録してアレコレできる分、色々と処理が遅い。処理速度を求めるなら使うべきではない」という主張も見かけたし、あるいは、「最低限の再描画領域をその都度求めてクリッピングしてやれば速度が稼げる」という話も見かけた。
もっとも、考えてみれば…。マウスを素早く動かしてる時に正確な画像描画を目にしないと作業ができないというわけでもないだろうし。このくらいは目を瞑るのもアリかもしれないなと。
あるいは、お絵かきソフトの類は大量のアイテムを登録して描画したいわけでもないだろうから、別のWidgetを使ってどうにかできないか検討するのもアリかもしれず。レイヤーに相当する QPixmap を何枚か上書きしていって、最後にブラシ枠画像を描画すればいいのだろうし。であれば、QGraphics* を持ち出すほどの処理ではない、かもしれない。
[ ツッコむ ]
#2 [prog][windows] AtomのScriptがやっとWindowsに対応してくれた
Atomエディタの拡張として、
_Script
という、PythonスクリプトだのRubyスクリプトだのをその場で実行できる拡張があるのだけど。
ふと気付いたら、ようやく Windows上でShebangを無視してくれるようになったようで。
_Ignore firstline check on Windows - rgbkrk/atom-script@4374623
修正箇所は、たったの1行っぽいけど。
長かった…。今まで、アップデートでファイルが差し変わるたびに、 _毎回自分で修正 してましたよ。実にアホらしかった…。
ふと気付いたら、ようやく Windows上でShebangを無視してくれるようになったようで。
_Ignore firstline check on Windows - rgbkrk/atom-script@4374623
修正箇所は、たったの1行っぽいけど。
長かった…。今まで、アップデートでファイルが差し変わるたびに、 _毎回自分で修正 してましたよ。実にアホらしかった…。
◎ ちょっと解説。 :
Python や Ruby等のスクリプトは、えてして、ソースの1行目に、
_Shebang(シバン行)
と呼ばれる、以下のような記述があって。
これは *NIX用の記述で…。
*NIX は Windows と違って、ファイルの拡張子と、そのファイルを利用するプログラムを関連付けてない。だから、「オイ、*NIXよ。このファイルを実行しろや」と指示しても、何を使って実行すればいいのか分からない。なので、ファイルの1行目を読んで、「ふむ。要は、この /usr/bin/env python なる者に、このファイルをそのまま渡してやればよろしいのですな」と判断して実行するわけで。
ただ、*NIX の世界は、環境によって、python だの ruby だのをどの場所に置いているか違っていたりする。だから、python等の場所(ファイルパス)を直接書くと問題が発生する。他所からスクリプトを持ってくるたびに、1行目を自分の環境に合わせて修正してやる羽目になる。
それはマズいよね、面倒臭いよね、ってことで、*NIX 世界の人達は、/usr/bin/ に _env ってツールを入れといて、env を経由してやれば python だの ruby だのは探して呼んでくれるよ、○○がどこに置いてあるかなんて気にしなくて済むよ、ということにした。これで、どの環境に持っていっても動いてくれるスクリプトが書けるようになったわけで。
ところが、Windows には /usr/bin/ なんてフォルダ自体が無いし、もちろん env も入ってない。そもそも Windows は、ファイルの拡張子で何のプログラムを呼び出すか覚えているから、Shebang を見る必要が無い。
ということで、Windows用の Python や Ruby は、1行目の Shebang を無視するようになっていて。せいぜい見るとしても、そこに書かれてるオプション文字列ぐらいしかチェックしない。「#!/usr/bin/env」の部分は無視しちゃう。
こうすることで、*NIX でも Windows でも、同じスクリプトソースを動かせるようにしていたわけですよ。
ところが、Atom拡張の Script は、1行目の Shebang をキッチリ見てしまう。*NIX でも Mac でも Windows でも、「/usr/bin/env python を呼べばええのやな」と処理していて。結果、Windows上で動かした時だけ、「/usr/bin/env なんて知らねえよボケ」とエラーが出ていたという。
更に、「コレ、エラー出るんだけど」とバグ報告があっても、「は? Linux や Mac では動くんですけど?」「Shebang に #!C:\〜\python って書けば動くだろ? 1行目には正確なパスを書くもんだぞ」とか返されちゃって。コイツラ、「#!/usr/bin/env 〜」の意味が分かってねえ…。
せっかく Pythonその他が、どのOS上でも動くようにと気配りして実装されてるのに、Atom拡張の Script はその努力を台無しにしていたわけですよ。…どうやら作者様が Windows を持ってないらしいので仕方ないところもありますが。
てなわけで、そのあたりの問題が解決したのはありがたいことだなと。こうして長々と誰も読まないであろう解説をテンション上がって書いてしまうぐらいに、個人的には大変喜んでおります。ありがたや。修正してくれてマジthx。
#!/usr/bin/env python
これは *NIX用の記述で…。
*NIX は Windows と違って、ファイルの拡張子と、そのファイルを利用するプログラムを関連付けてない。だから、「オイ、*NIXよ。このファイルを実行しろや」と指示しても、何を使って実行すればいいのか分からない。なので、ファイルの1行目を読んで、「ふむ。要は、この /usr/bin/env python なる者に、このファイルをそのまま渡してやればよろしいのですな」と判断して実行するわけで。
ただ、*NIX の世界は、環境によって、python だの ruby だのをどの場所に置いているか違っていたりする。だから、python等の場所(ファイルパス)を直接書くと問題が発生する。他所からスクリプトを持ってくるたびに、1行目を自分の環境に合わせて修正してやる羽目になる。
それはマズいよね、面倒臭いよね、ってことで、*NIX 世界の人達は、/usr/bin/ に _env ってツールを入れといて、env を経由してやれば python だの ruby だのは探して呼んでくれるよ、○○がどこに置いてあるかなんて気にしなくて済むよ、ということにした。これで、どの環境に持っていっても動いてくれるスクリプトが書けるようになったわけで。
ところが、Windows には /usr/bin/ なんてフォルダ自体が無いし、もちろん env も入ってない。そもそも Windows は、ファイルの拡張子で何のプログラムを呼び出すか覚えているから、Shebang を見る必要が無い。
ということで、Windows用の Python や Ruby は、1行目の Shebang を無視するようになっていて。せいぜい見るとしても、そこに書かれてるオプション文字列ぐらいしかチェックしない。「#!/usr/bin/env」の部分は無視しちゃう。
こうすることで、*NIX でも Windows でも、同じスクリプトソースを動かせるようにしていたわけですよ。
ところが、Atom拡張の Script は、1行目の Shebang をキッチリ見てしまう。*NIX でも Mac でも Windows でも、「/usr/bin/env python を呼べばええのやな」と処理していて。結果、Windows上で動かした時だけ、「/usr/bin/env なんて知らねえよボケ」とエラーが出ていたという。
更に、「コレ、エラー出るんだけど」とバグ報告があっても、「は? Linux や Mac では動くんですけど?」「Shebang に #!C:\〜\python って書けば動くだろ? 1行目には正確なパスを書くもんだぞ」とか返されちゃって。コイツラ、「#!/usr/bin/env 〜」の意味が分かってねえ…。
せっかく Pythonその他が、どのOS上でも動くようにと気配りして実装されてるのに、Atom拡張の Script はその努力を台無しにしていたわけですよ。…どうやら作者様が Windows を持ってないらしいので仕方ないところもありますが。
てなわけで、そのあたりの問題が解決したのはありがたいことだなと。こうして長々と誰も読まないであろう解説をテンション上がって書いてしまうぐらいに、個人的には大変喜んでおります。ありがたや。修正してくれてマジthx。
[ ツッコむ ]
2016/10/26(水) [n年前の日記]
#1 [pc] メインPCのHDDが遅い気がする
どうもメインPCのHDDが遅いような気がする。GIMP や Inkscape を起動する際に数分かかるのはどうもおかしいというか。以前も数分かかってたけど、もうちょっと速かったような。
環境は…。
CrystalDiskMark で測定してみた。
アレ? HDD自体は、そんなに遅くないな。ということは…どゆこと?
環境は…。
- M/B : Intel DH67BL (B3ステップ)
- HDD : Western Digital WD10EALX-009BA0 (WD Blue、1TB、SATA600)
CrystalDiskMark で測定してみた。
----------------------------------------------------------------------- CrystalDiskMark 5.1.2 x64 (C) 2007-2016 hiyohiyo Crystal Dew World : http://crystalmark.info/ ----------------------------------------------------------------------- * MB/s = 1,000,000 bytes/s [SATA/600 = 600,000,000 bytes/s] * KB = 1000 bytes, KiB = 1024 bytes Sequential Read (Q= 32,T= 1) : 125.153 MB/s Sequential Write (Q= 32,T= 1) : 113.850 MB/s Random Read 4KiB (Q= 32,T= 1) : 1.734 MB/s [ 423.3 IOPS] Random Write 4KiB (Q= 32,T= 1) : 1.602 MB/s [ 391.1 IOPS] Sequential Read (T= 1) : 120.791 MB/s Sequential Write (T= 1) : 110.307 MB/s Random Read 4KiB (Q= 1,T= 1) : 0.585 MB/s [ 142.8 IOPS] Random Write 4KiB (Q= 1,T= 1) : 1.140 MB/s [ 278.3 IOPS] Test : 100 MiB [C: 88.7% (203.1/229.0 GiB)] (x3) [Interval=5 sec] Date : 2016/10/26 21:17:19 OS : Windows 10 Professional [10.0 Build 10586] (x64) HDD WDC WD10EALX-009BA0 (SATA 6Gb/s)
アレ? HDD自体は、そんなに遅くないな。ということは…どゆこと?
[ ツッコむ ]
#2 [nitijyou] 自転車で買い物に
近所のコンビニ(?)で煙草を、ザ・ビッグで夜食等を購入。
◎ ゴールデンバットがフィルタ付きになってた。 :
煙管を使って吸ってる関係で、フィルタのついてないゴールデンバットを買ってたのだけど。今回買ったソレを開けてみてビックリ。なんでフィルタが付いてるんだ…。今までフィルム包装されてなかったのに、フィルム包装されてたから、何か妙だなとは思ったけれど…。
ググってみたら、2016年6月からフィルタ付きで売り始めたらしい。知らなかった。余計なことをしやがって…。
_ゴールデンバットにフィルター?狂気の沙汰だろ… - Togetterまとめ
_ゴールデンバットがフィルター付きに変更されていた... - 雨降ればブログ
それにしても、今まで買ってた品は、6月前に店が仕入れてた品だったのだな。自分は何も知らないまま、運良く買えてたのか…。逆に考えると、つまりはそれだけこの銘柄を買う人が少なかったということでもありそうな。市内中を探したけど、売ってる店は一軒しか見つからなかったし。どの店でも、そもそも売ってないという。
さて、困った。フィルタは要らないんだけど、どうしたもんか…。いやまあ、「そもそも吸うなよ」「禁煙しろよ」としか言われない話ではあるのだけど。
ググってみたら、2016年6月からフィルタ付きで売り始めたらしい。知らなかった。余計なことをしやがって…。
_ゴールデンバットにフィルター?狂気の沙汰だろ… - Togetterまとめ
_ゴールデンバットがフィルター付きに変更されていた... - 雨降ればブログ
それにしても、今まで買ってた品は、6月前に店が仕入れてた品だったのだな。自分は何も知らないまま、運良く買えてたのか…。逆に考えると、つまりはそれだけこの銘柄を買う人が少なかったということでもありそうな。市内中を探したけど、売ってる店は一軒しか見つからなかったし。どの店でも、そもそも売ってないという。
さて、困った。フィルタは要らないんだけど、どうしたもんか…。いやまあ、「そもそも吸うなよ」「禁煙しろよ」としか言われない話ではあるのだけど。
[ ツッコむ ]
2016/10/27(木) [n年前の日記]
#1 [python] PySideでズーム表示を試しているところ
PySide の QGraphics* で、ズーム表示を試しているところ。
◎ 拡大縮小表示自体の処理。 :
とりあえず拡大したり縮小したりの表示はできるようになったのだけど…。要は、QGraphicsScene に登録された Item に、setTransform() で「拡大縮小しろや」と設定してやればいいようで。
しかし、欲を出して、中ボタンドラッグ(ホイールボタンドラッグ)でキャンバス相当をスクロールさせようとしたあたりでハマり始めて。
def changeScale(self, scale): """ ズーム変更 """ global padding self.zoomv = scale t = QTransform() t.scale(self.zoomv, self.zoomv) # スケールだけ反映 self.bgItem.setTransform(t) bt = QTransform() bt.scale(self.zoomv, self.zoomv) self.brushItem.setTransform(bt)
しかし、欲を出して、中ボタンドラッグ(ホイールボタンドラッグ)でキャンバス相当をスクロールさせようとしたあたりでハマり始めて。
◎ 中ボタンドラッグでスクロール。 :
中ボタンドラッグでスクロールする方法は、以下が参考になった。
_python - How to scrolling QGraphicsScene in QGraphicsView by middle mouse? - Stack Overflow
要するに、マウス座標の変化分を offset としたとして、
しかし、上手くいかない…。
今までは、QGraphicsScene 内でマウスイベントを取得してたけど。それだと、中ボタンドラッグ開始と同時にスクロールがガガガガガガガって感じになって、ずっと処理が返ってこなくなった。何が起きてるのだ…。
おそらくだけど、中ボタンドラッグを検知してスクロールバーの位置を変更 → スクロールバーが動いたから中のWidgetの位置も動く → マウスカーソルが動いたものとして扱われる → 中ボタンドラッグ処理がそのまま再度呼び出され、またスクロールバーの位置が変更されて、みたいなことが延々と起きて無限ループに陥ってる、ような気がする。
仕方ないので、QGraphicsScene の中でマウスイベントを受け取るのは諦めて、マウスイベント関係は全て QGraphicsView 側で処理するようにしてみたり。これで、前述のような不具合は起きなくなった。
ところが、コレはコレでマウスカーソル座標の扱いに関して別の問題が。
_python - How to scrolling QGraphicsScene in QGraphicsView by middle mouse? - Stack Overflow
要するに、マウス座標の変化分を offset としたとして、
self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() + offset.x()) self.verticalScrollBar().setValue(self.verticalScrollBar().value() + offset.y())みたいなことをしてやればいいらしい。
しかし、上手くいかない…。
今までは、QGraphicsScene 内でマウスイベントを取得してたけど。それだと、中ボタンドラッグ開始と同時にスクロールがガガガガガガガって感じになって、ずっと処理が返ってこなくなった。何が起きてるのだ…。
おそらくだけど、中ボタンドラッグを検知してスクロールバーの位置を変更 → スクロールバーが動いたから中のWidgetの位置も動く → マウスカーソルが動いたものとして扱われる → 中ボタンドラッグ処理がそのまま再度呼び出され、またスクロールバーの位置が変更されて、みたいなことが延々と起きて無限ループに陥ってる、ような気がする。
仕方ないので、QGraphicsScene の中でマウスイベントを受け取るのは諦めて、マウスイベント関係は全て QGraphicsView 側で処理するようにしてみたり。これで、前述のような不具合は起きなくなった。
ところが、コレはコレでマウスカーソル座標の扱いに関して別の問題が。
◎ マウスカーソル座標取得の問題。 :
QGraphicsScene でマウスイベントを取る分には、「シーン内では、この辺にマウスカーソルがありますよ」的なイイ感じの座標取得ができたけど。QGraphicsView側で取ると、「シーンのオフセットその他モロモロなんてワシは知らんわい。とにかく QGraphicsView のガワに対してのマウスカーソル座標しか返さんぞ。つーかソレしか持ってないし」的な座標取得しかできない。
そこで、QGraphicsView 内のマウスカーソル座標+スクロールバーの値、みたいな座標値を求めて QGraphicsScene内でのマウスカーソル座標値を推測してやることに。
これで一見上手くいったように見えたものの、拡大表示をしてスクロールバーが存在しているうちはいいけれど、縮小表示をしてスクロールバーが無くなった際に正しいマウスカーソル座標値が得られなくなった。スクロールバーが無くなると、スクロールバーの値はずっと0を返すけど、実際には補正をしないといかんわけで…。
ということで泥臭いけど、おそらくは以下のようになってるのだろうと考えて、スクロールバーが有る時と無いときで座標値の求め方を変えることに。
そこで、QGraphicsView 内のマウスカーソル座標+スクロールバーの値、みたいな座標値を求めて QGraphicsScene内でのマウスカーソル座標値を推測してやることに。
これで一見上手くいったように見えたものの、拡大表示をしてスクロールバーが存在しているうちはいいけれど、縮小表示をしてスクロールバーが無くなった際に正しいマウスカーソル座標値が得られなくなった。スクロールバーが無くなると、スクロールバーの値はずっと0を返すけど、実際には補正をしないといかんわけで…。
ということで泥臭いけど、おそらくは以下のようになってるのだろうと考えて、スクロールバーが有る時と無いときで座標値の求め方を変えることに。
- self.viewport().rect().width() < self.scene().sceneRect().width() なら、スクロールバーが出ている(はず)。
- self.viewport().rect().width() >= self.scene().sceneRect().width() なら、スクロールバーは出ていない(はず)。
◎ ズーム表示の基準位置問題。 :
ズームをする時は、今まで見えてた範囲の左上の位置を基準にして拡大縮小するようにしていたのだけど。どういう処理をしているかといえば、ズーム変更前に今までのスクロールバーの値を取得しておいて、ズーム変更後、さっき取得したスクロールバーの値に新しいズーム率を掛けて、その値でスクロールバーの位置を設定、みたいな。
が、ここで欲を出して、見えてる範囲の中心を基準にしてズームを変えようとしてハマり始めたり。色々試したけど上手くいかない…。どうもスクロールバーの値とシーン内の座標値との関係が自分はさっぱり把握できてない気がする。
が、ここで欲を出して、見えてる範囲の中心を基準にしてズームを変えようとしてハマり始めたり。色々試したけど上手くいかない…。どうもスクロールバーの値とシーン内の座標値との関係が自分はさっぱり把握できてない気がする。
[ ツッコむ ]
#2 [anime] 「ViVid Strike!」4話を視聴
変身魔法少女が魔法格闘技をするアニメ、という説明でいいのだろうか…。
中盤、色々キツイ展開だな、見るの止めようかなと思ってたけど、ラストで「うわ」と声を出してしまった。そう来るか…。いやはや、これはよくやった。…何が「よくやった」なのかちょっと分かんないけど。
中盤、色々キツイ展開だな、見るの止めようかなと思ってたけど、ラストで「うわ」と声を出してしまった。そう来るか…。いやはや、これはよくやった。…何が「よくやった」なのかちょっと分かんないけど。
[ ツッコむ ]
2016/10/28(金) [n年前の日記]
#1 [python] PySideでズーム変更処理をまだ書いてたり
_QGraphicsView - PySide v1.0.7 documentation
を眺めてたら、
_scale
というメソッドがあることに気が付いて。これは…もしかして…。
今までは、QGraphicsScene 内の各Itemを拡大縮小表示させることでズーム変更をしていたけど。もしかして QGraphicsView の scale を使えば、まとめてズーム変更できるんじゃないか、と思えてきたので試したり。
scaleの使い方は、以下のやり取りが参考になった。というか、そのものズバリの PyQt版のサンプルも投稿されていて助かった。
_c++ - QGraphicsView Zooming in and out under mouse position using mouse wheel - Stack Overflow
今までは、QGraphicsScene 内の各Itemを拡大縮小表示させることでズーム変更をしていたけど。もしかして QGraphicsView の scale を使えば、まとめてズーム変更できるんじゃないか、と思えてきたので試したり。
scaleの使い方は、以下のやり取りが参考になった。というか、そのものズバリの PyQt版のサンプルも投稿されていて助かった。
_c++ - QGraphicsView Zooming in and out under mouse position using mouse wheel - Stack Overflow
◎ こんな感じになった。 :
自分で書いてみたら、こんな感じになった。…ソースが長くなってしまったので、Gistに貼ってみたり。
_gview_zoom2.py - Gist
_gview_zoom2.py - Gist
- マウスホイールで拡大縮小。
- ステータスバー上のボタンを押しても拡大縮小。
- 中ボタンドラッグ(ホイールボタンドラッグ)でスクロール。
◎ ダメな例も貼っておく。 :
もったいないから、昨日までごちゃごちゃやってた、ダメな例のソースも貼っておく。
_gview_zoom.py - Gist
前述の通り、こちらの例では QGraphicsScene内のItemを拡大縮小することでズーム変更してるのだけど。このやり方では、マウスカーソル位置を基準にして拡大縮小することが最後までできなかったという…。
_gview_zoom.py - Gist
前述の通り、こちらの例では QGraphicsScene内のItemを拡大縮小することでズーム変更してるのだけど。このやり方では、マウスカーソル位置を基準にして拡大縮小することが最後までできなかったという…。
◎ mapToScene()は便利。 :
前述のページを見ていて知ったのだけど。どうやら、mapToScene() や mapFromScene() を使うと、マウスカーソル座標の扱いも楽になるっぽい。
おそらくだけど…。
今まで、シーン内の座標値を得るために、スクロールバーの値を加味して、倍率を掛けて、とか面倒なことをしてたけど。mapToScene() を使ったらそのへんの処理をごっそり削れた。ありがたや。
おそらくだけど…。
- mapToScene() は、QGraphicsView 用の座標値を、QGraphicsScene 内での座標値に変換するメソッド。
- mapFromScene() は、QGraphicsScene用の座標値を、QGraphicsView用の座標値に変換するメソッド。
今まで、シーン内の座標値を得るために、スクロールバーの値を加味して、倍率を掛けて、とか面倒なことをしてたけど。mapToScene() を使ったらそのへんの処理をごっそり削れた。ありがたや。
◎ 浮動小数点の誤差で悩んだり。 :
ズーム変更を何度も繰り返していたら、倍率が100%に戻らず、99%になってしまって悩んだり。print で変数の値を表示しても100%(1.0)なのに、アプリ上の表示は99%になる。なんでや。Qtのバグなのかコレ。
浮動小数点の誤差っぽい。
_Python の小数 - Qiita
0.1を10回足しても1にならないソレ。超基本的なことなのに、うっかり忘れてた。
とりあえず、倍率は整数値で持つことに。実際に使う際に 100.0 で割ってから使えばええやろ…。結局最後に割ってるから誤差は残ってるけど、見た目ではどうせ分からんし。
ただ、倍率を増減させる際に 1.2 とか 0.8333 を掛けてるので、結局はやっぱり誤差が溜まってきて、どこかでおかしくなるという…。実際のソレを作る際は、100%、200%、300%等、キリがいい倍率をテーブルで持っておいて、順々に変化させていくことになるかなと。
浮動小数点の誤差っぽい。
_Python の小数 - Qiita
0.1を10回足しても1にならないソレ。超基本的なことなのに、うっかり忘れてた。
とりあえず、倍率は整数値で持つことに。実際に使う際に 100.0 で割ってから使えばええやろ…。結局最後に割ってるから誤差は残ってるけど、見た目ではどうせ分からんし。
ただ、倍率を増減させる際に 1.2 とか 0.8333 を掛けてるので、結局はやっぱり誤差が溜まってきて、どこかでおかしくなるという…。実際のソレを作る際は、100%、200%、300%等、キリがいい倍率をテーブルで持っておいて、順々に変化させていくことになるかなと。
◎ qAppてのがあったのか。 :
マウスカーソル形状を変える際には、
_QtGui.QApplication.setOverrideCursor()
を使うのだけど。
今までは、
で、今頃になって「qApp というグローバル変数があるぜ」「QApplication.〜 とか書かなくて済むぜ」と知り。コレを使うと以下のように書けるらしい。
ちなみに、カーソル種類は、 _QCursor Class | Qt 4.8 を眺めればなんとなく分かるかなと。ページの真ん中あたりに、画像一覧が。
今までは、
global myApp myApp = QApplication(sys.argv)とかやっておいて、後から、
global myApp myApp.setOverrideCursor(Qt.ClosedHandCursor)として、カーソル形状を変えてたわけで。
で、今頃になって「qApp というグローバル変数があるぜ」「QApplication.〜 とか書かなくて済むぜ」と知り。コレを使うと以下のように書けるらしい。
qApp.setOverrideCursor(Qt.ClosedHandCursor)少し楽になった。
ちなみに、カーソル種類は、 _QCursor Class | Qt 4.8 を眺めればなんとなく分かるかなと。ページの真ん中あたりに、画像一覧が。
[ ツッコむ ]
#2 [prog][neta] ある範囲に数値を収めるソレ
変数が持ってる数値を、ある範囲内に収めたい時、今までこういう書き方をしてたのですけど。
分かりやすいからコレはコレで、とは思うものの、なんだかダサいよなと。もっと短く書けないものか。
と思ってたら、以下のような書き方を見かけて。
なるほど…。4行が1行で済むのだな…。
でも、分かりやすさがちょっと落ちるし、関数だかメソッドだかを2回呼ぶのもどうなの、という気も。ソースの見た目は短くなっても、内部処理的にはむしろ長くなってないか。
まあ、どっちでもいいか…。
if a < 0: a = 0 if a > 100: a = 100
分かりやすいからコレはコレで、とは思うものの、なんだかダサいよなと。もっと短く書けないものか。
と思ってたら、以下のような書き方を見かけて。
a = max(0, min(a, 3200))
なるほど…。4行が1行で済むのだな…。
でも、分かりやすさがちょっと落ちるし、関数だかメソッドだかを2回呼ぶのもどうなの、という気も。ソースの見た目は短くなっても、内部処理的にはむしろ長くなってないか。
まあ、どっちでもいいか…。
[ ツッコむ ]
#3 [nitijyou] 日記をアップロード
気付いたら、約2ヶ月ほど日記をアップロードしてなかった…。たしか、2016/09/03にアップしたまま忘れてたようで。ということで、今頃まとめてアップロード。
変な文章を書いてないか、読み返して修正するのが面倒臭くて…。いや、まあ、「読み返してコレかよ」と言われそうな気もするけど。
変な文章を書いてないか、読み返して修正するのが面倒臭くて…。いや、まあ、「読み返してコレかよ」と言われそうな気もするけど。
[ ツッコむ ]
2016/10/29(土) [n年前の日記]
#1 [python] Atomエディタにlinter-pylintをインストールしてみたり
Pythonスクリプトの文法チェックをしてくれる pylint というツールがあるのだけど。その pylint をAtomエディタから常時呼び出して結果を表示してくれる、Atom拡張の linter-pylint をインストールしてみたり。環境は Windows10 x64 + Atom 1.11.2。
_linter-pylint
_steelbrain/linter: A Base Linter with Cow Powers
動作には、python、pylint の他に、linter なるAtom拡張も必要らしい。
ちなみに、pylint のインストール方法は、 _2016/10/10の日記 にメモってある。手元のバージョンは以下。
linter と linter-pylint は、Atom の設定ウインドウ?からインストールできる。
これで、何か作業をするたび、下のほうに「この行の書き方、Python文化的にはおかしいぜ」と表示されるようになった。
_linter-pylint
_steelbrain/linter: A Base Linter with Cow Powers
動作には、python、pylint の他に、linter なるAtom拡張も必要らしい。
ちなみに、pylint のインストール方法は、 _2016/10/10の日記 にメモってある。手元のバージョンは以下。
> pylint --version pylint 1.6.4, astroid 1.4.8 Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec 5 2015, 20:32:19) [MSC v.1500 32 bit (Intel)]
linter と linter-pylint は、Atom の設定ウインドウ?からインストールできる。
- Ctrl+, を押すか、あるいは Ctrl+Shift+P を押してから「settings view: open」を選べば設定ウインドウ(settings)が開く。
- 左のほうで「Install」を選んで、「linter pylint」とか打ち込めば色々出てくるので、「linter」と「linter-pylint」をインストール。
これで、何か作業をするたび、下のほうに「この行の書き方、Python文化的にはおかしいぜ」と表示されるようになった。
◎ ちょっと厳し過ぎる。 :
これで、書き方がよろしくなさそうなところを教えてもらえるようになったけど。
自作スクリプトを開いてみたら、膨大な警告数で。「なんだこの書き方は!」と何百行も文句を言われてゲンナリしてきた。スクリプトの行数より、pylintが出力した警告のほうが、行数が多い。
例えば…。
_C0103 で、「1文字の変数名はダメだ!」と怒られる。「x = event.pos().x()」と書くだけで怒られちゃうのはキツイ。しかも pylint はグローバル変数相当を認識してくれないようで、そのへん全部「コレ、定数だろ? 定数は全部大文字で書かないとダメだろ!」と怒られる。いや、それ、定数じゃねえよ…。
W0401で、「ワイルドカード(*)で import しちゃダメだ!」と怒られる。「from PySide.QtCore import *」と書くだけで怒られちゃう。
W0602で、「global hoge って書かれてるけど hoge なんて用意されてねえよ!」と怒られる。そもそもグローバル変数相当が認識できてなくて全部定数扱いされてるものだから、global を指定しても全部無いものとして扱われるようで。
W0603で、「そもそも global を使うんじゃねえ!」と怒られる。いや…限界有るだろ…。何が何でもグローバル変数を使うな、と言うなら、各事例はこう書き直せ、てなサンプルでも提示してよ…。
_W0613 で、「使ってない引数があるぞ!」と怒られる。…PySideのWidgetの、事前に用意された、イベントを取る各メソッドの中で、与えられた引数を使わずに処理する場面もたまに出てくるわけで。どうしろと。
W0614で、「お前、ワイルドカード(*)で import したよな? コレとコレとコレとコレと…使ってねえだろ!」と怒られる。…そんなこと言われても。 _PySide.QtCore と _PySide.QtGui だけでもコレだけクラスがあるわけで、コレを全部人力で選別・列挙していけというのかと。どう考えても人力ではなくツール作って自動化すべきだけど、たぶん実際に記述していったらそこだけで長々とした記述になるだろうに。お前、Java になるつもりなの?
E1101が、ちょっとよく分からない。
自作スクリプトを開いてみたら、膨大な警告数で。「なんだこの書き方は!」と何百行も文句を言われてゲンナリしてきた。スクリプトの行数より、pylintが出力した警告のほうが、行数が多い。
例えば…。
_C0103 で、「1文字の変数名はダメだ!」と怒られる。「x = event.pos().x()」と書くだけで怒られちゃうのはキツイ。しかも pylint はグローバル変数相当を認識してくれないようで、そのへん全部「コレ、定数だろ? 定数は全部大文字で書かないとダメだろ!」と怒られる。いや、それ、定数じゃねえよ…。
W0401で、「ワイルドカード(*)で import しちゃダメだ!」と怒られる。「from PySide.QtCore import *」と書くだけで怒られちゃう。
W0602で、「global hoge って書かれてるけど hoge なんて用意されてねえよ!」と怒られる。そもそもグローバル変数相当が認識できてなくて全部定数扱いされてるものだから、global を指定しても全部無いものとして扱われるようで。
W0603で、「そもそも global を使うんじゃねえ!」と怒られる。いや…限界有るだろ…。何が何でもグローバル変数を使うな、と言うなら、各事例はこう書き直せ、てなサンプルでも提示してよ…。
_W0613 で、「使ってない引数があるぞ!」と怒られる。…PySideのWidgetの、事前に用意された、イベントを取る各メソッドの中で、与えられた引数を使わずに処理する場面もたまに出てくるわけで。どうしろと。
W0614で、「お前、ワイルドカード(*)で import したよな? コレとコレとコレとコレと…使ってねえだろ!」と怒られる。…そんなこと言われても。 _PySide.QtCore と _PySide.QtGui だけでもコレだけクラスがあるわけで、コレを全部人力で選別・列挙していけというのかと。どう考えても人力ではなくツール作って自動化すべきだけど、たぶん実際に記述していったらそこだけで長々とした記述になるだろうに。お前、Java になるつもりなの?
E1101が、ちょっとよく分からない。
zoomfit_btn.clicked.connect(self.zoom_fit)てな行で、「E1101 Instance of 'Signal' has no 'connect' member」と怒られてるけど…。 _All codes - PyLint Messages にも説明が無いし。何を怒ってるんだろう…?
◎ ある程度無視するように設定。 :
ということで、こういった警告だらけでは、かえって分かりにくくなりそうなので、無視することにする。
ソースの最初のほうに以下を追加。
このように書いておけば、指定した種類の警告を無視する状態になる。
でも、W0613 あたりは残しておきたいのだけど…。しかし常時表示されていては、警告を出す意味が無いというか、肝心なところを見逃すだろうし…。
そもそも PySide が「addItem()」みたいなメソッド名をつけてるのに、自分が書く部分では「add_item()」みたいな命名規則を強要されるのは…なんだかなあ…。
ソースの最初のほうに以下を追加。
# pylint: disable-msg=C0103,W0401,W0602,W0603,W0613,W0614,E1101あるいは以下。
# pylint: disable=C0103,W0401,W0602,W0603,W0613,W0614,E1101
このように書いておけば、指定した種類の警告を無視する状態になる。
でも、W0613 あたりは残しておきたいのだけど…。しかし常時表示されていては、警告を出す意味が無いというか、肝心なところを見逃すだろうし…。
そもそも PySide が「addItem()」みたいなメソッド名をつけてるのに、自分が書く部分では「add_item()」みたいな命名規則を強要されるのは…なんだかなあ…。
[ ツッコむ ]
#2 [nitijyou] 自転車で買い物に
コンビニとサンドラッグによって夜食や非常食を購入。天気が怪しかったのですぐに帰ってきた。
[ ツッコむ ]
2016/10/30(日) [n年前の日記]
#1 [prog] Atomエディタ上でpep8やflake8を試したり
昨日、Atomエディタ上でPythonの文法チェックだか命名規則チェックだかができる linter-pylint を使ったのだけど。どうも色々と警告内容が厳し過ぎるなと。もうちょっと優しいツールは無いものか。
ググってみたら、Pythonの文法チェックをしてくれるツールは、pylint の他にも pep8、pyflakes、flake8 等があるらしく。
_Pythonのスタイルガイドとそれを守るための各種Lint・解析ツール5種まとめ! - SideCI Blog
_Python の Lint (文法チェッカ) まとめ - flake8 + hacking を使う - - Qiita
_Pythonの主要なLint(pep8, pylint, flake8)の設定方法まとめ - Qiita
更に、Atomエディタ上でもそれらを利用できる拡張があるようで。
_linter-pep8
_linter-flake8
試しに、linter-pylint を無効にして、linter-pep8 を入れてみたら、それほどゲンナリする警告は言ってこなくて。コレならイイ感じだなと。
調子に乗って linter-flake8 も試用してみたところ、こちらはもうちょっと厳しく言ってくる模様。とりあえず、linter-flake8 をしばらく利用してみようかなと。
デフォルトでは、タイピングが止まると自動的に flake8 が動くようだけど。まだソースをガシガシ打ってる最中にも動いてしまうとガンガンエラー表示が出て鬱陶しいので、Ctrl + Shift + P → linter : toggle を選んで停止/再開を切り替えたほうがいい時も。
ググってみたら、Pythonの文法チェックをしてくれるツールは、pylint の他にも pep8、pyflakes、flake8 等があるらしく。
_Pythonのスタイルガイドとそれを守るための各種Lint・解析ツール5種まとめ! - SideCI Blog
_Python の Lint (文法チェッカ) まとめ - flake8 + hacking を使う - - Qiita
_Pythonの主要なLint(pep8, pylint, flake8)の設定方法まとめ - Qiita
更に、Atomエディタ上でもそれらを利用できる拡張があるようで。
_linter-pep8
_linter-flake8
試しに、linter-pylint を無効にして、linter-pep8 を入れてみたら、それほどゲンナリする警告は言ってこなくて。コレならイイ感じだなと。
調子に乗って linter-flake8 も試用してみたところ、こちらはもうちょっと厳しく言ってくる模様。とりあえず、linter-flake8 をしばらく利用してみようかなと。
デフォルトでは、タイピングが止まると自動的に flake8 が動くようだけど。まだソースをガシガシ打ってる最中にも動いてしまうとガンガンエラー表示が出て鬱陶しいので、Ctrl + Shift + P → linter : toggle を選んで停止/再開を切り替えたほうがいい時も。
◎ flake8のインストール。 :
flake8 のインストール方法は以下。
使い方は以下。
なのだけど、手元の環境(Windows10 x64 + Pyhon 2.7.11)で試したら、実行時にエラーが出て。
flake8 を含んでいるという hacking なるツールをインストールしてみたところ、そちらであれば flake8 の実行時にエラーが出なかった。
flake8-docstrings もインストールすべき、と説明してるページも見かけたけど。flake8-docstrings-1.0.2 は標準入力関係でバグがある、みたいな話も見かけて。代わりに、flake8-pep257 を入れるといいらしいけど…。
_Missing docstring in public module error D100 - Issue #170 - AtomLinter/linter-flake8
_Value I/O Error - Issue #86 - AtomLinter/linter-flake8
_Linter does not recognize same docstring issues as flake8 on command line - Issue #116 - AtomLinter/linter-flake8
とりあえず、flake8 のバージョンを確認。
pip install flake8 pip install flake8-pep257
使い方は以下。
flake8 スクリプトソース名
なのだけど、手元の環境(Windows10 x64 + Pyhon 2.7.11)で試したら、実行時にエラーが出て。
flake8 を含んでいるという hacking なるツールをインストールしてみたところ、そちらであれば flake8 の実行時にエラーが出なかった。
pip install hacking
flake8-docstrings もインストールすべき、と説明してるページも見かけたけど。flake8-docstrings-1.0.2 は標準入力関係でバグがある、みたいな話も見かけて。代わりに、flake8-pep257 を入れるといいらしいけど…。
_Missing docstring in public module error D100 - Issue #170 - AtomLinter/linter-flake8
_Value I/O Error - Issue #86 - AtomLinter/linter-flake8
_Linter does not recognize same docstring issues as flake8 on command line - Issue #116 - AtomLinter/linter-flake8
とりあえず、flake8 のバージョンを確認。
> flake8 --version 2.5.5 (pep8: 1.5.7, mccabe: 0.2.1, hacking.core: 0.0.1, ProxyChecker: 0.0.1, flake8-pep257: 1.0.5, pyflakes: 0.8.1) CPython 2.7.11 on Windows
◎ flake8の一部の警告を無効にする方法。 :
flake8 は、一部の警告内容が矛盾するそうで。「関数宣言と docstring の間には空行が必要だぞ!」と「関数宣言と docstring の間には空行入れたらダメだぞ!」がぶつかるとかなんとか。ということで、やはりいくつかは常時警告を無視する設定が必要になるようで。
方法は、スクリプトと同じフォルダに、.flake8 というファイルを作って、例えば以下のような内容を書く。
あるいは、スクリプトソース内の警告が出てる行で、
_Configuring Flake8 - flake8 3.1.0.dev0 documentation には「~/.flake8 を書けば全体設定として使われる」と書いてあるように見えるのだけど。手元の環境で試したら、環境変数HOMEで設定してあるディレクトリに置いても、C:\Users\ユーザアカウント名\ 以下に置いても、設定が反映されなかった。一体どこに置けば反映されるんだ…。
むむ。どうやら、マイドキュメント\.flake8 なら反映されるっぽい。何故にどうしてそんな場所に…。
方法は、スクリプトと同じフォルダに、.flake8 というファイルを作って、例えば以下のような内容を書く。
[flake8] ignore = D211 max-line-length = 79
- ignore = Dxxx,Dxxx 等を書くことで、該当種類の警告が出なくなる。
- max-line-length = 79 と書くことで、1行は79文字まで、と伝える。
あるいは、スクリプトソース内の警告が出てる行で、
from PySide.QtCore import * # NOQAといった感じで行の最後のあたりに「# NOQA」を書く。ちなみに、このコメントの前には2つ以上のスペースが必要。
_Configuring Flake8 - flake8 3.1.0.dev0 documentation には「~/.flake8 を書けば全体設定として使われる」と書いてあるように見えるのだけど。手元の環境で試したら、環境変数HOMEで設定してあるディレクトリに置いても、C:\Users\ユーザアカウント名\ 以下に置いても、設定が反映されなかった。一体どこに置けば反映されるんだ…。
むむ。どうやら、マイドキュメント\.flake8 なら反映されるっぽい。何故にどうしてそんな場所に…。
[ ツッコむ ]
#2 [python] PySideでファイルオープンダイアログを表示したり等
PySideをまだ勉強中。
◎ ファイルオープンダイアログとファイル保存ダイアログ。 :
こんな感じで書けば、ファイルオープンダイアログ、ファイル保存ダイアログが開くらしい。
返り値を、fpath, _ で受け取ってるサンプルがあって、「『_』って何だ?」と思ったけど。タプルの返り値を受け取る際に、使わない値は「_」で受け取って捨ててしまう、みたいな何かがあるらしい。
def show_open_dialog(self): u"""ファイルオープンダイアログを表示.""" filter = "Image Files (*.png *.bmp *.jpg *.jpeg)" fpath, _ = QFileDialog.getOpenFileName(self, "Open File", self.cur_dir, filter) if fpath: self.gview.load_canvas_image(fpath) else: # cancel pass def show_save_dialog(self): u"""ファイル保存ダイアログを表示.""" filter = "Image Files (*.png)" fpath, _ = QFileDialog.getSaveFileName(self, "Save File", self.cur_dir, filter) if fpath: self.gview.scene().save_canvas(fpath) else: # cancel passキャンセルボタンが押された時は何が返ってくるのか分からなかったけど、ひょっとすると空文字列("") が返ってくるのかもしれない。
返り値を、fpath, _ で受け取ってるサンプルがあって、「『_』って何だ?」と思ったけど。タプルの返り値を受け取る際に、使わない値は「_」で受け取って捨ててしまう、みたいな何かがあるらしい。
◎ QPixmapのファイル保存。 :
PySideで、画像の描画その他に使う QPixmap を、画像ファイルとして保存するのは、save() を使えばいいらしい。
_QPixmap - PySide v1.0.7 documentation
def save_canvas(self, fpath): u"""キャンバスを画像ファイルとして保存.""" self.canvas_pixmap.save(fpath, "PNG")引数として、ファイルパス、画像フォーマット、圧縮率を渡す模様。圧縮率の指定を省略するとデフォルトの圧縮率で保存される、と書いてあるように見えた。
_QPixmap - PySide v1.0.7 documentation
◎ QPixmapの指定座標の色情報を取得。 :
QPixmap の指定座標からRGBA値を取得したいと思ったのだけど、QPixmap からは取得できないようで。ただし、toImage() を使って、一旦 QImage に変換してやれば、long値として取得できる模様。
取得したlong値をRGBAに変換するなら、QColor が使える。QColor.setRgba( long値 ) で long値を渡して設定してやれば、後は red()、green()、blue()、alpha() で、R,G,B,Aの値を取得できる。
long値はARGBの順で並んでるようにも見えたから、シフトとマスクで取り出せるんじゃないのとも思ったけど、仕様変更された時の対処や、OSによって並びが異なる可能性も考えると、面倒でも(?)、QColor を使ったほうがいいのかもしれない。
def get_rgb_from_canvas(self, pos): u"""キャンバスの指定座標からRGBA値 (r,g,b,a) を取得.""" x = int(pos.x()) y = int(pos.y()) pm = self.canvas_pixmap w, h = pm.width(), pm.height() if x < 0 or x >= w or y < 0 or y >= h: return None argb_long = pm.toImage().pixel(x, y) argb = QColor() argb.setRgba(argb_long) r = argb.red() g = argb.green() b = argb.blue() a = argb.alpha() return (r, g, b, a)
取得したlong値をRGBAに変換するなら、QColor が使える。QColor.setRgba( long値 ) で long値を渡して設定してやれば、後は red()、green()、blue()、alpha() で、R,G,B,Aの値を取得できる。
long値はARGBの順で並んでるようにも見えたから、シフトとマスクで取り出せるんじゃないのとも思ったけど、仕様変更された時の対処や、OSによって並びが異なる可能性も考えると、面倒でも(?)、QColor を使ったほうがいいのかもしれない。
[ ツッコむ ]
2016/10/31(月) [n年前の日記]
#1 [python] PySideのアレコレをメモ
PySide関係のアレコレをメモ。
◎ ボタンに画像を割り当てたい。 :
QPushButton に画像を割り当てて表示したい。
_user interface - Python QPushButton setIcon: put icon on button - Stack Overflow
_QPushButtonクラス - yu00’s blog
btn_pixmap = QPixmap(24, 24) btn_pixmap.fill(QColor(r, g, b)) btn.setIcon(QIcon(btn_pixmap)) btn.setIconSize(btn_pixmap.rect().size()) btn.update()setIcon() で QIcon(QPixmap) を渡してやれば画像を設定できるようで。一応その次に setIconSize() を呼んでアイコンサイズも設定してるけど、必要なのかどうか…。
_user interface - Python QPushButton setIcon: put icon on button - Stack Overflow
_QPushButtonクラス - yu00’s blog
◎ 色選択ダイアログを表示。 :
色を選択したい。
_QColorDialog - PySide v1.0.7 documentation
_QColor - PySide v1.0.7 documentation
_Pyside を使ったカラーピッカー(色選択ツール)のサンプル - Qiita
_Dialogs in PySide
color = QColorDialog.getColor(Qt.green, self) if color.isValid(): r = color.red() g = color.green() b = color.blue() self.set_rgb((r, g, b))QColorDialog.getColor(初期色, 親) を呼べば、色選択だかカラーピッカーだか、そういう感じの例のダイアログが表示されるらしい。返り値は QColor。QColor.isValid() を呼んで False だったらキャンセルされたと分かる。
_QColorDialog - PySide v1.0.7 documentation
_QColor - PySide v1.0.7 documentation
_Pyside を使ったカラーピッカー(色選択ツール)のサンプル - Qiita
_Dialogs in PySide
[ ツッコむ ]
以上、31 日分です。
wxPython始めたばかりなんですが、ubuntuのpython3.6.8でウインドウ内がちらつく版。でもちらつかないですね。