2014/06/01(日) [n年前の日記]
#1 [cg_tools] Drawgraphic 2を購入してみた
Drawgraphic 2 は、SOURCENEXTから販売されてる、1,980円のドローソフト。1000円割引券とやらを貰えるキャンペーン?があったので購入してみたり。前々から気になってたけど踏ん切りがつかなかったわけで。
感想というか、結論を先に書くけど。Drawgraphic 2 は、ドローソフトのふりをしている、ビットマップ画像編集ソフトじゃないかなと…。買うんじゃなかった。騙された。
感想というか、結論を先に書くけど。Drawgraphic 2 は、ドローソフトのふりをしている、ビットマップ画像編集ソフトじゃないかなと…。買うんじゃなかった。騙された。
◎ 操作時の反応。 :
操作時の反応は、結構キビキビしてる印象。
- Inkscape のように、何をするにしてもワンテンポ遅れる、ということはなく。
- LibreOffice Draw のように、何かオブジェクトを追加するたびにモードが変わってしまう、てなこともなく。
◎ 問題点。 :
数時間触ってたら、問題点がポロポロと。
ベクターデータ(eps)として保存したつもりが、実は中身はビットマップ画像でした! ババァーン! てのは、さすがに酷過ぎると思いました。お前、本当にドローソフトなの?
でもまあ、巨大なビットマップ画像として保存して、別のソフトで縮小処理をして、とかしてやれば使い道があるかも…と思ったら 342 dpi が指定できる最大値のようで。ダメだこりゃ。さすがソースネクスト。いや、メンテナンスしてるのはファンファーレだと思いますけど。
まあ、元が古いソフトらしいので、仕方ないのかも。値段も安いし。
- png等、ビットマップ画像で保存する際、アンチエイリアスをかけてくれない。ドローソフトのくせして、出力結果までジャギってるのは酷い。
- 画像として保存する際に、背景を透明にできない。必ず、何かの色と合成されてしまう。これではアルファチャンネルを持った素材画像を作れない。
- 半透明塗りが無い。と思う。たぶん。
- 保存ファイル(.fda)をダブルクリックしても開けない。「プログラムにコマンドを送信しているときに、エラーが発生しました。」とエラーメッセージが表示される。有償ソフトなのに、こういうレベルで不具合が出るとゲンナリする…。
- ビットマップ画像フォーマットは、そこそこの種類に対応してるのに、ベクターデータフォーマットへの対応数が少ない。ドローソフトなのに…。例えば、svg未対応なあたりは、今時厳しい気がする。
- pdf保存ができる時と、できない時がある。特定の図形が入っていたり、特定の操作をすると、保存できなくなる?
- epsで保存してみたら、ベクターデータのはずなのに、ファイルサイズが数十MBもあった。そして、GIMP や Inkscape で該当epsを開いてもアンチエイリアスがかかっていない。要するに、このソフト、レンダリングしたビットマップ画像をそのまま eps 内に突っ込んで「eps保存しました」と嘯いてる。
- emfで保存して Inkscape で読み込んでみたら、縦横比はおかしいわ、線の変更等もまともにできないわで。(もっとも、これは Inkscape のほうにも原因がありそうな気もするけど…)
ベクターデータ(eps)として保存したつもりが、実は中身はビットマップ画像でした! ババァーン! てのは、さすがに酷過ぎると思いました。お前、本当にドローソフトなの?
でもまあ、巨大なビットマップ画像として保存して、別のソフトで縮小処理をして、とかしてやれば使い道があるかも…と思ったら 342 dpi が指定できる最大値のようで。ダメだこりゃ。さすがソースネクスト。いや、メンテナンスしてるのはファンファーレだと思いますけど。
まあ、元が古いソフトらしいので、仕方ないのかも。値段も安いし。
◎ 起動時にエラーが出る問題。 :
.fda をダブルクリックすると、「プログラムにコマンドを送信しているときに、エラーが発生しました。」とエラーメッセージが表示されて開けない件だけど。解決できないか四苦八苦。ちなみに環境は Windows7 x64。
DOS窓で以下を打った。
とりあえず、管理者権限でDOS窓を開いて、以下のように変更。
ダメだった。相変わらず同じエラーが出る。ただし、以前はファイルすら開けなかったのが、今回はエラーメッセージが出ている裏で、一応ファイルを開いている状態になった。しかし、まだ何か設定がおかしいのだろう…。
よく分からないのが、以下のようにDOS窓から打ち込むとエラーが出ないこと。
また、「送る」フォルダを開いて、 *1 中に DrawGr2.exe のショートカットを作って、「送る」から .fda を開いてみた。これもエラーが出ない。ということは、指定は間違ってないと思えるわけで。であれば、エクスプローラ側の設定がおかしいんだろう。たぶん。
ウチの環境でのみ起きる問題なのかなと思ったけれど、Amazonのレビューでも同様の報告を見かけた。
とりあえず、 _FileTypesMan という、関連付けを変更できるアプリで、.fda に割り当てられていたアクションを弄ってみたり。
それにしても、どうしてこういうことになるんだろう…? DDEとやらを使わないと、何か別の問題が起きるのかな。
DOS窓で以下を打った。
> assoc .fda .fda=Scribe.Designing > ftype Scribe.Designing Scribe.Designing="C:\Program Files (x86)\SOURCENEXT\DrawGraphic2\DrawGr2.exe" /dde「/dde」が指定されてるあたりが怪しい。というのも、件のエラーメッセージでググると、えてして Excel で同様の問題が起きる事例に遭遇するわけで。そこでも DDE (Dynamic Data Exchange) が絡んでるらしくて。
とりあえず、管理者権限でDOS窓を開いて、以下のように変更。
> ftype Scribe.Designing="C:\Program Files (x86)\SOURCENEXT\DrawGraphic2\DrawGr2.exe" "%1"/dde を使わずに、"%1" でファイルのパスを渡すように、関連付けを変更、とでも言えばいいのかな…。
ダメだった。相変わらず同じエラーが出る。ただし、以前はファイルすら開けなかったのが、今回はエラーメッセージが出ている裏で、一応ファイルを開いている状態になった。しかし、まだ何か設定がおかしいのだろう…。
よく分からないのが、以下のようにDOS窓から打ち込むとエラーが出ないこと。
"C:\Program Files (x86)\SOURCENEXT\DrawGraphic2\DrawGr2.exe" "hoge.fda"
また、「送る」フォルダを開いて、 *1 中に DrawGr2.exe のショートカットを作って、「送る」から .fda を開いてみた。これもエラーが出ない。ということは、指定は間違ってないと思えるわけで。であれば、エクスプローラ側の設定がおかしいんだろう。たぶん。
ウチの環境でのみ起きる問題なのかなと思ったけれど、Amazonのレビューでも同様の報告を見かけた。
専用形式で保存したファイルをダブルクリックで起動させるとエラーして開かない。でもそのファイルをショートカットアイコンへドロップするとちゃんとその保存したファイルが開く・・・どうやらウチだけじゃないな。
とりあえず、 _FileTypesMan という、関連付けを変更できるアプリで、.fda に割り当てられていたアクションを弄ってみたり。
- 「DrawGraphicで開く(&O)」「open」の2つを無効にする。該当項目を右クリックして「アクションを編集」→ 無効にチェックを入れる。
- アクションを新規作成。「参照」をクリックして、DrawGr2.exe を指定。自動で「"%1"」も追加される。
- 新しく作ったアクションを「既定のアクション」に設定。
それにしても、どうしてこういうことになるんだろう…? DDEとやらを使わないと、何か別の問題が起きるのかな。
◎ 半透明機能は存在してた。 :
オブジェクトを選択した状態で、書式 → 透明度、を選んだら半透明にすることができた。機能を割り当てたツールボタンが見当たらないし、右クリックしてもメニューに無かったものだから、機能として持ってないのだなと勘違いしちゃいました…。
たぶんコレ、後になってから機能をつけたか、当時は実験的機能だったりして、UIへの反映が放置されたんじゃないかな…。
しかしやっぱり、背景を透明にして、ビットマップ画像保存をする方法が分からず。まあ、どうせアンチエイリアスがかからないから、別のソフトで開いて保存したほうがいいんだろうけど。
たぶんコレ、後になってから機能をつけたか、当時は実験的機能だったりして、UIへの反映が放置されたんじゃないかな…。
しかしやっぱり、背景を透明にして、ビットマップ画像保存をする方法が分からず。まあ、どうせアンチエイリアスがかからないから、別のソフトで開いて保存したほうがいいんだろうけど。
*1: スタートボタン → shell:sendTo で、「送る」フォルダは開ける。
この記事へのツッコミ
[ ツッコミを読む(1) | ツッコむ ]
2014/06/02(月) [n年前の日記]
#1 [dxruby][ruby][cg_tools] DXRubyとcairoでswfのシェイプを描画してみる実験
_2014/05/29
に、DXRubyでswfのシェイプを描画する実験をしたのだけど。あまりにも処理が遅い上に、描画も汚くてしょんぼりだったわけですが。
_cairo
と組み合わせて使えば、もっと速く、もっと綺麗にできるんじゃないかと思えたので試してみたり。
こんな感じになりました。右側が、cairoを使って描画した結果。 さすがに美しい…。cairo、凄いなあ。
ソースは以下。
_shapeparse_with_cairo.rb
データ一式も置いときます。
_swf_shape_parse_20140602.zip (434KB)
アンチエイリアスをかけながら描画してくれるライブラリなだけあって、さすがに綺麗。しかも、CPU負荷率を見る限りでは、自前で線描画や多角形塗りをするよりも、40倍ぐらい速くなりました。
それでもやっぱり、リアルタイムに描画するのは速度的に無理なので、実用にはならないのですけど。どう考えても、最初からレンダリング済みのビットマップ画像を用意しておくべきだなと。
更に、このやり方、現状ではかなりトホホな点があって。cairo で描画した後、結果を一旦 pngファイルでHDDに保存して、それを DXRuby の Image にロードし直していたりするわけで。
これがもし、cairo の Surface から、pngファイルとして書き出すべきバイナリデータを直接取得できれば…。あるいは、Surface内容をRGBAの配列で取得できれば、わざわざクソ遅いHDDにアクセスしなくても済むのですけど。残念ながら、そのようなメソッドは見つからなくて。
それにしても、swfのシェイプをこうして描画できるということは、svgも描画できたりするのかしら。たしか、svg を解析・描画する Rubyライブラリも存在していたはずなので、ちと試してみたいところ。
こんな感じになりました。右側が、cairoを使って描画した結果。 さすがに美しい…。cairo、凄いなあ。
ソースは以下。
_shapeparse_with_cairo.rb
require 'nokogiri' require 'dxruby' require 'cairo' require 'tempfile' require_relative 'bezierdraw' # swfのシェイプを解析してImageに描画するクラス(cairo使用版) # class ShapeParse DBG = false DBG2 = true TWIP = 20.0 attr_accessor :id attr_accessor :width attr_accessor :left attr_accessor :top attr_accessor :height attr_accessor :image attr_accessor :draw_data attr_accessor :clip_enable attr_accessor :surface attr_accessor :context def initialize(node, clip_enable = true) self.clip_enable = clip_enable self.id = node["objectID"].to_i puts "id[#{self.id}] #{node.name}" if DBG n = node.at(".//bounds/Rectangle") self.left = (n["left"].to_f / ShapeParse::TWIP).to_i self.top = (n["top"].to_f / ShapeParse::TWIP).to_i self.width = (n["right"].to_f / ShapeParse::TWIP).to_i self.height = (n["bottom"].to_f / ShapeParse::TWIP).to_i puts "size : (x,y)=#{self.left},#{self.top} (w,h)=#{self.width},#{self.height}" if DBG self.width = Window.width if self.width < Window.width self.height = Window.height if self.height < Window.height x0, y0 = 0, 0 x1, y1 = 0, 0 x2, y2 = 0, 0 f0_enable = true f1_enable = true l_enable = true fc = [[0, 0, 0, 0], [0, 0, 0, 0]] lc = [0, 0, 0, 0] lwidth = ShapeParse::TWIP lines = [] self.draw_data = [] n = node.at(".//shapes/Shape/edges").child while n != nil case n.name when "ShapeSetup" unless lines.empty? save_draw_data(lines, f0_enable, f1_enable, l_enable, lwidth, fc[0], fc[1], lc) lines = [] end s = "#{n.name} " x0 = n["x"].to_f if n.key?("x") y0 = n["y"].to_f if n.key?("y") f0_enable = (n["fillStyle0"] == "1")? true : false f1_enable = (n["fillStyle1"] == "1")? true : false l_enable = (n["lineStyle"] == "1")? true : false if false s += "(x,y)=#{x0/TWIP}, #{y0/TWIP} (" s += (f0_enable)? "f0 " : " " s += (f1_enable)? "f1 " : " " s += (l_enable)? "l" : " " s += ")" puts s end n.xpath(".//fillStyles").each do |nn| nn.xpath(".//Solid/color/Color").each_with_index do |m, i| fc[i] = get_color(m) end end n.xpath(".//lineStyles").each do |nn| nn.xpath(".//LineStyle").each do |m| lwidth = m["width"].to_i if m.key?("width") m.xpath(".//color//Color").each do |c| lc = get_color(c) end end end if n.key?("x") and n.key?("y") lines.push([x0, y0]) end when "CurveTo" # 二次ベジェ曲線 x1 = x0 + n["x1"].to_f y1 = y0 + n["y1"].to_f x2 = x1 + n["x2"].to_f y2 = y1 + n["y2"].to_f lst = BezierDraw.calc(x0, y0, x1, y1, x2, y2) lines.concat(lst.slice(1..-1)) x0 = x2 y0 = y2 when "LineTo" # 直線 x1 = x0 + n["x"].to_f y1 = y0 + n["y"].to_f lines.push([x1, y1]) x0 = x1 y0 = y1 else puts "!! Unknown Tag : #{n.name}" end n = n.next end draw(false) end # 色配列を取得 # # @param [Object] node 「Color」ノード # @return [Array] A,R,G,Bが入った配列 # def get_color(node) col = [255, 0, 0, 0] # ARGB ["alpha", "red", "green", "blue"].each_with_index do |s,i| col[i] = node[s].to_f if node.key?(s) end return col end # 描画用の直線データを記録 # # @param [Array] lines 直線データ配列 # @param [Boolean] fe0 塗り潰し0をするか否か # @param [Boolean] fe1 塗り潰し1をするか否か # @param [Boolean] le 線を描くか否か # @param [Number] lw 線幅 # @param [Array] fc0 塗り潰し0の色配列 # @param [Array] fc1 塗り潰し1の色配列 # @param [Array] lc1 線描画の色配列 # def save_draw_data(lines, fe0, fe1, le, lw, fc0, fc1, lc) np = [] ox, oy = nil, nil lines.each do |p| x, y = p x /= TWIP y /= TWIP np.push([x, y]) if x != ox or y != oy ox, oy = x, y end # 記録 self.draw_data.push([np, fe0, fe1, le, lw, fc0.dup, fc1.dup, lc.dup]) end # Imageオブジェクトに描画 # # @param [Boolean] clear_enable trueならImageをクリアしてから描画 # def draw(clear_enable = true, scale_x = 1.0, scale_y = 1.0) # self.image.clear if clear_enable # cairoのサーフェスを確保 self.surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, self.width, self.height) self.context = Cairo::Context.new(surface) self.draw_data.each do |d| p, fe0, fe1, le, lw, fc0, fc1, lc = d np = [] p.each { |q| np.push([q[0] * scale_x, q[1] * scale_y]) } draw_line(self.context, np, fe0, fe1, le, lw, fc0, fc1, lc) end # 一時ファイル作成 temp = Tempfile.new(['shapeparse', '.png']) temp.binmode temp.close # pngファイルに出力 self.surface.write_to_png(temp.path) # DXRubyで読み込み self.image = Image.load(temp.path) temp.close(true) end # 色配列の数値を変換して返す # # @note 255までの値を持っていた色配列を、1.0までの値に変換する # # @param [Array] c 色配列ARGB # @return [Array] 色配列RGBA # def get_rgba(c) r = [] c.each do |n| m = n / 255.0 m = 0.0 if m < 0.0 m = 1.0 if m > 1.0 r.push(m) end return r[1], r[2], r[3], r[0] end # 多角形を描画 # # @param [Object] ct cairoのcontext # @param [Array] p 頂点座標が入った配列。 # @param [Boolean] f0_enable trueなら塗り潰し有、falseなら塗り潰し無 # @param [Boolean] f1_enable trueなら塗り潰し有、falseなら塗り潰し無 # @param [Boolean] l_enable trueなら線を描く、falseなら線を描かない # @param [Number] lwidth 線幅 # @param [Array] fc0 色配列。A,R,G,B # @param [Array] fc1 色配列。A,R,G,B # @param [Array] lc 色配列。A,R,G,B # def draw_line(ct, p, f0_enable, f1_enable, l_enable, lwidth, fc0, fc1, lc) return if (!f0_enable and !l_enable) ct.set_line_join(Cairo::LineJoin::ROUND) # 結合点の種類を指定 ct.set_line_cap(Cairo::LineCap::ROUND) # 線の終点の種類を指定 lw = lwidth / TWIP lw = 1.0 if lw < 1.0 # swfは1.0より細い線幅も1.0の線幅で描画するらしい ct.set_line_width(lw) # 線幅を指定 # 塗る色を指定 if f0_enable ct.set_source_rgba(get_rgba(fc0)) else ct.set_source_rgba(get_rgba(lc)) end x0 , y0 = p[0] ct.move_to(x0, y0) 1.step(p.size - 1, 1) do |i| ct.line_to(p[i][0], p[i][1]) end if f0_enable # 塗り潰し ct.fill_preserve end # 線を描画 ct.set_source_rgba(get_rgba(lc)) if l_enable ct.stroke end end if $0 == __FILE__ # ---------------------------------------- # 動作テスト font = Font.new(14) # swfmillで swf → xml変換したxmlを解析 # infile = "swfdata/test_pdr1.xml" infile = "swfdata/test_pdr2.xml" doc = Nokogiri::XML(File.open(infile)) {|cfg| cfg.noblanks} objs = Hash.new doc.xpath("//DefineShape3").each do |node| pdr = ShapeParse.new(node, false) # ベクターデータを解析して画像化 objs[pdr.id] = pdr end redraw_fg = false ang = 0 scale = 1.0 Window.bgcolor = [0, 190, 118] Window.fps = 60 # メインループ Window.loop do break if Input.keyPush?(K_ESCAPE) # Rキー押しでスケールを変えて再描画 redraw_fg = (Input.keyDown?(K_R))? true : false objs.each_value do |o| # ベクターデータを再描画できなくもないが、遅くて実用にならない o.draw(true, scale, scale) if redraw_fg Window.draw(0, 0, o.image) end s = "#{Window.real_fps} FPS / CPU: #{Window.getLoad.to_i}%" Window.drawFont(4, 4, s, font) ang += 10 scale = Math.cos(ang * Math::PI / 180.0) + 1.5 end end
データ一式も置いときます。
_swf_shape_parse_20140602.zip (434KB)
アンチエイリアスをかけながら描画してくれるライブラリなだけあって、さすがに綺麗。しかも、CPU負荷率を見る限りでは、自前で線描画や多角形塗りをするよりも、40倍ぐらい速くなりました。
それでもやっぱり、リアルタイムに描画するのは速度的に無理なので、実用にはならないのですけど。どう考えても、最初からレンダリング済みのビットマップ画像を用意しておくべきだなと。
更に、このやり方、現状ではかなりトホホな点があって。cairo で描画した後、結果を一旦 pngファイルでHDDに保存して、それを DXRuby の Image にロードし直していたりするわけで。
これがもし、cairo の Surface から、pngファイルとして書き出すべきバイナリデータを直接取得できれば…。あるいは、Surface内容をRGBAの配列で取得できれば、わざわざクソ遅いHDDにアクセスしなくても済むのですけど。残念ながら、そのようなメソッドは見つからなくて。
それにしても、swfのシェイプをこうして描画できるということは、svgも描画できたりするのかしら。たしか、svg を解析・描画する Rubyライブラリも存在していたはずなので、ちと試してみたいところ。
◎ メモリマップドファイルは使えないかな。 :
メモリ上に仮想ファイルシステムの類でも作れたら、HDDにアクセスしなくても済むんじゃないかと思えてきたのだけど。そういうことができるライブラリってあるのかしら。
_メモリマップトファイル - Wikipedia には、
_Rubyist Magazine - Ruby Library Report 【第 4 回】 Win32Utils
_djberg96/win32-mmap - GitHub
もしかして、Windows + Ruby なら、win32-mmap てのが使える…?
_メモリマップトファイル - Wikipedia には、
Ruby : Mmap というgem(ライブラリ)があり、メモリマップトファイルを実装している。という記述があったのだけど。
_Rubyist Magazine - Ruby Library Report 【第 4 回】 Win32Utils
_djberg96/win32-mmap - GitHub
もしかして、Windows + Ruby なら、win32-mmap てのが使える…?
◎ DXRuby + cairo の組み合わせ。 :
cairo の使い方については、
_rcairo 事始め - takihiro日記
を参考にさせてもらって試していたのですけど。せっかくだから、DXRuby で結果表示をするサンプルも置いときます。
_test_cairo1.rb
以下のような感じになります。
_test_cairo1.rb
# cairo のテスト # # 以下を参考にしました。 # # rcairo 事始め - takihiro日記 # http://d.hatena.ne.jp/takihiro/20100331/1269992290 require 'cairo' require 'dxruby' require 'tempfile' w, h = 640 - 32, 480 - 32 surface = Cairo::ImageSurface.new(w, h) context = Cairo::Context.new(surface) # 背景色を指定 context.set_source_rgba(0, 0, 0, 0) # 透明 context.rectangle(0, 0, w, h) context.fill # 四角を書く context.set_source_color(Cairo::Color::RED) x, y, rw, rh = 20, 20, w / 2, h / 2 context.rectangle(x, y, rw, rh) context.fill_preserve context.set_source_color(Cairo::Color::BLACK) context.stroke # 円を書く context.set_source_color(Cairo::Color::GREEN) r = h / 3 x, y, rw, rh = 100, 30, 50, 50 context.arc(w/2, h/2, r, 0, 2 * Math::PI) context.fill_preserve context.set_source_color(Cairo::Color::BLUE) context.stroke # 多角形 context.set_source_color(Cairo::Color::YELLOW) context.move_to(30, 30) context.line_to(20, 60) context.line_to(40, 80) context.line_to(80, 40) context.line_to(60, 30) context.line_to(30, 30) context.fill_preserve context.set_source_color(Cairo::Color::PURPLE) context.stroke # 重ねる画像を設定 surface2 = Cairo::ImageSurface.from_png('sample2.png') context.set_source(surface2, w - surface2.width - 24, h - surface2.height - 24) context.paint # 文字配置 context.set_source_rgb(255, 255, 255) context.font_size = 26 context.move_to(10, 150) context.show_text('文字') # フォントを指定してないので文字化けする context.move_to(10, 180) context.select_font_face('メイリオ', 0, 0) context.show_text('メイリオフォント') # ---------------------------------------- # 一時ファイルを作成 temp = Tempfile.new(['test', '.png']) temp.binmode temp.close # pngファイルに出力 surface.write_to_png(temp.path) # DXRubyで読み込み img = Image.load(temp.path) temp.close(true) # DXRubyで表示 Window.bgcolor = C_BLUE Window.loop do break if Input.keyPush?(K_ESCAPE) Window.draw(16, 16, img) end
以下のような感じになります。
[ ツッコむ ]
#2 [cg_tools] フリーで使えるドローソフトを試用してみたり
Drawgraphic 2 がちょっとアレなソフトだったので、もしかするとフリーソフトのほうがグッドだったりしないのかなと疑念が湧いて。ググっていたら、いくつかのドローソフトが気になったので、それぞれ試用してみたりして。
環境は、Windows7 x64。
ちなみに、自分、普段は、 _Inkscape 0.48.2 や _LibreOffice Draw を使ってます。
環境は、Windows7 x64。
ちなみに、自分、普段は、 _Inkscape 0.48.2 や _LibreOffice Draw を使ってます。
◎ Dynamic Draw を試用。 :
_Dynamic Draw
Drawgraphic 2 との比較だけど。
ただ、操作性については若干難有り。
そんな感じで、操作性・作業のしやすさに関しては、Drawgraphic 2 > Dynamic Draw > LibreOffice Draw、という印象。
他に気づいた点をメモ。
Drawgraphic 2 との比較だけど。
- ビットマップ画像保存時、背景を透明にして出力できる。(ファイル → 選択部品の画像をエクスポート、を選べばビットマップ画像として保存できる)
- ビットマップ画像保存時、アンチエイリアスを有効にして出力できる。
- svgエクスポートにも対応。
- 一瞬で起動する。爆速。
ただ、操作性については若干難有り。
- LibreOffice Draw ほど酷くはないけど、Drawgraphic 2 に比べると、色や線幅の指定が時々元に戻ってしまうので、連続での作業がしづらい。
- メニューの表記が独特・Windowsの一般的なアプリから乖離していて、パッと見で「難しそう」と感じてしまう。ショートカットキーの割り当てを強調して伝えたいのは理解できるけど…。「F.ファイル E.編集 V.表示」より、「ファイル(F) 編集(E) 表示(V)」のほうが良いのでは…。
- アイコンが全て白黒なので、ツールボタンの場所や定義が把握しにくい。昔の*NIX系ソフトでよく見かけた、ストイックなノリに近いというか。
そんな感じで、操作性・作業のしやすさに関しては、Drawgraphic 2 > Dynamic Draw > LibreOffice Draw、という印象。
他に気づいた点をメモ。
- 半透明塗りは無いらしい。
- アンチエイリアス有効、かつ、背景を透明にしてビットマップ画像を出力すると、境界が汚くなる。いわゆるフリンジ?が出ちゃう。
◎ グリッドをどの階層に描画するかという問題。 :
Drawgraphic 2 も、Dynamic Draw も、図形を塗り潰すとグリッドが隠れてしまって、途端に作業しづらくなるのだけど。
これが Inkscape なら、図形を塗り潰してもグリッド線が上に表示され続けるので、作業が快適だなと気付いたり。その代り(?)、Inkscape は全てがモッサリですが。
Drawgraphic 2 は、図形のアウトラインだけ描画するモード(ワイヤーフレーム表示)があるので、グリッドに頼った作業をするのであれば、そのモードで表示してしまうのもアリかなと。
たしか、FREEHAND にも簡易描画モードがあったような気がする。昔のドローソフトは、PCスペックが低くても作業できるようにするために、描画処理を軽くする仕様も求められたのだろうけど。結果的に、グリッドに頼った作業をする時も、回避策が存在している状態になったと言えるのかも。
Dynamic Draw には、アウトラインだけ描画するモードも、グリッドを最前面に描画する設定も、どちらも無いように見えました。
これが Inkscape なら、図形を塗り潰してもグリッド線が上に表示され続けるので、作業が快適だなと気付いたり。その代り(?)、Inkscape は全てがモッサリですが。
Drawgraphic 2 は、図形のアウトラインだけ描画するモード(ワイヤーフレーム表示)があるので、グリッドに頼った作業をするのであれば、そのモードで表示してしまうのもアリかなと。
たしか、FREEHAND にも簡易描画モードがあったような気がする。昔のドローソフトは、PCスペックが低くても作業できるようにするために、描画処理を軽くする仕様も求められたのだろうけど。結果的に、グリッドに頼った作業をする時も、回避策が存在している状態になったと言えるのかも。
Dynamic Draw には、アウトラインだけ描画するモードも、グリッドを最前面に描画する設定も、どちらも無いように見えました。
◎ ParaDrawを試用。 :
_ParaDraw
ただ、ベクターデータとして swf か pdr でしか保存できないあたりが厳しい…。
- グリッド表示・吸着機能がある。かつ、図形を塗り潰してもグリッドは手前に表示されてるので作業しやすい。
- ビットマップ画像保存時は背景を透明にすることもできる。
- アンチエイリアスもかかってる。
ただ、ベクターデータとして swf か pdr でしか保存できないあたりが厳しい…。
◎ pdr/swf/svg関係の変換ツール。 :
_PDR2SVG
pdr (ParaDraw形式) → svg変換ができる。試してみたところ、一部の線データが消滅(したように見えた)けど、そこそこsvgに変換してくれた。 _SVG終章 - パラフラノススメ - Yahoo!ブログ という記事によると、Flashとsvgは線の太さ(ストロークの太さ)について仕様が違うので再現は難しいらしい。
_SWF2SVG
swf → svg変換ができる。Adobe AIR製アプリ。 _FlashファイルからシェイプをSVGとして抜き出す - SWF2SVG MOONGIFT によると、コマンドラインツールだそうで、GUIは無し。以下のようなバッチファイルを、PATHの通ったところに置いて使ってみたり。
swf2svg.bat
pdr (ParaDraw形式) → svg変換ができる。試してみたところ、一部の線データが消滅(したように見えた)けど、そこそこsvgに変換してくれた。 _SVG終章 - パラフラノススメ - Yahoo!ブログ という記事によると、Flashとsvgは線の太さ(ストロークの太さ)について仕様が違うので再現は難しいらしい。
_SWF2SVG
swf → svg変換ができる。Adobe AIR製アプリ。 _FlashファイルからシェイプをSVGとして抜き出す - SWF2SVG MOONGIFT によると、コマンドラインツールだそうで、GUIは無し。以下のようなバッチファイルを、PATHの通ったところに置いて使ってみたり。
swf2svg.bat
@set SWF2SVGPATH="C:\Program Files (x86)\SWF2SVG\SWF2SVG.exe" %SWF2SVGPATH% %1 %2 %3 %4 %5 %6 %7 %8 %9こちらも比較的、swfの見た目を再現してくれた。
◎ J.S Draw を試用。 :
_J.S Draw
_すらすらプログラマー J.S Draw
操作性・作業のしやすさに関しては、LibreOffice Draw と似た感じで、現時点ではあまりよろしくなく。図形を置くたびに色設定その他がリセットされたり、図形を塗り潰すとグリッドが隠れてしまったりで。
鋭意開発中のソフトらしく、機能面はまだまだこれから、らしい。しかし、それでも…。
_すらすらプログラマー J.S Draw
操作性・作業のしやすさに関しては、LibreOffice Draw と似た感じで、現時点ではあまりよろしくなく。図形を置くたびに色設定その他がリセットされたり、図形を塗り潰すとグリッドが隠れてしまったりで。
鋭意開発中のソフトらしく、機能面はまだまだこれから、らしい。しかし、それでも…。
- 描画画面はアンチエイリアスがかかっている。
- 保存形式としてxmlが選べる。
[ ツッコむ ]
#3 [anime][neta] 「謎の支援者」ネタ
夢の中で、「盲目の美少女が、周囲からアレコレ助けてもらうのだけど、実はその周囲とは」てなネタを見て。目が覚めてから、ちょっと考え込んだり。
元ネタは、何だろうなあ…。
とりあえず、自分が夢でソレを見たのは、「HUNTERxHUNTER」の影響じゃないかなと思ったのだけど。学生時代にも、山口美由紀先生の短編作品でそういうのを見たような気もするし。子供の頃に、怪談の類でそういうネタを見ていたような気もするし。何にせよ、メジャーな元ネタ、様々なアレンジ作品があるような気がする。
「『周囲』の正体は何か?」という問いに対して、各人がどんな答えを出してくるかで、なんちゃって性格診断もできるかもしれないなと。幽霊だったり、ロボットだったり、モンスターだったり、あるいは、れっきとした人間だけど裏があったり、等々色々思いつくだろうけど。どれを思いついたのかで、その人の嗜好が分かりそう。真っ先に幽霊を思いつく人と、ロボットを思いつく人では、明らかに属性が違うだろから、「貴方は○○派です」と、テキトーな決めつけで分類して会話のネタにできたりしそう。ていうかソレってロールシャッハテストなのかな。
こういうネタは、小説だと表現しやすいのだろうな。「彼」「彼女」とだけ記述しておいて、実はこうだったのです、てな見せ方がしやすいし。小説は、本来の設定とは全く異なるイメージを読者が想像してしまうように、誘導することがたやすい。文字情報しかないから、意図的に誤解させる、という手管が使える。
漫画やアニメだと、ちょっと難しいよなと。「HUNTERxHUNTER」のように、本来そこにある状況をそのまま描く感じになって、怪談っぽい印象が随分と弱くなってしまう。
いや、違う見せ方もあるか…。当人の思い込みをそのまま視覚化しちゃうソレ。読者側はうっすらと状況が分かってるのに、提示されてる光景が異質なので、そのギャップでクラクラしてしまう。高野文子先生の「田辺のつる」…でしたっけか? あの見せ方。
別に、視覚的な見せ方で凝る必要はないのか…。「あしながおじさん」だって、謎の支援者ネタだよな…。
要するに、支援者の正体を隠しておいて、それを開示していくことで、話は作れるのだろうなと。自分が夢で見た「盲目の美少女」というソレは、支援者の姿を隠すために要する設定でしかなく。別の何かで隠せれば、それで済んでしまうのかも。
と、ここまで書いて、ふと思い出したけど。この手の元ネタは、「耳なし芳一」じゃないのかな…。
元ネタは、何だろうなあ…。
とりあえず、自分が夢でソレを見たのは、「HUNTERxHUNTER」の影響じゃないかなと思ったのだけど。学生時代にも、山口美由紀先生の短編作品でそういうのを見たような気もするし。子供の頃に、怪談の類でそういうネタを見ていたような気もするし。何にせよ、メジャーな元ネタ、様々なアレンジ作品があるような気がする。
「『周囲』の正体は何か?」という問いに対して、各人がどんな答えを出してくるかで、なんちゃって性格診断もできるかもしれないなと。幽霊だったり、ロボットだったり、モンスターだったり、あるいは、れっきとした人間だけど裏があったり、等々色々思いつくだろうけど。どれを思いついたのかで、その人の嗜好が分かりそう。真っ先に幽霊を思いつく人と、ロボットを思いつく人では、明らかに属性が違うだろから、「貴方は○○派です」と、テキトーな決めつけで分類して会話のネタにできたりしそう。ていうかソレってロールシャッハテストなのかな。
こういうネタは、小説だと表現しやすいのだろうな。「彼」「彼女」とだけ記述しておいて、実はこうだったのです、てな見せ方がしやすいし。小説は、本来の設定とは全く異なるイメージを読者が想像してしまうように、誘導することがたやすい。文字情報しかないから、意図的に誤解させる、という手管が使える。
漫画やアニメだと、ちょっと難しいよなと。「HUNTERxHUNTER」のように、本来そこにある状況をそのまま描く感じになって、怪談っぽい印象が随分と弱くなってしまう。
いや、違う見せ方もあるか…。当人の思い込みをそのまま視覚化しちゃうソレ。読者側はうっすらと状況が分かってるのに、提示されてる光景が異質なので、そのギャップでクラクラしてしまう。高野文子先生の「田辺のつる」…でしたっけか? あの見せ方。
別に、視覚的な見せ方で凝る必要はないのか…。「あしながおじさん」だって、謎の支援者ネタだよな…。
要するに、支援者の正体を隠しておいて、それを開示していくことで、話は作れるのだろうなと。自分が夢で見た「盲目の美少女」というソレは、支援者の姿を隠すために要する設定でしかなく。別の何かで隠せれば、それで済んでしまうのかも。
と、ここまで書いて、ふと思い出したけど。この手の元ネタは、「耳なし芳一」じゃないのかな…。
この記事へのツッコミ
- Re: 「謎の支援者」ネタ by 名無しさん 2014/06/03 15:31
- 星新一でも似たような話がありましたね。
http://occult-atoaji.sakura.ne.jp/?p=8746
[ ツッコミを読む(1) | ツッコむ ]
2014/06/03(火) [n年前の日記]
#1 [ruby] メモリマップドファイルについて勘違いしてた
mmap って、メモリ上にファイルを作るという話じゃなくて、ファイルをメモリのように扱う、という仕組みだったのですね…。自分がやりたかったことと真逆じゃないか…。トホホ。
それはともかく、とりあえず _win32-mmap の _サンプル をコピペして実験。
コレ、どんな場面で使うんだろう…。
それはともかく、とりあえず _win32-mmap の _サンプル をコピペして実験。
# win32-mmap のテスト # ファイルをメモリのように扱う require 'win32/mmap' tmpfile = File.join(File.expand_path(File.dirname(__FILE__)), "test.map") map1 = Win32::MMap.new(:file => tmpfile, :size => 1024) map1.foo = 'hello' map1.bar = 77 map1.close map2 = Win32::MMap.new(:file => tmpfile) p map2.foo # 'hello' p map2.bar # 77 map2.closeたしかに、test.map が作られた。
コレ、どんな場面で使うんだろう…。
[ ツッコむ ]
#2 [dxruby] cairoの出力結果をファイルを作らずにDXRubyに渡せた
_Cairo::Surfaceクラス
を眺めていたら、
以下で試してみたら、DXRuby で表示できました。ヤッター。
_test_cairo1_stringio.rb
もしかすると、ファイル書き込みした直後はキャッシュ?が効いてて、読み込み処理もさほど遅くなかったとか? 実際はどうだか分からんですけど。
write_to_png(stream)という記述に気がついて。さらにググったら、 _class StringIO が使えそうだなと。
write_to_png(filename)
サーフェスの内容をPNG画像として書き出します。 引数がwriteメソッドを持っている場合はそのオブジェクトの writeメソッドを使ってPNG画像を出力します。
以下で試してみたら、DXRuby で表示できました。ヤッター。
_test_cairo1_stringio.rb
# cairo のテスト。 # StringIO で DXRuby の Image にデータを渡してみる版 require 'cairo' require 'dxruby' require 'stringio' w, h = 640 - 32, 480 - 32 surface = Cairo::ImageSurface.new(w, h) context = Cairo::Context.new(surface) # 円を書く context.set_line_width(12) context.set_source_color(Cairo::Color::GREEN) r = h / 3 x, y, rw, rh = 100, 30, 50, 50 context.arc(w/2, h/2, r, 0, 2 * Math::PI) context.fill_preserve context.set_source_color(Cairo::Color::RED) context.stroke # StringIOを使って png出力、かつ、Image生成 temp = StringIO.new("", 'w+') surface.write_to_png(temp) temp.rewind img = Image.loadFromFileInMemory(temp.read) # DXRubyで表示 Window.bgcolor = [64, 64, 64] Window.loop do break if Input.keyPush?(K_ESCAPE) Window.draw(16, 16, img) endしかし、昨日の虎描画版で、同じ処理を試してみても、処理が速くなった感じはしなくて。
もしかすると、ファイル書き込みした直後はキャッシュ?が効いてて、読み込み処理もさほど遅くなかったとか? 実際はどうだか分からんですけど。
[ ツッコむ ]
#3 [ruby][dxruby] DXRuby と cairo と rsvg2 で svgを描画して表示してみたり
_Rubyist Magazine - cairo: 2 次元画像描画ライブラリ
によると、rsvg2 ライブラリを使えば svgファイルを cairo で描画できるらしくて。
であれば、DXRuby上でも、cairo と rsvg2 を使って svgファイルを描画できるのかなと。早速実験。
しかし、Windows + Ruby 1.9.x で、rsvg2 を使おうとしたら、ハマってしまったり。以下のライブラリが必要なのだけど…。
_rsvg2 | RubyGems.org | your community gem host
_gdk_pixbuf2 | RubyGems.org | your community gem host
_glib2 | RubyGems.org | your community gem host
であれば、DXRuby上でも、cairo と rsvg2 を使って svgファイルを描画できるのかなと。早速実験。
しかし、Windows + Ruby 1.9.x で、rsvg2 を使おうとしたら、ハマってしまったり。以下のライブラリが必要なのだけど…。
_rsvg2 | RubyGems.org | your community gem host
_gdk_pixbuf2 | RubyGems.org | your community gem host
_glib2 | RubyGems.org | your community gem host
◎ Ruby 2.x の場合。 :
Ruby 2.x は、以下の通りで、すんなりインストールできた。
gem install cairo --platform=x86-mingw32 gem install glib2 gem install gdk_pixbuf2 gem install rsvg2
> gem list | grep "cairo\|glib2\|gdk_pixbuf2\|rsvg2" cairo (1.12.9 x86-mingw32) gdk_pixbuf2 (2.2.0 x86-mingw32) glib2 (2.2.0 x86-mingw32) rsvg2 (2.2.0 x86-mingw32)
◎ Ruby 1.9.x の場合。 :
Ruby 1.9.x では問題があって。
試しにバージョンを落としてインストールしてみたり。
ダメ元で、最新版だけをアンインストールしてみる。
以下のような状態になった。
この状態にすれば、Ruby 1.9.x でも、rsvg2 が一応使えた、ように見えた。
ただ、最新版じゃないから、何かバグがあったりするのかもしれないけど…。そもそも、こんなインストール作業、許されるのかな…。初心者なので分かりません。
- rsvg2 2.2.0 は、cairo 1.12.8 以降を要求する。
- しかし、Ruby 1.9.x で利用できるのは、cairo 1.12.4 まで。
試しにバージョンを落としてインストールしてみたり。
gem install cairo --version '=1.12.4' gem install glib2 --version '=1.2.6' gem install gdk_pixbuf2 --version '=1.2.6' gem install rsvg2 --version '=1.2.6'すると、途中で、glib2 と cairo の最新版を勝手にインストールされてしまった。
ダメ元で、最新版だけをアンインストールしてみる。
> gem uninstall glib2 Select gem to uninstall: 1. glib2-1.2.6-x86-mingw32 2. glib2-2.2.0-x86-mingw32 3. All versions > 2 Successfully uninstalled glib2-2.2.0-x86-mingw32 > gem uninstall cairo Select gem to uninstall: 1. cairo-1.12.4-x86-mingw32 2. cairo-1.12.9-x86-mingw32 3. All versions > 2 Successfully uninstalled cairo-1.12.9-x86-mingw32
以下のような状態になった。
> gem list | grep "cairo\|glib2\|gdk_pixbuf2\|rsvg2" cairo (1.12.4 x86-mingw32) gdk_pixbuf2 (1.2.6 x86-mingw32) glib2 (1.2.6 x86-mingw32) rsvg2 (1.2.6 x86-mingw32)
この状態にすれば、Ruby 1.9.x でも、rsvg2 が一応使えた、ように見えた。
ただ、最新版じゃないから、何かバグがあったりするのかもしれないけど…。そもそも、こんなインストール作業、許されるのかな…。初心者なので分かりません。
◎ 実験に使ったソース。 :
以下のようなソースを書いた。
_svgdisp_width_dxruby.rb
結果は以下の通り。 描画できたっぽい感じ。
Ruby 1.9.x を使ってる場合は、ライブラリのインストールが面倒臭いという問題はあるものの。一応、DXRuby でも、この程度の記述で、svgファイルを描画できました。cairo と rsvg2、ありがたいなあ。
でもまあ、DXRuby でベクターデータを描画するメリットって、思いつかないのですけど。あらかじめビットマップ画像にしておいて、ソレを使うほうがいいよな…。
cairo の描画結果を、DXRuby を使うことで即座に表示・確認できる、といった使い方なら、これもアリなのかな…。
_svgdisp_width_dxruby.rb
require 'rsvg2' require 'stringio' require 'dxruby' # SVGをrsvg2とcairoで描画してDXRubyのImageにする # class Svg2Image attr_accessor :handle attr_accessor :width attr_accessor :height attr_accessor :ratio attr_accessor :image def initialize(infile, ratio = 1.0) self.handle = RSVG::Handle.new_from_file(infile) make_image(ratio) end def make_image(ratio = 1.0) self.ratio = ratio.to_f self.width, self.height, = self.handle.dimensions.to_a self.width *= ratio self.height *= ratio Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, self.width, self.height) do |surface| context = Cairo::Context.new(surface) context.scale(self.ratio, self.ratio) context.render_rsvg_handle(self.handle) temp = StringIO.new("", "w+") surface.write_to_png(temp) temp.rewind self.image.dispose if self.image self.image = Image.loadFromFileInMemory(temp.read) temp.close end end end if $0 == __FILE__ # ---------------------------------------- # 動作テスト infile = "Ghostscript_Tiger.svg" scale = 0.5 scale_add = 0.1 svg = Svg2Image.new(infile, 0.5) font = Font.new(14) Window.bgcolor = [64, 64, 64] Window.loop do break if Input.keyPush?(K_ESCAPE) # Rキーで拡大縮小再描画 if Input.keyDown?(K_R) svg.make_image(scale) scale_add *= -1 if scale <= 0.25 or scale >= 1.5 scale += scale_add end Window.draw(0, 0, svg.image) s = "#{Window.real_fps.to_i} FPS #{Window.getLoad.to_i} %" s += " #{svg.image.width} x #{svg.image.height}" Window.drawFont(4, 4, s, font) end endGhostscript_Tiger.svg は、 _File:Ghostscript Tiger.svg - Wikimedia Commons から入手。
結果は以下の通り。 描画できたっぽい感じ。
Ruby 1.9.x を使ってる場合は、ライブラリのインストールが面倒臭いという問題はあるものの。一応、DXRuby でも、この程度の記述で、svgファイルを描画できました。cairo と rsvg2、ありがたいなあ。
でもまあ、DXRuby でベクターデータを描画するメリットって、思いつかないのですけど。あらかじめビットマップ画像にしておいて、ソレを使うほうがいいよな…。
cairo の描画結果を、DXRuby を使うことで即座に表示・確認できる、といった使い方なら、これもアリなのかな…。
[ ツッコむ ]
#4 [ruby] bundlerについて勉強
Ruby のライブラリをインストールする際、RubyGems なる仕組みが ―― gem というコマンドが使えるわけですけど。Ruby 1.9.3 上で、cairo、glib2、gdk_pixbuf2、rsvg2 のバージョンを決め打ちしてインストールする作業が面倒臭かったので、bundler なる仕組みを使えないものかなと思って調べ始めたり。
とりあえず、bundler をインストール。
雛形ファイルを作る。
以下のような感じに修正してみたけど…。
あらかじめ、cairo、glib2、gdk_pixbuf2、rsvg2 を、gem uninstall xxxx でアンインストールしておいた上で、以下を実行。
ただ、この指定だと、Rubyのシステム部分?に、ライブラリをインストールしてしまう。今回はシステムにインストールしたかったので、コレでいいのだろうけど。フツーはプロジェクト単位で、どのライブラリを使うのか、分けて管理するらしくて。一般的には、プロジェクトフォルダ/vendor/bundle 以下にインストールする。らしい。たぶん。
それはともかく。一つの Gemfile の中で、
こんな感じではどうかしら。
とりあえず、bundler をインストール。
gem install bundler
雛形ファイルを作る。
bundle initGemfile というファイルが、カレントフォルダに作られた。エディタで開く。
以下のような感じに修正してみたけど…。
source "https://rubygems.org" platforms :mingw_19 do gem "cairo", "1.12.4" gem "glib2", "1.2.6" gem "gdk_pixbuf2", "1.2.6" gem "rsvg2", "1.2.6" end # platforms :mingw_20 do # gem "cairo" # gem "glib2" # gem "gdk_pixbuf2" # gem "rsvg2" # endplatforms :mingw_19 do 〜 end で、「Ruby 1.9 mingw32版なら、このライブラリをインストールせよ」と指定をしている、らしい。よく分かってないですが。ちなみに、 _Gemfile(5) - A format for describing gem dependencies for Ruby programs の、PLATFORMS (:platforms) のところに、記述できる種類の一覧があるようで。
あらかじめ、cairo、glib2、gdk_pixbuf2、rsvg2 を、gem uninstall xxxx でアンインストールしておいた上で、以下を実行。
bundle installこれで、バージョン決め打ちでインストール出来たように見えた。
ただ、この指定だと、Rubyのシステム部分?に、ライブラリをインストールしてしまう。今回はシステムにインストールしたかったので、コレでいいのだろうけど。フツーはプロジェクト単位で、どのライブラリを使うのか、分けて管理するらしくて。一般的には、プロジェクトフォルダ/vendor/bundle 以下にインストールする。らしい。たぶん。
bundle install --path vendor/bundleしかし、このままだと、スクリプト内で require 'hoge' とかしても「ライブラリがねえよ」と言われてしまう。…どうすれば使えるようになるのかは、まだ調べてないです。
それはともかく。一つの Gemfile の中で、
- 「Ruby 1.9 mingw32版なら、このバージョンのライブラリをインストールせよ」
- 「Ruby 2.0 mingw32版なら、最新版のライブラリをインストールせよ」
You cannot specify the same gem twice with different version requirements. You specified: cairo (= 1.12.4) and cairo (>= 0)さて、どう書けばいいんだろう…。
こんな感じではどうかしら。
source "https://rubygems.org" platforms :mingw do if RUBY_VERSION =~ /^1.9/ gem "cairo", "1.12.4" gem "glib2", "1.2.6" gem "gdk_pixbuf2", "1.2.6" gem "rsvg2", "1.2.6" else gem "cairo" gem "glib2" gem "gdk_pixbuf2" gem "rsvg2" end endコレで合ってるのかな…? よくわからん…。
[ ツッコむ ]
#5 [cg_tools] Ipx、TpX、LaTeXDrawを試用
_描画・グラフツール - TeX Wiki
で、Windows上で使えるフリーのドローソフトがいくつか紹介されてたので、少し試用。
どれもTex?とやらで利用することを前提にしたソフトなのかなと思えたり。何にせよ、フリーで使えるドローソフトも結構選択肢があるのだなと…。ありがたや。
どれもTex?とやらで利用することを前提にしたソフトなのかなと思えたり。何にせよ、フリーで使えるドローソフトも結構選択肢があるのだなと…。ありがたや。
◎ Ipeを試用。 :
_Ipe extensible drawing editor | Free Graphics software downloads at SourceForge.net
から、ipe-7.1.5-win.zip をDLして解凍。bin/ipe.exe を実行。
- UIの見た目は若干カラフル。
- 中ボタンドラッグでキャンバス?の移動。
- 左側の菱形っぽいマークをクリックしていくことで、線のみ → 線と塗り → 塗りのみ → 線のみ、と切り替えられる。
- 線や多角形は、左クリックで点を打つ。右クリックで決定?
- Ctrl+Eでパス編集。パス編集決定はSpaceキー。
- xml(おそらくIpeの保存形式)の他、pdf、eps で保存できる。
◎ TpXを試用。 :
_TpX: drawing tool for TeX | Free Graphics software downloads at SourceForge.net
から、TpX_ExecDistribution1_5.zip をDLして解凍。TpX.exe を実行。
- ちょっとストイックなUIの見た目。
- 図形の塗りは、上のツールバーのバケツみたいなところで指定。
- 図形を一つ置くたびにモードがリセットされる。(選択ツールに戻ってしまう)
- グリッドを前面に表示するオプション有。View → Grid on Top
- eps, pdf, emf, svg, png, bmp等、保存できる種類が多い。latex-dvips なんてものもある。
◎ LaTeXDrawを試用。 :
_LaTeXDraw | Free Development software downloads at SourceForge.net
から、LaTeXDraw-3.1.0-bin.zip をDLして解凍。Windows7 の場合は、install_vista_seven.vbs を実行することでインストールができる。LaTeXDraw.jar を実行。
- Java製アプリ。
- 見た目は若干カラフル。
- 下のツールバー上の各ボタンを選ぶことで、塗り色の変更等ができる模様。
- svg が保存形式。その他、eps, pdf, jpeg, bmp, png等で書き出しもできるらしい。
[ ツッコむ ]
2014/06/04(水) [n年前の日記]
#1 [dxruby][ruby] Ruby 1.9.3 上に rsvg2 2.0.2 を入れようとしたのだけど
rsvg2 の依存関係を眺めていたら、rsvg2、gdk_pixbuf2、glib2 の 2.0.2 も入りそうに見えたので、Windows7 x64 + Ruby 1.9.3 上でインストールしてみたのだけど。「gdk_pixbuf2.so がロードできん」とエラーが出て。
ググってみたら、 _[ruby-gnome2-devel-ja] gdk_pixbuf2 windows: 2.0.1以降、単体でrequireするとLoadError という報告が。
ということで、Windows7 x64 + Ruby 1.9.3 上で rsvg2、gdk_pixbuf2、glib2 をインストールする時は、1.2.6 じゃないとやっぱりダメっぽいです。とメモ。
ググってみたら、 _[ruby-gnome2-devel-ja] gdk_pixbuf2 windows: 2.0.1以降、単体でrequireするとLoadError という報告が。
Windowsでgdk_pixbuf2を単体でrequireしようとしたところ、 gdk_pixbuf2.soがLoadErrorになりました。2.0.0までは大丈夫 なのですが、2.0.1と2.0.2がだめなようです。
原因はおそらくlibgdk_pixbufとlibpngの依存関係で、 libgdk_pixbuf-2.0-0.dllがlibpng16-16.dllに依存しているのに、 バンドルされているのがlibng14-14.dllのためだと思います。なるほど…。
ということで、Windows7 x64 + Ruby 1.9.3 上で rsvg2、gdk_pixbuf2、glib2 をインストールする時は、1.2.6 じゃないとやっぱりダメっぽいです。とメモ。
[ ツッコむ ]
#2 [cg_tools] Linux上で動作するドローソフトをいくつか試用したり
_20 Vector Graphics Editors Reviewed | Smashing Magazine
という記事を眺めているうちに、Linux上で動作するドローソフトがなんだか気になったので、VMware Player + Ubuntu 12.04 LTS 上でインストールできるドローソフトをいくつか試したり。
◎ karbonを試用。 :
Ubuntuソフトウェアセンターからインストールできた。
しかしコレ、終了するたびにクラッシュする。うーん。
- パッと見、カラフルなUI。
- 図形を配置する方法がちとよく分からず。右下の Add Shape から、キャンバスにD&Dして、大きさを調整する、という感じでいいのかな?
- スペースキー + 左ドラッグで、キャンバスを移動。
- パス編集中、Shift + 左クリックで、頂点の種類を変更。
- 右上の、塗りと線のアイコンのどちからをクリックすることで、塗り、もしくは線の色を変えられる。右側の色ボタン、もしくはその右の三角を押して色を選択。あるいは、下にあるカラーリスト内をクリックして選択。
- エクスポート時に選べるベクターデータは、svg か wmf。…wmf は古い規格なので、emf に比べると精度が低くて見た目酷くなるんだけど、いいのかしら。
しかしコレ、終了するたびにクラッシュする。うーん。
◎ Xfigを試用。 :
これも Ubuntuソフトウェアセンターからインストールできた。
- いかにも昔の*NIX向けソフトな感じがする白黒オンリーの殺風景なUI。なんだか昔の Tcl/Tk 等を思い出す。
- 操作時、右上に、マウスの「左ボタン」「中ボタン」「右ボタン」の割り当てが表示される。中ボタンが決定で、右ボタンがキャンセルになってる場面が多い印象。中ボタンが決定なあたり、実に X Window 用らしい割り当てかなと。
- メニュー項目を選ぶときは、メニューボタンを押しっぱなしにして操作しないといけない。これが X Window 文化なのだろうか…。
- 配置した図形を選択する方法が分からない。左下のEDIT等を押して、やっていくしかないのだろうか。
- eps, emf, svg 等でエクスポート可能。他にもかなりの種類をサポートしている。
- 見た目はディザ等で表示されてるけど、epsエクスポートしたらグレースケールになっていた。作業中の見た目と出力結果が結構違ってくることを意識しながら作業する必要がありそう。
◎ Tgifを試用。 :
これも Ubuntuソフトウェアセンターからインストールできた。しかし、起動しない。どうやら起動に必要なフォントが足りてないらしい。以下を参考にして色々インストールした。
_fonts - problem running tgif in ubuntu 12.04.1 LTS - Ask Ubuntu
_[ubuntu] installing tgif
_tgifの起動時のエラー:学びの道案内:So-netブログ
Xfig も Tgif も、実験レポートに貼り付けるための図を描くツール、みたいな印象。
そういや、学生時代、8bit PC しか持ってなかったしプリンタも持ってなかったから、実験レポートに貼る図も、グラフも、手描きだったような気がする…。あの頃に、こういうツールがあったら便利だったのだろうなあ。
_fonts - problem running tgif in ubuntu 12.04.1 LTS - Ask Ubuntu
_[ubuntu] installing tgif
_tgifの起動時のエラー:学びの道案内:So-netブログ
sudo apt-get install ttf-mscorefonts-installer texlive-latex-extra xfonts-100dpi xfonts-75dpi x11-utils texlive-latex-baseインストール後、OS再起動。
- 昔の*NIX向けソフトらしい白黒UI。
- ウインドウ下部のステータスバーに、マウスの、左、中、右ボタンの割り当てが表示される。
- 上のツールバー上に、塗りパターン、色選択ボタンがある。左クリックや右クリックで種類を順々に切り替えていける。選択リスト表示は、中ボタン。
- 保存ファイル名指定時に、ディレクトリ名もキーボードから入力しないといけないらしい。TABキーで補完は効かない。
- エクスポート時の操作がちと変わってる。File → Print/Export Format で保存形式(アイコン画像)を選んだうえで、File → Print をすることでベクターデータが保存されるらしい。
- eps, ps, pdf, svg でエクスポート(Print)可能。
Xfig も Tgif も、実験レポートに貼り付けるための図を描くツール、みたいな印象。
そういや、学生時代、8bit PC しか持ってなかったしプリンタも持ってなかったから、実験レポートに貼る図も、グラフも、手描きだったような気がする…。あの頃に、こういうツールがあったら便利だったのだろうなあ。
◎ sk1も試してみたかったのだけど。 :
_優れたベクターグラフィックス描画ツールsK1 | SourceForge.JP Magazine
によると、Skencil を fork した sK1 なるドローソフトもあるらしいのだけど。Ubuntu 12.04 LTS の場合、標準で入ってる Python が新し過ぎて、sK1 が動かない・公式サイトでもパッケージを公開してないらしくて。ちと残念。古いディストリを別途インストールしないと試用すらできないのか…。
[ ツッコむ ]
#3 [dxruby] 射影変換について勉強中
_平面射影変換
という記事によると、8つの係数を求めれば変換式が使えるそうで、さらに、
_射影変換(ホモグラフィ)について理解してみる - デジタル・デザイン・ラボラトリーな日々
に、8つの係数を求めるメソッドが書いてあったので、コレをそのまま書けば射影変換とやらができるのかなと思えたので、DXRuby上で試してみたり。
なんだか全然違う表示になった。どうも根本的なところを自分は勘違いしてるっぽい。もうちょっと勉強しないと。
なんだか全然違う表示になった。どうも根本的なところを自分は勘違いしてるっぽい。もうちょっと勉強しないと。
[ ツッコむ ]
2014/06/05(木) [n年前の日記]
#1 [dxruby] DXRuby上で射影変換ができた
元記事・参考記事の内容が全然理解できてないけど。写経してたらそれっぽく描画されるようになったのでアップロード。
Window.drawMorph による描画結果とは、ちょっと違うことが分かるかしら。
ソースは以下。
_projtrans.rb.txt
_lena.png (125KB)
それと、他のスクリプトからも、require すれば使えるように書いておきました。
スクリプト内でやってることを簡単に説明すると…。
インチキとは言うけれど、PS1やSSの3Dゲームも似たようなことをして誤魔化してたので、ゲームなら全然アリじゃないかなと。 *1
Window.drawMorph による描画結果とは、ちょっと違うことが分かるかしら。
ソースは以下。
_projtrans.rb.txt
require 'dxruby' # 4点を指定して射影変換描画 class ProjTrans attr_accessor :images attr_accessor :src_w attr_accessor :src_h attr_accessor :divx, :divy attr_accessor :mdivx, :mdivy attr_accessor :src_pos attr_accessor :src_idx # コンストラクタ # # @param [Object] img Imageオブジェクト # @param [Number] divx x方向の分割数 # @param [Number] divy y方向の分割数 # def initialize(img, divx = 8, divy = 8) self.divx = divx self.divy = divy self.src_w, self.src_h = img.width, img.height self.images = img.sliceTiles(divx, divy) # 画像を分割 # 頂点列を登録 self.src_pos = [] w, h = 0, 0 bx, by = 0, 0 i = 0 (0..self.divy).each do |iy| bx = 0 (0..self.divx).each do |ix| if ix < self.divx and iy < self.divy i = iy * self.divx + ix w = self.images[i].width h = self.images[i].height end puts "#{i} : (#{bx}, #{by})" if false # 元画像のサイズで座標値を割っておく self.src_pos.push([bx.to_f / self.src_w, by.to_f / self.src_h]) bx += w i += 1 end by += h end # 頂点番号を登録 self.src_idx = [] self.divy.times do |iy| self.divx.times do |ix| addy = self.divx + 1 i = ix + iy * addy self.src_idx.push([i, i + 1, i + 1 + addy, i + addy]) end end if false self.src_idx.each_with_index {|a, i| puts "#{i} : #{a}" } end end # 描画 # # @param [Number] x1 点1のx座標 # @param [Number] y1 点1のy座標 # @param [Number] x2 点2のx座標 # @param [Number] y2 点2のy座標 # @param [Number] x3 点3のx座標 # @param [Number] y3 点3のy座標 # @param [Number] x4 点4のx座標 # @param [Number] y4 点4のy座標 # @param [Number] alpha アルファ値 0-255 # @param [Number] z 描画深度 # @param [Number] blend 合成種類 # @param [Number] mdivx drawMorphに与えるx方向の分割数 # @param [Number] mdivy drawMorphに与えるy方向の分割数 # def draw(x1, y1, x2, y2, x3, y3, x4, y4, alpha = 255, z = 0, blend = :alpha, mdivx = 2, mdivy = 2) # a から h までの、8つの係数を求める sa, sb, sc, sd, se, sf, sg, sh = get_system(x1.to_f, y1.to_f, x2.to_f, y2.to_f, x3.to_f, y3.to_f, x4.to_f, y4.to_f) # 射影変換 d = [] self.src_pos.each do |x, y| m = (x * sg + y * sh + 1) u = (x * sa + y * sb + sc) / m v = (x * sd + y * se + sf) / m d.push([u, v]) end self.src_idx.each_with_index do |a, i| i0, i1, i2, i3 = a Window.drawMorph(d[i0][0], d[i0][1], d[i1][0], d[i1][1], d[i2][0], d[i2][1], d[i3][0], d[i3][1], self.images[i], :dividex => mdivx, :dividey => mdivy, :alpha => alpha, :z => z, :blend => blend) end end # 8つの係数を求める # # @note 変換式に与える座標値を元画像のサイズで割らないとこの係数は使えない # # @param [Number] x0 点1のx座標 # @param [Number] y0 点1のy座標 # @param [Number] x1 点2のx座標 # @param [Number] y1 点2のy座標 # @param [Number] x2 点3のx座標 # @param [Number] y2 点3のy座標 # @param [Number] x3 点4のx座標 # @param [Number] y3 点4のy座標 # @return [Array] 8つの係数を配列で返す # def get_system(x0, y0, x1, y1, x2, y2, x3, y3) sx = (x0 - x1) + (x2 - x3) sy = (y0 - y1) + (y2 - y3) dx1 = x1 - x2 dx2 = x3 - x2 dy1 = y1 - y2 dy2 = y3 - y2 z = (dx1 * dy2) - (dy1 * dx2) g = ((sx * dy2) - (sy * dx2))/z h = ((sy * dx1) - (sx * dy1))/z return [ x1 - x0 + g * x1, x3 - x0 + h * x3, x0, y1 - y0 + g * y1, y3 - y0 + h * y3, y0, g, h ] end end if $0 == __FILE__ # ---------------------------------------- # 動作確認 img = Image.load("lena.png") prt = ProjTrans.new(img) if false # ---------------------------------------- # 簡単な使い方の例 Window.loop do break if Input.keyPush?(K_ESCAPE) alpha = 255 z = 0 blend = :alpha divx = 2 divy = 2 # 左上の点から時計回りに4点を指定 prt.draw(160, 100, 320, 20, 600, 460, 100, 300, alpha, z, blend, divx, divy) end else # ---------------------------------------- # 動作確認 font = Font.new(14) step = 0 pos = [] poly_pos = [] morph_enable = false mdiv = 1 Window.loop do break if Input.keyPush?(K_ESCAPE) if Input.mousePush?(M_LBUTTON) # マウスの左ボタンが押されたので座標を記録 pos = [] if step == 0 pos.push([Input.mousePosX, Input.mousePosY]) step += 1 if step >= 4 # 4点が入力された step = 0 poly_pos = pos.dup end end # zキーが押されたら drawMorph で描画するかどうかを切替 morph_enable = !morph_enable if Input.keyPush?(K_Z) # 上下キーで分割数を変更 (1から64まで。128にすると落ちる…) mdiv *= 2 if (Input.keyPush?(K_UP) and mdiv < 64) mdiv /= 2 if (Input.keyPush?(K_DOWN) and mdiv >= 2) if poly_pos.size == 4 # 4点が決まってるので、画像を変形して描画 x1, y1 = poly_pos[0] x2, y2 = poly_pos[1] x3, y3 = poly_pos[2] x4, y4 = poly_pos[3] unless morph_enable # 射影変換で描画する場合 prt.draw(x1, y1, x2, y2, x3, y3, x4, y4, 255, 0, :alpha, mdiv, mdiv) else # drawMorphで描画する場合 Window.drawMorph(x1, y1, x2, y2, x3, y3, x4, y4, img, :dividex => mdiv, :dividey => mdiv) end end # 指定済みの頂点位置を描画 d = 5 pos.each do |p| x, y = p Window.drawLine(x - d, y, x + d, y, C_GREEN) Window.drawLine(x, y - d, x, y + d, C_GREEN) end i = step + 1 y = 2 msg = [ "#{Window.real_fps.to_i} FPS CPU: #{Window.getLoad.to_i} %", "zキー : drawMorph 描画との切替 [#{(morph_enable)? "drawMorph" : "射影変換"}]", "↑↓キー : drawMorph 分割数 [#{mdiv}]", "時計回りで、4回、マウスクリックしてください (#{step+1}/4)" ].each_with_index do |s, iy| Window.drawFont(4, 2 + iy * (font.size + 8), s, font) end end end end一応、グリッドを上から描き込んだlena様画像も置いときます。
_lena.png (125KB)
それと、他のスクリプトからも、require すれば使えるように書いておきました。
# ProjTransの使用例 require 'dxruby' require_relative 'projtrans' img = Image.load("lena.png") prt = ProjTrans.new(img) Window.loop do break if Input.keyPush?(K_ESCAPE) alpha = 255 z = 0 blend = :alpha divx, divy = 2, 2 # 左上の点から時計回りに4点を指定 prt.draw(160, 100, 320, 20, 600, 460, 100, 300, alpha, z, blend, divx, divy) end
スクリプト内でやってることを簡単に説明すると…。
- 元画像を 4x4 とか 8x8分割。
- 4点を指定することで、射影変換の変換式で使う8つの係数を求める。
- 分割された各画像に対して、射影変換後の4点を求める。
- その4点で、Window.drawMorph を使って描画。
インチキとは言うけれど、PS1やSSの3Dゲームも似たようなことをして誤魔化してたので、ゲームなら全然アリじゃないかなと。 *1
◎ 問題点。 :
一応できたものの、問題が。
各ポリゴン?の描画面積が小さい場合や、正方形に近い描画の場合は、Window.drawMorph のみで描画しちゃってもいいだろうと思うわけですよ。小さいポリゴンがチラチラ飛んでる分には、どうせ違いなんてパッと見では分かりませんし。おそらく、広い面積を描画する場合に限って、こういった遠近感がついてる描画を使えるのかなと。ただ、どんな演出・背景構成を思いつくかというと、うーん。
それはともかく、これを Shader でやったらどうなるんだろう…。いや、DXRuby のサンプルスクリプトの中に、既にあった気もしますが…。
- 予想より、CPU負荷が高い。1枚描画するだけで、CPU使用率が 15〜20% ぐらいになってしまう。
- 使い道が思いつかない。
各ポリゴン?の描画面積が小さい場合や、正方形に近い描画の場合は、Window.drawMorph のみで描画しちゃってもいいだろうと思うわけですよ。小さいポリゴンがチラチラ飛んでる分には、どうせ違いなんてパッと見では分かりませんし。おそらく、広い面積を描画する場合に限って、こういった遠近感がついてる描画を使えるのかなと。ただ、どんな演出・背景構成を思いつくかというと、うーん。
それはともかく、これを Shader でやったらどうなるんだろう…。いや、DXRuby のサンプルスクリプトの中に、既にあった気もしますが…。
◎ 参考ページ。 :
_射影変換(ホモグラフィ)について理解してみる - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その11 - デジタル・デザイン・ラボラトリーな日々
他の参考資料もメモ。
_平面射影変換
_重なる気持ち -台形補正- | _level0 | Kayac Front End Engineer's Blog
_射影変換(ホモグラフィ)について理解してみる その2 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その3 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その4 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その5 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その6 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その7 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その8 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その9 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その10 - デジタル・デザイン・ラボラトリーな日々
_ホモグラフィ - Shogo Computing Laboratory
_Saqoosha :: スーパー高速に射影変換するには
_Processingで射影変換(ホモグラフィ) | United Field:中西泰人研究室
_遠近法の射影変換パラメータ計算の高速化(pdf)
_Homography << HIDIHO!
_Projection Matrix - wonderfl build flash online
_射影変換 (Homography) - jsdo.it - Share JavaScript, HTML5 and CSS
_テクスチャマッピング入門 射影変換(ホモグラフィ) - jsdo.it - Share JavaScript, HTML5 and CSS
_射影変換(ホモグラフィ)について理解してみる その11 - デジタル・デザイン・ラボラトリーな日々
m2とm5は近似値なのに、それ以外は結構数値の大きさが違います。これでなぜ射影変換出来るのかと調べたところ、描画処理の部分が下記のようなっており、なんと描画サイズ(dstWidth,dstHeight)で割っておりました。昨日スクリプトを書いた時は描画がおかしくて首を捻ったけれど。この一文を目にしたので同じことをしてみたら、それっぽく描画されて「おお…」と思いました。
他の参考資料もメモ。
_平面射影変換
_重なる気持ち -台形補正- | _level0 | Kayac Front End Engineer's Blog
_射影変換(ホモグラフィ)について理解してみる その2 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その3 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その4 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その5 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その6 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その7 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その8 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その9 - デジタル・デザイン・ラボラトリーな日々
_射影変換(ホモグラフィ)について理解してみる その10 - デジタル・デザイン・ラボラトリーな日々
_ホモグラフィ - Shogo Computing Laboratory
_Saqoosha :: スーパー高速に射影変換するには
_Processingで射影変換(ホモグラフィ) | United Field:中西泰人研究室
_遠近法の射影変換パラメータ計算の高速化(pdf)
_Homography << HIDIHO!
_Projection Matrix - wonderfl build flash online
_射影変換 (Homography) - jsdo.it - Share JavaScript, HTML5 and CSS
_テクスチャマッピング入門 射影変換(ホモグラフィ) - jsdo.it - Share JavaScript, HTML5 and CSS
*1: PS1もSSも、ハードウェアでは、三角形 or 四角形の平面的な変形描画機能しか持ってなかったので、そのまま広い面積を描画してしまうと妙な画面になってしまうわけで。なので、必要な時はポリゴンを分割して、とかやってました。まあ、3Dゲームの場合は、z値を使って分割が必要かどうか判定してたはずですが。
[ ツッコむ ]
#2 [ruby] RubyのStructって速度的にはどうなんだろう
上記のスクリプトを書いてた際に、最初は x,y 座標だけを格納するクラスを作って座標管理してたのですけど。速度的によろしくないのかなと配列で管理するようにしちゃったのです。もしかして、クラスじゃなくて Struct を使えば良かったのだろうか…。
と思ってググっていたら、DXRuby作者様が、 _classとStruct - mirichiの日記 において速度測定していて。Ruby 1.9.1 では、Struct のほうがクラスより遅いのか…。
自分も実験。
もちろん、配列ばかり使うと、どこに何の値が入ってるか分かりづらくなるし、途中に何か要素を追加すると修正が大変だし。書きやすさ・メンテナンスと、処理速度の、トレードオフだったりするのかな。
と思ってググっていたら、DXRuby作者様が、 _classとStruct - mirichiの日記 において速度測定していて。Ruby 1.9.1 では、Struct のほうがクラスより遅いのか…。
自分も実験。
# class, Struct, Array のベンチマーク require 'benchmark' IDX = 0 class Hoge attr_accessor :data def initialize(d = 0) self.data = d end end Fuga = Struct.new(:data) Benchmark.bmbm { |x| x.report("class-new ") { 1000000.times { val = Hoge.new(0) } } x.report("Struct-new ") { 1000000.times { val = Fuga.new(0) } } x.report("Array-new ") { 1000000.times { val = [0] } } val = Hoge.new x.report("class-data= ") { 1000000.times { val.data = 0 } } val = Fuga.new x.report("Struct-data=") { 1000000.times { val.data = 0 } } a = [0, 0, 0, 0] x.report("Array-data= ") { 1000000.times { a[IDX] = 0 } } v = Hoge.new(0) x.report("=class-data ") { 1000000.times { b = v.data } } v = Fuga.new(0) x.report("=class-data ") { 1000000.times { b = v.data } } a = [0, 0, 0, 0] x.report("=Array-data ") { 1000000.times { b = a[IDX] } } }
> ruby --version ruby 1.9.3p545 (2014-02-24) [i386-mingw32] > ruby struct_bench.rb Rehearsal ------------------------------------------------ class-new 0.312000 0.000000 0.312000 ( 0.314018) Struct-new 0.265000 0.000000 0.265000 ( 0.261015) Array-new 0.109000 0.000000 0.109000 ( 0.108006) class-data= 0.172000 0.000000 0.172000 ( 0.175010) Struct-data= 0.187000 0.000000 0.187000 ( 0.175010) Array-data= 0.094000 0.000000 0.094000 ( 0.099006) =class-data 0.078000 0.000000 0.078000 ( 0.077004) =class-data 0.078000 0.000000 0.078000 ( 0.077005) =Array-data 0.062000 0.000000 0.062000 ( 0.065004) --------------------------------------- total: 1.357000sec user system total real class-new 0.312000 0.000000 0.312000 ( 0.310017) Struct-new 0.250000 0.000000 0.250000 ( 0.256015) Array-new 0.109000 0.000000 0.109000 ( 0.106006) class-data= 0.171000 0.000000 0.171000 ( 0.177010) Struct-data= 0.172000 0.000000 0.172000 ( 0.175010) Array-data= 0.109000 0.000000 0.109000 ( 0.099005) =class-data 0.078000 0.000000 0.078000 ( 0.078005) =class-data 0.078000 0.000000 0.078000 ( 0.077004) =Array-data 0.063000 0.000000 0.063000 ( 0.065004)生成時に値を渡すなら、Struct のほうが速いのか…。でも、Array を生成するほうが、もっと速いな…。値を代入するのも、読み取るのも、Array のほうが速いっぽい。
もちろん、配列ばかり使うと、どこに何の値が入ってるか分かりづらくなるし、途中に何か要素を追加すると修正が大変だし。書きやすさ・メンテナンスと、処理速度の、トレードオフだったりするのかな。
[ ツッコむ ]
2014/06/06(金) [n年前の日記]
#1 [cg_tools] G.CREW5を試用してみたり
ドローソフトについてググっていたら、G.CREWというドローソフトの情報を目にしたのです。
G.CREW は、Windows95/98時代に、低価格ながらそこそこの機能を持ってるということでウケていたソフト。G.CREW 8 まで出たのだけど、販売会社側で何か色々あったようで、惜しむ声が多い中、販売終了になってしまった悲運のソフト。てな捉え方でいいのでしょうか。分かりませんが。
どんなソフトだったのか少し気になったので、HDDの中をゴソゴソと。G.CREW5 なら当時購入したので持っているのです。 *1 G.CREW5 と G.CREW8 って、機能面はどのくらい違うんだろう。ググっても、資料が無くてわからんのですけど。何にせよ、G.CREW5すらどんなソフトだったのか忘れているわけで、再確認しておきたいなと。
G.CREW は、Windows95/98時代に、低価格ながらそこそこの機能を持ってるということでウケていたソフト。G.CREW 8 まで出たのだけど、販売会社側で何か色々あったようで、惜しむ声が多い中、販売終了になってしまった悲運のソフト。てな捉え方でいいのでしょうか。分かりませんが。
どんなソフトだったのか少し気になったので、HDDの中をゴソゴソと。G.CREW5 なら当時購入したので持っているのです。 *1 G.CREW5 と G.CREW8 って、機能面はどのくらい違うんだろう。ググっても、資料が無くてわからんのですけど。何にせよ、G.CREW5すらどんなソフトだったのか忘れているわけで、再確認しておきたいなと。
◎ Windows7 x64にインストールを試みたけど。 :
さて、Windows7 x64で使えるかどうか…。Windows 95/NT対応としか書いてないアプリのはずだけど…。
結果。
_64bit Windows時代到来:第3回 アプリケーションの互換性 (1/3) - @IT
XPモードは、32ビット版OSなので、インストーラも起動したし、インストールできたし、起動もしました。ということは、もしかすると Windows7 32ビット版なら動いちゃったりするのかな。どうなんだろう。
インストールされたファイル群を、Windows7 x64 上にコピーしたら動いたりしないかなー、と思ったけど、ダメっぽいです。どうやら、G.CREW5 は、以下のファイルをシステムにインストールしてるようで。
結果。
- Windows7 x64 ... NG。インストールすらできない。
- Windows7 x64 + VMWare Player + XPモード ... OK。
- Windows7 x64 + VMWare Player + Windows 98 ... OK。
_64bit Windows時代到来:第3回 アプリケーションの互換性 (1/3) - @IT
XPモードは、32ビット版OSなので、インストーラも起動したし、インストールできたし、起動もしました。ということは、もしかすると Windows7 32ビット版なら動いちゃったりするのかな。どうなんだろう。
インストールされたファイル群を、Windows7 x64 上にコピーしたら動いたりしないかなー、と思ったけど、ダメっぽいです。どうやら、G.CREW5 は、以下のファイルをシステムにインストールしてるようで。
- C:\Windows\system32\ACCUGNT5.DLL
- C:\Windows\C:\Windows\MET'S\*.ocx
◎ 感想・印象。 :
とりあえず、XPモード上では起動したので、少し触ってみたけれど…。
操作性はともかく、今なら、機能面については、Inkscape、LibreOffice Draw、Dynamic Draw のどれを使っても事足りるんじゃないか、てな印象でした。
ベクターデータの出力フォーマットも、wmfしかサポートしてないので旨味は無いし。考えてみれば、インストーラが16ビットアプリだったから…。 _Windows Metafile - Wikipedia によると、wmf = 16ビット、emf = 32ビット、らしいので、当時 wmfしかサポートしてないのは当たり前、だったのかもしれず。
操作性はともかく、今なら、機能面については、Inkscape、LibreOffice Draw、Dynamic Draw のどれを使っても事足りるんじゃないか、てな印象でした。
ベクターデータの出力フォーマットも、wmfしかサポートしてないので旨味は無いし。考えてみれば、インストーラが16ビットアプリだったから…。 _Windows Metafile - Wikipedia によると、wmf = 16ビット、emf = 32ビット、らしいので、当時 wmfしかサポートしてないのは当たり前、だったのかもしれず。
◎ LibreOfficeの動作がちと怪しい。 :
G.CREW5 で作った wmf を、LibreOffice 4.2.4.2 の Draw、Writer にD&Dしたら表示がおかしくなった。極一部しか表示されず、かつ、ベクターデータではなくビットマップデータになってるようで。
Microsoft Word 2003 に D&D したら、期待していた表示になったので…。どうも LibreOffice は、wmf 関係の互換性が、まだちょっと怪しいのかなと。
LibreOffice ではwmf が全然使えない、というわけでもなくて。G.CREW5 の CD-ROM に同梱されてた wmf のクリップアートなら、LibreOffice にD&Dしてもそれらしく描画された。
おそらくだけど、LibreOffice は、wmf の仕様に対して、対応済みの部分と、未対応の部分がありそうな予感。G.CREW5 で出力した wmf は、たまたまその未対応仕様を使ってしまったのかもしれないなと。根拠はないけど。
Microsoft Word 2003 に D&D したら、期待していた表示になったので…。どうも LibreOffice は、wmf 関係の互換性が、まだちょっと怪しいのかなと。
LibreOffice ではwmf が全然使えない、というわけでもなくて。G.CREW5 の CD-ROM に同梱されてた wmf のクリップアートなら、LibreOffice にD&Dしてもそれらしく描画された。
おそらくだけど、LibreOffice は、wmf の仕様に対して、対応済みの部分と、未対応の部分がありそうな予感。G.CREW5 で出力した wmf は、たまたまその未対応仕様を使ってしまったのかもしれないなと。根拠はないけど。
◎ G.CREW5に添付されてるクリップアートのライセンスが分からない。 :
CD-ROMの中にはライセンスに関するドキュメントが一切入ってなくて。このクリップアート群は、どの範囲まで使えるのだろう?
まあ、大体にしてこの手のファイルは、個人利用のみ、商用利用不可、政治宗教関係不可、てなあたりが関の山だろうけど。
絵柄や内容がどうであれ、ライセンスのせいでゴミ同然になっていくデータが多いような気がする。個人で出す年賀状ぐらいにしか使えないのだろうな…。まあ、データを作った人は既に報酬を貰ってるはずなので、後は野とやれ山となれ、ですわな。
まあ、大体にしてこの手のファイルは、個人利用のみ、商用利用不可、政治宗教関係不可、てなあたりが関の山だろうけど。
絵柄や内容がどうであれ、ライセンスのせいでゴミ同然になっていくデータが多いような気がする。個人で出す年賀状ぐらいにしか使えないのだろうな…。まあ、データを作った人は既に報酬を貰ってるはずなので、後は野とやれ山となれ、ですわな。
*1: セットアップCD-ROMはタンス(?)の中にあるけれど、一々発掘作業を行うのが大変なので、isoにして外付けHDDにバックアップしてある状態。
[ ツッコむ ]
#2 [cg_tools] Paintgraphic 2 Pro を購入してみたり
Paintgraphic 2 Pro は、SOURCENEXT が販売してる画像編集ソフト。
*1
ほとんど半額に近い割引キャンペーン+1,000円割引券があったので、試しに買ってみたり。どんなソフトなのか、前から気にはなっていたのです。
機能面に関しては…。GIMPがあれば間に合ってしまう印象…。
ただ、フィルタをかける際、使用前と使用後を、左右に画面分割して提示してくれるのはグッドだなと。考えてみたら、その手のTVCMや雑誌広告では、当たり前のように使ってる見せ方なのだから、CGソフトもフツーに採用すべきじゃないのかと気付かされたり。
他に特筆すべき点があるとしたら、起動の速さ。一瞬で立ち上がる。 _基本部分は大昔のソフト との話なので、そのあたりも軽いのかなと。
それはさておき。これでもう ソースネクストが販売してるソフトの中で、気になるソフトは1本も無くなってしまった…。
機能面に関しては…。GIMPがあれば間に合ってしまう印象…。
ただ、フィルタをかける際、使用前と使用後を、左右に画面分割して提示してくれるのはグッドだなと。考えてみたら、その手のTVCMや雑誌広告では、当たり前のように使ってる見せ方なのだから、CGソフトもフツーに採用すべきじゃないのかと気付かされたり。
他に特筆すべき点があるとしたら、起動の速さ。一瞬で立ち上がる。 _基本部分は大昔のソフト との話なので、そのあたりも軽いのかなと。
それはさておき。これでもう ソースネクストが販売してるソフトの中で、気になるソフトは1本も無くなってしまった…。
*1: 開発というか、メンテナンスは、ファンファーレですけど。
[ ツッコむ ]
#3 [cg_tools] ペイントソフトの起動時間を測定してみた
Paintgraphic 2 Pro の起動速度にちょっと感心したので、他のアプリはどうなのか気になり始めて。ストップウォッチ片手に、手持ちの画像編集ソフトの起動時間を測ってみたり。
環境は以下の通り。
測定結果。
*1
この手のペイントソフト・画像編集ソフトって、1度起動してしまえば、その後はずっとそのソフトを立ち上げたまま作業をするわけで。それを考えると、初回起動で待たされるからソレが一体何なんだ、と言えなくもないのですけど…。
しかし、さすがに、クリックしてから1分経たないと使えないソフトと、クリックして1秒で使えるソフトでは、印象が違っても仕方ないよなと思えてきたり。GIMPを起動するたびに「遅いなあ…」と思っていましたが、まさかこんなに差があるとは。
HDDだからこのような起動時間になるのでしょうけど。SSDならどのくらい違ってくるのでしょうかね…。どのソフトも一瞬で起動するのかしらん。
と思ったけれど、メモリ上にファイルがキャッシュされてるであろう2回目の起動時にもそれなりに時間がかかってるから、SSD環境も、一瞬で起動と言うわけにはいかないのかもしれませんな。
環境は以下の通り。
- OS : Windows7 x64
- HDD : Western Digital WD10EALX-009BA0 (1TB、SATA600、7200rpm)
- CPU : Intel Core i5 2500 (3.3GHz)
- RAM : 8GB (PC3-10600, DDR3 SDRAM)
測定結果。
ソフト名 | 初回起動 (秒) | 2回目の起動 (秒) |
---|---|---|
GIMP 2.6.12 | 178 | 27 |
GIMP 2.8.10 Portable | 64 | 21 |
Adobe Photoshop Elements 8 | 25 | 15 |
CELSYS CLIP STUDIO PAINT PRO | 25 | 6 |
CELSYS Illust Studio | 10 | 4 |
Paint.NET | 5 | 1 |
Paintgraphic 2 Pro | 3 | 1 |
PixBuilder Studio | 1 | 1 |
AzPainter2 | 1 | 1 |
この手のペイントソフト・画像編集ソフトって、1度起動してしまえば、その後はずっとそのソフトを立ち上げたまま作業をするわけで。それを考えると、初回起動で待たされるからソレが一体何なんだ、と言えなくもないのですけど…。
しかし、さすがに、クリックしてから1分経たないと使えないソフトと、クリックして1秒で使えるソフトでは、印象が違っても仕方ないよなと思えてきたり。GIMPを起動するたびに「遅いなあ…」と思っていましたが、まさかこんなに差があるとは。
HDDだからこのような起動時間になるのでしょうけど。SSDならどのくらい違ってくるのでしょうかね…。どのソフトも一瞬で起動するのかしらん。
と思ったけれど、メモリ上にファイルがキャッシュされてるであろう2回目の起動時にもそれなりに時間がかかってるから、SSD環境も、一瞬で起動と言うわけにはいかないのかもしれませんな。
*1: GIMP 2.6.12 の初回起動が約3分かかってるのは、フォント検索がされてしまったから。フォントを頻繁に入れ替える環境ならこのくらいかかるという参考データになりそうなので、フェアではないですけど、あえてメモしました。
[ ツッコむ ]
#4 [dxruby] DXRubyのShaderについて勉強中
DXRubyサンプルの、shader_sample/sample_vertexshader.rb が、Shaderを使って3D表示をしているサンプル、のように思えるので眺めていたり。
このスクリプト、バーテックスシェーダ(頂点シェーダ)とやらを使ってるのですな…。
ピクセルシェーダとやらであれば、 _DXRuby Wiki - チュートリアル にあるチュートリアルが大変参考になるというか、コピペしてちょっと変えるだけでイイ感じになったのですが。バーテックスシェーダ…ってどう使うのやら。
このスクリプト、バーテックスシェーダ(頂点シェーダ)とやらを使ってるのですな…。
ピクセルシェーダとやらであれば、 _DXRuby Wiki - チュートリアル にあるチュートリアルが大変参考になるというか、コピペしてちょっと変えるだけでイイ感じになったのですが。バーテックスシェーダ…ってどう使うのやら。
[ ツッコむ ]
2014/06/07(土) [n年前の日記]
#1 [dxruby] DXRubyでラスタースクロール処理に再チャレンジ
_2014/01/12
に、DXRuby の Shader (HLSL)を使ってラスタースクロールの実験を ―― ラスタースクロールだけで疑似3Dっぽい表現ができないか実験していたのですが。ラスタースクロールに使える画像の作り方が分からなくて、諦めてしまったのでした。
ふと、今頃になって、「こういう画像を作ればよかったのではないか?」とピンと来たので試してみたり。
結果的には、こんな感じの画面になりました。 うむ。ストIIですな。
ふと、今頃になって、「こういう画像を作ればよかったのではないか?」とピンと来たので試してみたり。
結果的には、こんな感じの画面になりました。 うむ。ストIIですな。
- 天井と床は、y値に応じて、x方向のスクロール量を変える。
- 上辺(下辺)が1ドットスクロールしたら、下辺(上辺)は2ドットスクロールするようにした。
- 横方向のスクロールは、64ドットでループ。
◎ 画像を作る際のコツ。 :
たぶん、こういう画像を作ればいいんじゃないかな…。
ピンク色のところが、最終的に欲しい画像。
例えば、GIMPで作業するなら、
グリッドに合わせて線を引いていくのは面倒臭かったので、下地画像を作成するスクリプトを書いてみたり。
_mk_ras_img.rb
そして、これらの下地画像を参考にしつつ、GIMPで画像を作成。以下のような感じに。
ついでに、柱の画像もテキトーに作成。テクスチャを適当に作って、フィルター → マップ → オブジェクトにマップ → 円柱、とかそんな感じ。
例えば、GIMPで作業するなら、
- 変形ツールの遠近法?だかで、上辺896ドット、下辺1792ドットの台形画像を作成。
- 真ん中あたりから、896 x 160ドットぐらいをクリップ。
- 台形画像を作る際、下辺の長さを、上辺の2倍の長さにすると、処理や計算が楽。
- 最終的に必要な画像の横幅は、ウインドウサイズ+グリッドサイズ(64ドット) x 4 にしておくと楽。
グリッドに合わせて線を引いていくのは面倒臭かったので、下地画像を作成するスクリプトを書いてみたり。
_mk_ras_img.rb
# # ラスタースクロール用BGの下絵画像を生成して保存する。 # 天井、壁、床、の3つの画像を保存する。 # require 'dxruby' # ---------------------------------------- # 定義部分 wdw_w = 640 # ウインドウ横幅 wdw_h = 480 # ウインドウ縦幅 cw = 128 / 2 # 1マス分のドットサイズ h0 = 32 * 5 h2 = 32 * 5 h1 = wdw_h - h0 - h2 w = wdw_w + cw * 4 # 画像横幅 # 出力ファイル名 output_fname = [ "bg_ras_a_base.png", "bg_ras_b_base.png", "bg_ras_c_base.png", ] # 定義部分ここまで # ---------------------------------------- # 新規画像作成 img0 = Image.new(w, h0, [0, 0, 0, 0]) img1 = Image.new(w, h1, [0, 0, 0, 0]) img2 = Image.new(w, h2, [0, 0, 0, 0]) # 線を引く cx = w / 2 0.step(cx, cw) do |d| a0 = d a1 = d * 2 img0.line(cx + a1, 0, cx + a0, h0, C_WHITE) img0.line(cx - a1, 0, cx - a0, h0, C_WHITE) img1.line(cx + a0, 0, cx + a0, h1, C_WHITE) img1.line(cx - a0, 0, cx - a0, h1, C_WHITE) img2.line(cx + a0, 0, cx + a1, h2, C_WHITE) img2.line(cx - a0, 0, cx - a1, h2, C_WHITE) end # 保存する img0.save(output_fname[0]) img1.save(output_fname[1]) img2.save(output_fname[2]) font = Font.new(14) # 表示して確認 Window.loop do break if Input.keyPush?(K_ESCAPE) x = (Window.width - w) / 2 y = 0 Window.draw(x, y, img0) y += img0.height Window.draw(x, y, img1) y += img1.height Window.draw(x, y, img2) y += img2.height [ output_fname[0], output_fname[1], output_fname[2], "を保存しました" ].each_with_index do |s, i| Window.drawFont(4, 4 + i * 20, s, font) end end実行すると、以下の3つの画像が保存される。
そして、これらの下地画像を参考にしつつ、GIMPで画像を作成。以下のような感じに。
- 128x128の画像を作成。これが1マス分。
- フィルタ → マップ → 並べる、で、1792 x 640 ドットの画像を作成。
- 遠近法ツールで、遠近感がついた台形に変形。ガイドを作って、頂点をガイドに合わせるようにすれば作業が少し楽。x=448,x=1344の位置にガイドを作ればいいのかな。
- ガイドの作り方は、画像 → ガイド → 新規ガイド。それと、表示 → ガイドにスナップ、にチェックが入っていること。
- 変形できたら、矩形選択ツールで、必要な部分だけコピー。
- ファイル → 画像の生成 → クリップボードから、を選べば新規画像ができる。
- ブレンドツール(グラデーションを塗るツール)や、色調整で、見た目を修正。
ついでに、柱の画像もテキトーに作成。テクスチャを適当に作って、フィルター → マップ → オブジェクトにマップ → 円柱、とかそんな感じ。
◎ スクリプトはこんな感じに。 :
スクリプトはこんな感じに。
_bgrasterscroll3.rb.txt
実行すれば、前述のスクリーンショットのような画面になるはず。マウスカーソルのx座標で、スクロール速度が変わります。
他のスクリプトから呼んで使えるようにもしておきました。以下は使用例。
画像も含めて、一式をzipにして置いときます。ライセンスは、Public Domain ってことで。
_bg_raster_scroll3_20140607.zip (2.9MB)
_bgrasterscroll3.rb.txt
# Shaderを使ってラスタスクロールのテスト # 天井、壁、床をラスタースクロールさせるっぽい感じの処理 # 画像を読み込んで表示する版 require 'dxruby' class BgRasterScroll3 attr_accessor :gridsize attr_accessor :imgs attr_accessor :shaders # コンストラクタ # # @param [Number] gridsize 1マス分のドットサイズ # @param [Array] imgs 天井、壁、床のImageオブジェクトを配列に入れて渡す # def initialize(gridsize, imgs) hlsl = <<EOS float2 size; float d; float dd; texture tex0; sampler Samp0 = sampler_state { Texture =<tex0>; // こっちだと画面がチラチラする (´・ω・`) // MinFilter = LINEAR; // MagFilter = LINEAR; // MipFilter = LINEAR; // こっちならチラチラしない MinFilter = POINT; MagFilter = POINT; MipFilter = NONE; AddressU = WRAP; AddressV = WRAP; }; struct PixelIn { float2 UV : TEXCOORD0; }; struct PixelOut { float4 Color : COLOR0; }; PixelOut PS1(PixelIn input) { PixelOut output; input.UV.x = input.UV.x + ((d + (d * input.UV.y * dd)) / size.x); output.Color = tex2D( Samp0, input.UV ); return output; } PixelOut PS2(PixelIn input) { PixelOut output; input.UV.x = input.UV.x + ((d + (d * (1.0 - input.UV.y) * dd)) / size.x); output.Color = tex2D( Samp0, input.UV ); return output; } PixelOut PS3(PixelIn input) { PixelOut output; input.UV.x = input.UV.x + d / size.x; output.Color = tex2D( Samp0, input.UV ); return output; } // float4 PS(float2 input : TEXCOORD0) : COLOR0 // { // float4 output; // // input.x -= ((d / size.x) + ((d / size.x) * input.y * dd)); // input.x = input.x - ((d + (d * input.y * dd)) / size.x); // output = tex2D( Samp0, input); // return output; // } technique FloorScroll { pass P0 { PixelShader = compile ps_2_0 PS1(); } } technique CeilingScroll { pass P0 { PixelShader = compile ps_2_0 PS2(); } } technique WallScroll { pass P0 { PixelShader = compile ps_2_0 PS3(); } } EOS core = Shader::Core.new(hlsl, {:size=>:float, :d=>:float, :dd=>:float}) self.shaders = [] self.imgs = [] self.gridsize = gridsize shader_names = [ ["CeilingScroll", 1.0], ["WallScroll", 1.0], ["FloorScroll", 1.0] ] shader_names.each_with_index do |dt, i| sname, dd = dt img = imgs[i] self.imgs.push(img) shr = Shader.new(core, sname) shr.size = [img.width, img.height] shr.d = 0 # スクロール量 shr.dd = dd # 上辺と下辺で、x方向に何ドットずれるか self.shaders.push(shr) end end # スクロール量を更新 # # @param [Number] d スクロール量 # def update(d) d = (d % self.gridsize) self.shaders.each do |shr| shr.d = d end end # 描画 # # @param [Number] bx 描画位置 x # @param [Number] by 描画位置 y # def draw(bx, by) x, y = bx - self.gridsize * 2, by 3.times do |i| Window.drawShader(x, y, self.imgs[i], self.shaders[i]) y += self.imgs[i].height end end end if __FILE__ == $0 # ---------------------------------------- # 動作確認 imgs = [] # 画像ファイル名一覧に従って画像ロード [ "bg_ras_a.png", # 天井 "bg_ras_b.png", # 壁 "bg_ras_c.png" # 床 ].each {|fn| imgs.push(Image.load(fn)) } # ラスタースクロール用オブジェクトを発生 ras = BgRasterScroll3.new(64, imgs) # 柱スプライトを発生 pole = Image.load("pole.png") sprs = [] 4.times do |i| spr = Sprite.new(i * (96 * 2) + 72, 480 - (160 /2) - 128 + 8, pole) sprs.push(spr) end font = Font.new(14) x = 0 Window.loop do break if Input.keyPush?(K_ESCAPE) # マウス位置に応じてスクロール量を変化 dx = ((Window.width / 2) - Input.mousePosX).to_f / Window.width * 32 x -= dx ras.update(x) # スクロール量を指定 ras.draw(0, 0) # 描画 # 柱を描画 tdx = dx + dx * 0.5 sprs.each do |spr| spr.x += tdx spr.x += Window.width + 128 if dx < 0 and spr.x + 64 < 0 spr.x -= (Window.width + 128) if dx > 0 and spr.x > Window.width end Sprite.update(sprs) Sprite.draw(sprs) Window.drawFont(4, 4, "dx = #{dx} , x = #{x}", font) end end
実行すれば、前述のスクリーンショットのような画面になるはず。マウスカーソルのx座標で、スクロール速度が変わります。
他のスクリプトから呼んで使えるようにもしておきました。以下は使用例。
# BgRasterScroll3.rb の呼び出しテスト require 'dxruby' require_relative 'bgrasterscroll3' imgs = [] [ "bg_ras_a_base.png", # 天井 "bg_ras_b_base.png", # 壁 "bg_ras_c_base.png" # 床 ].each {|fn| imgs.push(Image.load(fn)) } ras = BgRasterScroll3.new(64, imgs) x = 0 Window.loop do break if Input.keyPush?(K_ESCAPE) ras.update(x) # スクロール量を指定 ras.draw(0, 0) # 描画 x += 3 end
画像も含めて、一式をzipにして置いときます。ライセンスは、Public Domain ってことで。
_bg_raster_scroll3_20140607.zip (2.9MB)
[ ツッコむ ]
2014/06/08(日) [n年前の日記]
#1 [dxruby] Shader勉強中
先日書いた射影変換スクリプトを Shader でやれないかなと疑問が湧いたので、DXRuby のサンプル、shader_sample/sample_vertexshader.rb を眺めていたのだけど。考えてみたら、バーテックスシェーダとやらを使わずに、ピクセルシェーダとやらを使うだけでもできそうな気がしてきたり。
とりあえず書いて試してみたけど、なんだか結果がおかしい。どうも変換前の座標と変換後の座標が入れ替わってるような気がする。どうやって解決すべきなのだろう…。
とりあえず書いて試してみたけど、なんだか結果がおかしい。どうも変換前の座標と変換後の座標が入れ替わってるような気がする。どうやって解決すべきなのだろう…。
[ ツッコむ ]
#2 [zatta][neta] 自分の感覚がおかしくなってる気がする
_小学校長がトイレで盗撮容疑逮捕 NHKニュース
という記事の中で、
「小学生児童を撮影してたんじゃなくて、大人の女性を撮影してたなら、別に問題無いんじゃね」と思った直後に、「…ん? なんか変だぞ?」と気がついて。
世の中、その手の犯罪が増え過ぎて、自分の感覚もちょっとおかしくなってるような、そんな気がしてきました…。
今月5日の昼前、勤務先の学校の1階にある女子トイレに侵入し、女性教諭をスマートフォンで盗撮したとして、建造物侵入と県の迷惑防止条例違反の疑いが持たれています。という記述を見かけたのです。
「小学生児童を撮影してたんじゃなくて、大人の女性を撮影してたなら、別に問題無いんじゃね」と思った直後に、「…ん? なんか変だぞ?」と気がついて。
世の中、その手の犯罪が増え過ぎて、自分の感覚もちょっとおかしくなってるような、そんな気がしてきました…。
[ ツッコむ ]
2014/06/09(月) [n年前の日記]
#1 [dxruby] DXRubyのShaderで射影変換
_先日書いた射影変換スクリプト
をShaderで実現できないか実験中。
一応できた、ような気がする。どうしてこういう式になるのかちゃんと分かってないけど…。
ソースは以下。
_projtransshader.rb
他のスクリプトから呼び出して使う場合は以下のような感じ。
実験用のlena様画像も置いときます。
_lena.png (125KB)
参考ページは、 _mieki256のブックマーク - "射影変換" を見ていただければと。
変換式のための8つの係数を求める際、Ruby の Matrix ライブラリを使っているけど。Ruby の Matrix ライブラリは pure Ruby なので処理が遅いという話も見かけたわけで。もし、大量にこの手のポリゴンを描画したい場合は、もしかすると高速なMatrixライブラリを探すか、バーテックスシェーダとやらを使ってどうにかするとか考えないといかんのかな、という気もしたのですけど実際どうなのかはよく分かりません。
一応できた、ような気がする。どうしてこういう式になるのかちゃんと分かってないけど…。
ソースは以下。
_projtransshader.rb
require 'dxruby' require 'matrix' # 4点を指定して射影変換描画。Shaderを使って描画する版 # class ProjTransShader # wrapする版 @@HLSL1 = <<EOS float2 size, uvadd; float4 g_a, g_e; texture tex0; sampler Samp = sampler_state { Texture =<tex0>; // MipFilter = LINEAR; // MinFilter = LINEAR; // MagFilter = LINEAR; // MipFilter = POINT; // MinFilter = POINT; // MagFilter = POINT; AddressU = WRAP; AddressV = WRAP; }; float4 PS(float2 input : TEXCOORD0) : COLOR0 { float2 p; p.x = input.x * size.x; p.y = input.y * size.y; input.x = ((p.x * g_a[0] + p.y * g_a[1] + g_a[2]) / (p.x * g_e[2] + p.y * g_e[3] + 1.0) + uvadd.x) / size.x; input.y = ((p.x * g_a[3] + p.y * g_e[0] + g_e[1]) / (p.x * g_e[2] + p.y * g_e[3] + 1.0) + uvadd.y) / size.y; return tex2D( Samp, input ); } technique { pass { PixelShader = compile ps_2_0 PS(); } } EOS # wrapしない版 @@HLSL2 = <<EOS float2 size, uvadd; float4 g_a, g_e; texture tex0; sampler Samp = sampler_state { Texture =<tex0>; AddressU = BORDER; AddressV = BORDER; }; float4 PS(float2 input : TEXCOORD0) : COLOR0 { float2 p; p.x = input.x * size.x; p.y = input.y * size.y; input.x = ((p.x * g_a[0] + p.y * g_a[1] + g_a[2]) / (p.x * g_e[2] + p.y * g_e[3] + 1.0) + uvadd.x) / size.x; input.y = ((p.x * g_a[3] + p.y * g_e[0] + g_e[1]) / (p.x * g_e[2] + p.y * g_e[3] + 1.0) + uvadd.y) / size.y; return tex2D( Samp, input ); } technique { pass { PixelShader = compile ps_2_0 PS(); } } EOS attr_accessor :image attr_accessor :shader_wrap attr_accessor :shader_no_wrap attr_accessor :tilew, :tileh attr_accessor :rt attr_accessor :cof attr_accessor :wrap_enable # コンストラクタ # # @param [Object] img Imageオブジェクト # @param [Boolean] wrap_enable trueならwrap、falseならwrapしない # def initialize(img, wrap_enable = false) self.wrap_enable = wrap_enable self.image = img self.shader_wrap = Shader.new(Shader::Core.new( @@HLSL1, { :size=>:float, :uvadd=>:float, :g_a=>:float, :g_e=>:float })) self.shader_no_wrap = Shader.new(Shader::Core.new(@@HLSL2, { :size=>:float, :uvadd=>:float, :g_a=>:float, :g_e=>:float })) # 画面を覆い隠すタイル数を求める self.tilew = Window.width.quo(self.image.width).ceil self.tileh = Window.height.quo(self.image.height).ceil # RenderTargetを生成 rw = self.image.width * self.tilew rh = self.image.height * self.tileh self.rt = RenderTarget.new(rw, rh) self.shader_wrap.size = [rw, rh] self.shader_wrap.uvadd = [0, 0] self.shader_no_wrap.size = [rw, rh] self.shader_no_wrap.uvadd = [0, 0] update(0, 0, 640, 0, 640, 480, 0, 480) end # 射影変換の式に与える8つの係数を求めてShaderに渡す # # @param [Number] x1 点1のx座標 # @param [Number] y1 点1のy座標 # @param [Number] x2 点2のx座標 # @param [Number] y2 点2のy座標 # @param [Number] x3 点3のx座標 # @param [Number] y3 点3のy座標 # @param [Number] x4 点4のx座標 # @param [Number] y4 点4のy座標 # def update(x1, y1, x2, y2, x3, y3, x4, y4) # self.cof = get_system(x1.to_f, y1.to_f, x2.to_f, y2.to_f, # x3.to_f, y3.to_f, x4.to_f, y4.to_f) src = [ [0.0, 0.0], [self.image.width.to_f, 0.0], [self.image.width.to_f, self.image.height.to_f], [0.0, self.image.height.to_f] ] dst = [ [ x1.to_f, y1.to_f ], [ x2.to_f, y2.to_f ], [ x3.to_f, y3.to_f ], [ x4.to_f, y4.to_f ] ] self.cof = get_proj_param(dst, src) self.shader_wrap.g_a = self.cof[0..3] self.shader_wrap.g_e = self.cof[4..7] self.shader_no_wrap.g_a = self.cof[0..3] self.shader_no_wrap.g_e = self.cof[4..7] end # uvスクロール値を設定 # # @param [Number] u u値 # @param [Number] v v値 # def set_scroll_uv(u, v) self.shader_wrap.uvadd[0] = u self.shader_wrap.uvadd[1] = v self.shader_no_wrap.uvadd[0] = u self.shader_no_wrap.uvadd[1] = v end # uvスクロール値を加算 # # @param [Number] u u加算値 # @param [Number] v v加算値 # def add_scroll_uv(u, v) self.shader_wrap.uvadd[0] += u self.shader_wrap.uvadd[1] += v self.shader_no_wrap.uvadd[0] += u self.shader_no_wrap.uvadd[1] += v end # 描画 # # @param [Number] x0 描画x座標 # @param [Number] y0 描画x座標 # @param [Number] alpha アルファ値 0-255 # @param [Number] z 描画深度 # @param [Number] blend 合成種類 # def draw(x0, y0, alpha = 255, z = 0, blend = :alpha) tw, th = 1, 1 shader = self.shader_no_wrap if self.wrap_enable tw, th = self.tilew, self.tileh shader = self.shader_wrap end # Shader が参照する画像を RenderTarget に作成 self.rt.drawTile(0, 0, [[0]], [self.image], 0, 0, tw, th).update # Shader を使って描画 Window.drawEx(x0, y0, self.rt, :shader=>shader, :alpha=>alpha, :z=>z, :blend=>blend) end # wrapの切り替え # # @param [Boolean] wrap_enable trueならwrap有効、falseならwrap無効 # def set_wrap(wrap_enable) self.wrap_enable = wrap_enable end # 変換式用の8つの係数を取得 # # @note 変換式に与える座標値を元画像のサイズで割らないとこの係数は使えない # # @param [Number] x0 点1のx座標 # @param [Number] y0 点1のy座標 # @param [Number] x1 点2のx座標 # @param [Number] y1 点2のy座標 # @param [Number] x2 点3のx座標 # @param [Number] y2 点3のy座標 # @param [Number] x3 点4のx座標 # @param [Number] y3 点4のy座標 # @return [Array] 8つの係数を配列で返す # def get_system(x0, y0, x1, y1, x2, y2, x3, y3) sx = (x0 - x1) + (x2 - x3) sy = (y0 - y1) + (y2 - y3) dx1 = x1 - x2 dx2 = x3 - x2 dy1 = y1 - y2 dy2 = y3 - y2 z = (dx1 * dy2) - (dy1 * dx2) g = ((sx * dy2) - (sy * dx2)) / z h = ((sy * dx1) - (sx * dy1)) / z return [ x1 - x0 + g * x1, x3 - x0 + h * x3, x0, y1 - y0 + g * y1, y3 - y0 + h * y3, y0, g, h ] end # 変換式用の8つの係数を取得 # # @note 参考ページ # 月の杜工房 - 射影変換のパラメータを求める # http://mf-atelier.sakura.ne.jp/mf-atelier/modules/tips/program/algorithm/a6.html # # @param [Array] s 変換前の4点座標配列([[x1,y1],[x2,y2],...) # @param [Array] d 変換後の4点座標配列([[x1,y1],[x2,y2],...) # @return [Array] 8つの係数を配列で返す # def get_proj_param(s, d) x0, y0 = d[0] x1, y1 = d[1] x2, y2 = d[2] x3, y3 = d[3] m = Matrix[ [ s[0][0], s[0][1], 1.0, 0.0, 0.0, 0.0, -x0 * s[0][0], -x0 * s[0][1] ], [ s[1][0], s[1][1], 1.0, 0.0, 0.0, 0.0, -x1 * s[1][0], -x1 * s[1][1] ], [ s[2][0], s[2][1], 1.0, 0.0, 0.0, 0.0, -x2 * s[2][0], -x2 * s[2][1] ], [ s[3][0], s[3][1], 1.0, 0.0, 0.0, 0.0, -x3 * s[3][0], -x3 * s[3][1] ], [ 0.0, 0.0, 0.0, s[0][0], s[0][1], 1.0, -y0 * s[0][0], -y0 * s[0][1] ], [ 0.0, 0.0, 0.0, s[1][0], s[1][1], 1.0, -y1 * s[1][0], -y1 * s[1][1] ], [ 0.0, 0.0, 0.0, s[2][0], s[2][1], 1.0, -y2 * s[2][0], -y2 * s[2][1] ], [ 0.0, 0.0, 0.0, s[3][0], s[3][1], 1.0, -y3 * s[3][0], -y3 * s[3][1] ] ] n = m.inv # 逆行列を取得 g_a = n[0,0] * x0 + n[0,1] * x1 + n[0,2] * x2 + n[0,3] * x3 + n[0,4] * y0 + n[0,5] * y1 + n[0,6] * y2 + n[0,7] * y3 g_b = n[1,0] * x0 + n[1,1] * x1 + n[1,2] * x2 + n[1,3] * x3 + n[1,4] * y0 + n[1,5] * y1 + n[1,6] * y2 + n[1,7] * y3 g_c = n[2,0] * x0 + n[2,1] * x1 + n[2,2] * x2 + n[2,3] * x3 + n[2,4] * y0 + n[2,5] * y1 + n[2,6] * y2 + n[2,7] * y3 g_d = n[3,0] * x0 + n[3,1] * x1 + n[3,2] * x2 + n[3,3] * x3 + n[3,4] * y0 + n[3,5] * y1 + n[3,6] * y2 + n[3,7] * y3 g_e = n[4,0] * x0 + n[4,1] * x1 + n[4,2] * x2 + n[4,3] * x3 + n[4,4] * y0 + n[4,5] * y1 + n[4,6] * y2 + n[4,7] * y3 g_f = n[5,0] * x0 + n[5,1] * x1 + n[5,2] * x2 + n[5,3] * x3 + n[5,4] * y0 + n[5,5] * y1 + n[5,6] * y2 + n[5,7] * y3 g_g = n[6,0] * x0 + n[6,1] * x1 + n[6,2] * x2 + n[6,3] * x3 + n[6,4] * y0 + n[6,5] * y1 + n[6,6] * y2 + n[6,7] * y3 g_h = n[7,0] * x0 + n[7,1] * x1 + n[7,2] * x2 + n[7,3] * x3 + n[7,4] * y0 + n[7,5] * y1 + n[7,6] * y2 + n[7,7] * y3 return [g_a, g_b, g_c, g_d, g_e, g_f, g_g, g_h] end # 1点を射影変換する # # @param [Number] x x座標 # @param [Number] y y座標 # @param [Array] cof 8つの係数配列 # @return [Array] 射影変換後のx,y座標を配列で返す # def Projection(x, y, cof) mm = (x.to_f * cof[6] + y.to_f * cof[7] + 1.0) u = (x.to_f * cof[0] + y.to_f * cof[1] + cof[2]) / mm v = (x.to_f * cof[3] + y/to_f * cof[4] + cof[5]) / mm return u, v end end if $0 == __FILE__ # ---------------------------------------- # 動作確認 if false # ---------------------------------------- # 簡単な使い方の例 img = Image.load("lena.png") prt = ProjTransShader.new(img) Window.loop do break if Input.keyPush?(K_ESCAPE) # 左上の点から時計回りに4点を指定 prt.update(160, 100, 320, 20, 600, 460, 100, 300) prt.draw(0, 0) # 描画 end else # ---------------------------------------- # 動作確認 morph_enable = false wrap_enable = false img = Image.load("lena.png") prt = ProjTransShader.new(img, wrap_enable) alpha = 255 z = 0 blend = :alpha font = Font.new(12) step = 0 pos = [] poly_pos = [] Window.loop do break if Input.keyPush?(K_ESCAPE) if Input.mousePush?(M_LBUTTON) # マウスの左ボタンが押されたので座標を記録 pos = [] if step == 0 pos.push([Input.mousePosX, Input.mousePosY]) step += 1 if step >= 4 # 4点が入力された step = 0 poly_pos = pos.dup end end # zキーが押されたら drawMorph で描画するかどうかを切替 morph_enable = !morph_enable if Input.keyPush?(K_Z) # wキーが押されたら wrap 切り替え wrap_enable = !wrap_enable if Input.keyPush?(K_W) if poly_pos.size == 4 # 4点が決まってるので、画像を変形して描画 x1, y1 = poly_pos[0] x2, y2 = poly_pos[1] x3, y3 = poly_pos[2] x4, y4 = poly_pos[3] unless morph_enable # 射影変換で描画する場合 prt.set_wrap(wrap_enable) #prt.set_scroll_uv(2, 2) prt.update(x1, y1, x2, y2, x3, y3, x4, y4) prt.draw(0, 0, alpha, z, blend) else # drawMorphで描画する場合 Window.drawMorph(x1, y1, x2, y2, x3, y3, x4, y4, img, :dividex => 4, :dividey => 4) end end # 指定済みの頂点位置を描画 d = 10 pos.each do |p| x, y = p Window.drawLine(x - d, y, x + d, y, C_RED) Window.drawLine(x, y - d, x, y + d, C_RED) end i = step + 1 y = 2 msg = [ "#{Window.real_fps.to_i} FPS CPU: #{Window.getLoad.to_i} %", "z : 描画切替 [#{(morph_enable)? "drawMorph" : "射影変換"}]", "w : wrap切替 [#{(wrap_enable)? "Wrap" : "No wrap"}]", "時計回りで4回、マウスクリック (#{step+1}/4)" ].each_with_index do |s, iy| Window.drawFont(4, 2 + iy * (font.size + 8), s, font) end end end end
他のスクリプトから呼び出して使う場合は以下のような感じ。
# ProjTransShaderの使用例 require 'dxruby' require_relative 'projtransshader' img = Image.load("lena.png") prt = ProjTransShader.new(img) Window.loop do break if Input.keyPush?(K_ESCAPE) alpha = 255 z = 0 blend = :alpha # 左上の点から時計回りに4点を指定 prt.update(160, 100, 320, 20, 600, 460, 100, 300) prt.draw(0, 0, alpha, z, blend) end
実験用のlena様画像も置いときます。
_lena.png (125KB)
参考ページは、 _mieki256のブックマーク - "射影変換" を見ていただければと。
変換式のための8つの係数を求める際、Ruby の Matrix ライブラリを使っているけど。Ruby の Matrix ライブラリは pure Ruby なので処理が遅いという話も見かけたわけで。もし、大量にこの手のポリゴンを描画したい場合は、もしかすると高速なMatrixライブラリを探すか、バーテックスシェーダとやらを使ってどうにかするとか考えないといかんのかな、という気もしたのですけど実際どうなのかはよく分かりません。
[ ツッコむ ]
#2 [ruby] NMatrixについて調べてたり
Ruby で高速な行列計算をできる NMatrix なるライブラリがあるらしいと知ったのだけど。ググってるうちに2種類あると知り。
_SciRuby/narray - GitHub を眺めると、SciRuby にも NArray がある…? どのライブラリをどんな風に呼べばいいのか分かりません。
- NArray のサブクラスとしての NMatrix
- SciRuby の NMatrix
_SciRuby/narray - GitHub を眺めると、SciRuby にも NArray がある…? どのライブラリをどんな風に呼べばいいのか分かりません。
[ ツッコむ ]
2014/06/10(火) [n年前の日記]
#1 [ruby] 配列に入ってる整数を全て実数にしたい
Ruby で、配列に入った値を整数から実数にしたいときがあるのですけど。今まで以下のように書いてたわけで。
色々ググってたら、こういう書き方もできそうだなと。
_flatten, flatten! (Array) - Rubyリファレンス
_map, map! (Array) - Rubyリファレンス
しかし、ベンチマークを取ってみたら、flatten と map を使った書き方は微妙に遅くて。
微妙に遅いというか、3倍遅いのかな。見た目アホっぽく、ベタッと書いたほうが、まだ速い場面もあるのだなと…。
もっと違う書き方はできないかしら。
x1, y1 = a[0][0].to_f, a[0][1].to_f x2, y2 = a[1][0].to_f, a[1][1].to_f x3, y3 = a[2][0].to_f, a[2][1].to_f x4, y4 = a[3][0].to_f, a[3][1].to_fもっといい書き方ないのかなと。
色々ググってたら、こういう書き方もできそうだなと。
x1, y1, x2, y2, x3, y3, x4, y4 = a.flatten.map {|item| item.to_f }
_flatten, flatten! (Array) - Rubyリファレンス
flattenメソッドは、配列の配列を平坦化した新しい配列を返します。配列中に含まれる配列からすべて要素を取り出して、親の配列の中に並べます。
_map, map! (Array) - Rubyリファレンス
mapメソッドは、要素の数だけ繰り返しブロックを実行し、ブロックの戻り値を集めた配列を作成して返します。collectメソッドの別名です。
しかし、ベンチマークを取ってみたら、flatten と map を使った書き方は微妙に遅くて。
# 配列内の値を実数にする際のベンチマークを測定 require 'benchmark' def hoge(a) x1 = a[0][0].to_f x2 = a[1][0].to_f x3 = a[2][0].to_f x4 = a[3][0].to_f y1 = a[0][1].to_f y2 = a[1][1].to_f y3 = a[2][1].to_f y4 = a[3][1].to_f x1 + x2 + x3 + x4 + y1 + y2 + y3 + y4 end def fuga(a) x1, y1 = a[0][0].to_f, a[0][1].to_f x2, y2 = a[1][0].to_f, a[1][1].to_f x3, y3 = a[2][0].to_f, a[2][1].to_f x4, y4 = a[3][0].to_f, a[3][1].to_f x1 + x2 + x3 + x4 + y1 + y2 + y3 + y4 end def piyo(a) x1, y1, x2, y2, x3, y3, x4, y4 = a.flatten.map {|item| item.to_f } x1 + x2 + x3 + x4 + y1 + y2 + y3 + y4 end dst = [ [160, 100], [320, 20], [600, 460], [100, 300]] n = 1000000 Benchmark.bm do |x| x.report("a[0][0].to_f A: ") { n.times {|i| hoge(dst) } } x.report("a[0][0].to_f B: ") { n.times {|i| fuga(dst) } } x.report("flatten.map: ") { n.times {|i| piyo(dst) } } end
user system total real a[0][0].to_f A: 1.061000 0.000000 1.061000 ( 1.056060) a[0][0].to_f B: 1.139000 0.000000 1.139000 ( 1.143066) flatten.map: 2.870000 0.000000 2.870000 ( 2.872164)
微妙に遅いというか、3倍遅いのかな。見た目アホっぽく、ベタッと書いたほうが、まだ速い場面もあるのだなと…。
もっと違う書き方はできないかしら。
[ ツッコむ ]
#2 [ruby] NArrayをインストールしてみた
Windows7 x64 + Ruby 1.9.3 p545 mingw32版で、NArray を試用。
Ruby標準の Matrix を使うより、NArrayの NMatrix を使ったほうが、約7倍ほど速い、という結果になった。
ただ、Matrix と NMatrix は、添字の順番が逆になるらしい。そこは注意しないといかんようで。
gem install narray-ruby19 --no-ri --no-rdoc
◎ 速度を測定してみた。 :
# NMatrix (NArray) のテスト require 'benchmark' require 'matrix' # 標準添付のMatrixライブラリ require 'narray' # NArray # require 'narray/narray' # SciRubyのNArray # require 'nmatrix' # SciRubyのNMatrix def get_proj_param(s, d) # x0, y0, x1, y1, x2, y2, x3, y3 = d.flatten.map {|item| item.to_f } # sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3 = s.flatten.map {|item| item.to_f } x0 = d[0][0].to_f x1 = d[1][0].to_f x2 = d[2][0].to_f x3 = d[3][0].to_f y0 = d[0][1].to_f y1 = d[1][1].to_f y2 = d[2][1].to_f y3 = d[3][1].to_f sx0 = s[0][0].to_f sx1 = s[1][0].to_f sx2 = s[2][0].to_f sx3 = s[3][0].to_f sy0 = s[0][1].to_f sy1 = s[1][1].to_f sy2 = s[2][1].to_f sy3 = s[3][1].to_f m = Matrix[ [ sx0, sy0, 1.0, 0.0, 0.0, 0.0, -x0 * sx0, -x0 * sy0 ], [ sx1, sy1, 1.0, 0.0, 0.0, 0.0, -x1 * sx1, -x1 * sy1 ], [ sx2, sy2, 1.0, 0.0, 0.0, 0.0, -x2 * sx2, -x2 * sy2 ], [ sx3, sy3, 1.0, 0.0, 0.0, 0.0, -x3 * sx3, -x3 * sy3 ], [ 0.0, 0.0, 0.0, sx0, sy0, 1.0, -y0 * sx0, -y0 * sy0 ], [ 0.0, 0.0, 0.0, sx1, sy1, 1.0, -y1 * sx1, -y1 * sy1 ], [ 0.0, 0.0, 0.0, sx2, sy2, 1.0, -y2 * sx2, -y2 * sy2 ], [ 0.0, 0.0, 0.0, sx3, sy3, 1.0, -y3 * sx3, -y3 * sy3 ] ] n = m.inv # 逆行列を取得 g_a = n[0,0] * x0 + n[0,1] * x1 + n[0,2] * x2 + n[0,3] * x3 + n[0,4] * y0 + n[0,5] * y1 + n[0,6] * y2 + n[0,7] * y3 g_b = n[1,0] * x0 + n[1,1] * x1 + n[1,2] * x2 + n[1,3] * x3 + n[1,4] * y0 + n[1,5] * y1 + n[1,6] * y2 + n[1,7] * y3 g_c = n[2,0] * x0 + n[2,1] * x1 + n[2,2] * x2 + n[2,3] * x3 + n[2,4] * y0 + n[2,5] * y1 + n[2,6] * y2 + n[2,7] * y3 g_d = n[3,0] * x0 + n[3,1] * x1 + n[3,2] * x2 + n[3,3] * x3 + n[3,4] * y0 + n[3,5] * y1 + n[3,6] * y2 + n[3,7] * y3 g_e = n[4,0] * x0 + n[4,1] * x1 + n[4,2] * x2 + n[4,3] * x3 + n[4,4] * y0 + n[4,5] * y1 + n[4,6] * y2 + n[4,7] * y3 g_f = n[5,0] * x0 + n[5,1] * x1 + n[5,2] * x2 + n[5,3] * x3 + n[5,4] * y0 + n[5,5] * y1 + n[5,6] * y2 + n[5,7] * y3 g_g = n[6,0] * x0 + n[6,1] * x1 + n[6,2] * x2 + n[6,3] * x3 + n[6,4] * y0 + n[6,5] * y1 + n[6,6] * y2 + n[6,7] * y3 g_h = n[7,0] * x0 + n[7,1] * x1 + n[7,2] * x2 + n[7,3] * x3 + n[7,4] * y0 + n[7,5] * y1 + n[7,6] * y2 + n[7,7] * y3 return [g_a, g_b, g_c, g_d, g_e, g_f, g_g, g_h] end def get_proj_param_nmatrix(s, d) x0 = d[0][0].to_f x1 = d[1][0].to_f x2 = d[2][0].to_f x3 = d[3][0].to_f y0 = d[0][1].to_f y1 = d[1][1].to_f y2 = d[2][1].to_f y3 = d[3][1].to_f sx0 = s[0][0].to_f sx1 = s[1][0].to_f sx2 = s[2][0].to_f sx3 = s[3][0].to_f sy0 = s[0][1].to_f sy1 = s[1][1].to_f sy2 = s[2][1].to_f sy3 = s[3][1].to_f # m = NArray::NMatrix[ m = NMatrix[ [ sx0, sy0, 1.0, 0.0, 0.0, 0.0, -x0 * sx0, -x0 * sy0 ], [ sx1, sy1, 1.0, 0.0, 0.0, 0.0, -x1 * sx1, -x1 * sy1 ], [ sx2, sy2, 1.0, 0.0, 0.0, 0.0, -x2 * sx2, -x2 * sy2 ], [ sx3, sy3, 1.0, 0.0, 0.0, 0.0, -x3 * sx3, -x3 * sy3 ], [ 0.0, 0.0, 0.0, sx0, sy0, 1.0, -y0 * sx0, -y0 * sy0 ], [ 0.0, 0.0, 0.0, sx1, sy1, 1.0, -y1 * sx1, -y1 * sy1 ], [ 0.0, 0.0, 0.0, sx2, sy2, 1.0, -y2 * sx2, -y2 * sy2 ], [ 0.0, 0.0, 0.0, sx3, sy3, 1.0, -y3 * sx3, -y3 * sy3 ] ] n = m.inverse # 逆行列を取得 g_a = n[0,0] * x0 + n[1,0] * x1 + n[2,0] * x2 + n[3,0] * x3 + n[4,0] * y0 + n[5,0] * y1 + n[6,0] * y2 + n[7,0] * y3 g_b = n[0,1] * x0 + n[1,1] * x1 + n[2,1] * x2 + n[3,1] * x3 + n[4,1] * y0 + n[5,1] * y1 + n[6,1] * y2 + n[7,1] * y3 g_c = n[0,2] * x0 + n[1,2] * x1 + n[2,2] * x2 + n[3,2] * x3 + n[4,2] * y0 + n[5,2] * y1 + n[6,2] * y2 + n[7,2] * y3 g_d = n[0,3] * x0 + n[1,3] * x1 + n[2,3] * x2 + n[3,3] * x3 + n[4,3] * y0 + n[5,3] * y1 + n[6,3] * y2 + n[7,3] * y3 g_e = n[0,4] * x0 + n[1,4] * x1 + n[2,4] * x2 + n[3,4] * x3 + n[4,4] * y0 + n[5,4] * y1 + n[6,4] * y2 + n[7,4] * y3 g_f = n[0,5] * x0 + n[1,5] * x1 + n[2,5] * x2 + n[3,5] * x3 + n[4,5] * y0 + n[5,5] * y1 + n[6,5] * y2 + n[7,5] * y3 g_g = n[0,6] * x0 + n[1,6] * x1 + n[2,6] * x2 + n[3,6] * x3 + n[4,6] * y0 + n[5,6] * y1 + n[6,6] * y2 + n[7,6] * y3 g_h = n[0,7] * x0 + n[1,7] * x1 + n[2,7] * x2 + n[3,7] * x3 + n[4,7] * y0 + n[5,7] * y1 + n[6,7] * y2 + n[7,7] * y3 return [g_a, g_b, g_c, g_d, g_e, g_f, g_g, g_h] end def dump_cof_diff(cof1, cof2) puts s = "abcdefgh" 8.times do |i| d = cof1[i] - cof2[i] puts "#{s[i, 1]} = diff: #{d} , #{cof1[i]}, #{cof2[i]}" end end src = [[0, 0],[512, 0], [512, 512], [0, 512]] dst = [ [160, 100], [320, 20], [600, 460], [100, 300]] cof1 = [] cof2 = [] n = 10000 Benchmark.bm do |x| x.report("Array: ") { n.times {|i| cof1 = get_proj_param(src, dst)} } x.report("NArray: ") { n.times {|i| cof2 = get_proj_param_nmatrix(src, dst) } } dump_cof_diff(cof1, cof2) end
> ruby test_narray.rb user system total real Array: 3.042000 0.000000 3.042000 ( 3.049174) NArray: 0.421000 0.000000 0.421000 ( 0.430025) a = diff: -1.1102230246251565e-16 , 0.07848173515981738, 0.07848173515981749 b = diff: -5.551115123125783e-17 , -0.2090468036529681, -0.20904680365296804 c = diff: 0.0 , 160.0, 160.0 d = diff: 2.7755575615628914e-17 , -0.1708761415525114, -0.17087614155251143 e = diff: -5.551115123125783e-17 , 0.1150470890410959, 0.11504708904109595 f = diff: 0.0 , 100.0, 100.0 g = diff: 0.0 , -0.0007313070776255703, -0.0007313070776255703 h = diff: 0.0 , -0.0009185930365296805, -0.0009185930365296805
Ruby標準の Matrix を使うより、NArrayの NMatrix を使ったほうが、約7倍ほど速い、という結果になった。
ただ、Matrix と NMatrix は、添字の順番が逆になるらしい。そこは注意しないといかんようで。
◎ SciRuby の narray-nmatrix もインストールしてみた。 :
_SciRuby/narray - GitHub
を参考にインストール。
NArray を使うか、SciRuby を使うかは、選べるらしい。
NArray を使う場合。
SciRuby の NMatrix を使う場合。
名前空間?を使って指定する場合。
gem install narray-nmatrix --pre --no-ri --no-rdoc
NArray を使うか、SciRuby を使うかは、選べるらしい。
NArray を使う場合。
require 'narray'
SciRuby の NMatrix を使う場合。
require 'narray/narray' require 'nmatrix'
名前空間?を使って指定する場合。
NArray::NMatrix # NArray の NMatrix を使う場合 NMatrix # SciRuby の NMatrix を使う場合
[ ツッコむ ]
#3 [ruby] docoptが気になる
_docopt/docopt.rb - GitHub
_docopt | RubyGems.org | your community gem host
_Pythonのコマンドライン引数処理の決定版 docopt (あとJuliaに移植したよ) - りんごがでている
_docopt - shkh's blog
_docopt・language for description of command-line interfaces
一般的に、コマンドラインツールのオプション指定って、スクリプト内でどんな種類があるかチマチマと指定していくわけだけど。docoptなるライブラリを使えば、ヘルプメッセージをそのまま記述することで、どんなオプション指定があり得るのかを解析・反映してくれるらしくて。
世の中には頭がいい人が居るもんだなと、大変感心いたしました。その発想は無かった。たしかにそのほうが、記述が分かりやすい。そして、色々な場所で応用できそうな考え方のように思えたり。
いや、考えてみたら、Markdown記法もソレか…。出来上がりがざっくりと想像しやすい、そんな見た目になるような記法のルールを作る ―― コンピュータの都合で記法を考えるんじゃなくて、人間がパッと見でどう感じるか、そちらを優先して記法を作る。というアプローチだよなと。
_docopt | RubyGems.org | your community gem host
_Pythonのコマンドライン引数処理の決定版 docopt (あとJuliaに移植したよ) - りんごがでている
_docopt - shkh's blog
_docopt・language for description of command-line interfaces
一般的に、コマンドラインツールのオプション指定って、スクリプト内でどんな種類があるかチマチマと指定していくわけだけど。docoptなるライブラリを使えば、ヘルプメッセージをそのまま記述することで、どんなオプション指定があり得るのかを解析・反映してくれるらしくて。
世の中には頭がいい人が居るもんだなと、大変感心いたしました。その発想は無かった。たしかにそのほうが、記述が分かりやすい。そして、色々な場所で応用できそうな考え方のように思えたり。
いや、考えてみたら、Markdown記法もソレか…。出来上がりがざっくりと想像しやすい、そんな見た目になるような記法のルールを作る ―― コンピュータの都合で記法を考えるんじゃなくて、人間がパッと見でどう感じるか、そちらを優先して記法を作る。というアプローチだよなと。
[ ツッコむ ]
2014/06/11(水) [n年前の日記]
#1 [neta] SwiftのWindows版って無いのかなあ
有るわけないか。Appleの言語だもんな。
なんだか最近、Mac版、Linux版はあるけどWindows版はありません、てな環境が増え続けているような気がする。
なんだか最近、Mac版、Linux版はあるけどWindows版はありません、てな環境が増え続けているような気がする。
[ ツッコむ ]
#2 [ruby] 8x8行列と、4x4行列と2x2行列と、Matrixと、NMatrix
射影変換で8つの係数を求める際に、8x8の行列を作って逆行列を求めて、みたいなことをしているのですが。8x8行列を、4x4行列と2x2行列の組み合わせにすると高速化できるよ、という話があって。
_遠近法の射影変換パラメータ計算の高速化 (pdf)
_射影変換(ホモグラフィ)について理解してみる その5 - デジタル・デザイン・ラボラトリーな日々
どのくらい速くなるのか、Ruby上で試してみたのです。
_test_narray.rb を使用。
なんだか妙な結果に。
_遠近法の射影変換パラメータ計算の高速化 (pdf)
_射影変換(ホモグラフィ)について理解してみる その5 - デジタル・デザイン・ラボラトリーな日々
どのくらい速くなるのか、Ruby上で試してみたのです。
_test_narray.rb を使用。
> ruby test_narray.rb user system total real Matrix 8x8: 3.026000 0.000000 3.026000 ( 3.033174) Matrix 4x4 2x2: 1.264000 0.000000 1.264000 ( 1.257072) NMatrix 8x8: 0.421000 0.000000 0.421000 ( 0.418023) NMatrix 4x4 2x2: 0.515000 0.000000 0.515000 ( 0.515030)
なんだか妙な結果に。
- Ruby標準のMatrixを使う場合は、たしかに8x8行列より4x4、2x2行列のほうが速い。
- NArray の NMatrix を使う場合は、8x8行列のままのほうが速い。4x4、2x2行列にするとむしろ遅くなる。
[ ツッコむ ]
#3 [windows] Windows 98上で動くPDF出力仮想プリンタとPDFビューワ
VMware Player上で Windows 98を動かしているのだけど。色々問題が。
◎ 仮想プリンタ。 :
プリンタが繋がってないので、アプリ上で印刷プレビューが呼び出せないなと。どうしたもんか。
PDFを出力する仮想プリンタをインストールすればいいんじゃないかと閃いた。ググってみたら、PrimoPDF 3.1 なら Windows 98 でも動くらしい。
_XLsoft エクセルソフト : activePDF 無料 PDF 作成/変換ソフトウェア PrimoPDF 4.1 日本語版 - サポート から辿って、PrimoPDF 3.1 日本語版をDL。Windows 98 上でインストール。
設定ダイアログの下の方が切れてしまっている…。けど、一応出力できたからいいか…。
PDFを出力する仮想プリンタをインストールすればいいんじゃないかと閃いた。ググってみたら、PrimoPDF 3.1 なら Windows 98 でも動くらしい。
_XLsoft エクセルソフト : activePDF 無料 PDF 作成/変換ソフトウェア PrimoPDF 4.1 日本語版 - サポート から辿って、PrimoPDF 3.1 日本語版をDL。Windows 98 上でインストール。
設定ダイアログの下の方が切れてしまっている…。けど、一応出力できたからいいか…。
◎ PDFビューワ。 :
PDFを出力しても、閲覧できないのではよろしくないなと思えてきたので、Windows 98上でも動く Adobe Acrobat Reader を探す。
_Widows95,Windows98,WindowsMeでPDFファイルを開きたいでも開けない場合の対処法: パソコンの使い方からパソコンの使いこなし方ホームページ活用法と解決法
_Old and New Version of Adobe Reader Download - OldApps.com
Windows 98 の場合、Adobe Reader 5.05 までなら動く。以下のFTPサーバから入手。
_ftp://ftp.adobe.com/pub/adobe/acrobatreader/win/
_ftp://ftp.adobe.com/pub/adobe/acrobatreader/win/5.x/
ar505jpn.exe をDLして、Windows 98上でインストール。
6.0 は、Windows 98 SE 以上じゃないと動かない。最初分からなくて、インストールしようとしたら、「こんなOS知らねえよ」と怒られてしまった。
_Widows95,Windows98,WindowsMeでPDFファイルを開きたいでも開けない場合の対処法: パソコンの使い方からパソコンの使いこなし方ホームページ活用法と解決法
_Old and New Version of Adobe Reader Download - OldApps.com
Windows 98 の場合、Adobe Reader 5.05 までなら動く。以下のFTPサーバから入手。
_ftp://ftp.adobe.com/pub/adobe/acrobatreader/win/
_ftp://ftp.adobe.com/pub/adobe/acrobatreader/win/5.x/
ar505jpn.exe をDLして、Windows 98上でインストール。
6.0 は、Windows 98 SE 以上じゃないと動かない。最初分からなくて、インストールしようとしたら、「こんなOS知らねえよ」と怒られてしまった。
◎ 解凍ツール。 :
zipすら解凍できないのはよろしくないなと。何か解凍ツールを入れないと。
Explzh はどうかな、6.06 までは Windows 98 でも動くらしいし。と思ったのだけど、DLしてインストールしてみたら起動しない。おそらく、Explzh 6.06 が対応してるのは、Windows 98 SE じゃないのかな…。Windows 98 には対応してない気がする。
もう少しググってみたら、 _Lhaplus が対応してるらしいと分かった。1.59 をインストール。
Explzh はどうかな、6.06 までは Windows 98 でも動くらしいし。と思ったのだけど、DLしてインストールしてみたら起動しない。おそらく、Explzh 6.06 が対応してるのは、Windows 98 SE じゃないのかな…。Windows 98 には対応してない気がする。
もう少しググってみたら、 _Lhaplus が対応してるらしいと分かった。1.59 をインストール。
◎ ブラウザ。 :
IEを使うより、古い Opera を使ったほうが多少はマシらしい。
_Windows 98 関連ソフトウェア - CELLA.DAT
「最後の正式対応バージョンは9.64」と書いてあったので、ソレをインストールしておくことにする。
_Index of /pub/opera/win/964/int
Opera_964_int_Setup.exe をDLしてインストール。
_Windows 98 関連ソフトウェア - CELLA.DAT
「最後の正式対応バージョンは9.64」と書いてあったので、ソレをインストールしておくことにする。
_Index of /pub/opera/win/964/int
Opera_964_int_Setup.exe をDLしてインストール。
[ ツッコむ ]
#4 [nitijyou] 自転車で買い物に
親父さんの電動自転車を借りてホーマックとヨークベニマルに。ホーマックで靴を、ヨークベニマルで夜食や食材等を購入。
店から出たら雨が降ってた。トホホ。まあ、曇りだし、雲は厚いから、そのうち降るだろうとは思ってたけど。
店から出たら雨が降ってた。トホホ。まあ、曇りだし、雲は厚いから、そのうち降るだろうとは思ってたけど。
[ ツッコむ ]
2014/06/12(木) [n年前の日記]
#1 [windows] Wordでアルバム一覧っぽいページを作るにはどうしたらいいんだろう
親父さんから、「小さい写真をずらずらと並べて一覧にした印刷物を作るにはどうしたらいいのか」という質問を受けて、ちょっと悩んでしまったり。
親父さんの友人が過去にそういう印刷物を作っていたらしいのだけど。そこで使っていたのは Word らしいので、Word で作れるのだろうけど…。どんな作業をすればいいんだろう。
親父さんの友人が過去にそういう印刷物を作っていたらしいのだけど。そこで使っていたのは Word らしいので、Word で作れるのだろうけど…。どんな作業をすればいいんだろう。
◎ 自分も Word で試してみたり。 :
自分も Word 2003 を起動して試してみたりして。
*1
とりあえず、表を挿入して、各セルに画像を挿入していけばどうにかなりそうかなと。ただ、エクスプローラから画像ファイルをD&Dした際に、元々挿入済みだった画像がD&Dした画像で上書き消去されてしまう時があって悩んだり。
なんとなく分かってきた。あらかじめ、挿入したいセルをクリックしてカーソル位置を合わせておいて、その状態でD&Dすれば狙ったセルに対して挿入できる模様。
ググってみたら、 _アルバム作成Wordマクロ なるものを公開してくれている方が。ありがたや。しかし試してみたところ、画像の縦横比がおかしなことになってしまってガックリ。縦横比は元画像の縦横比を維持してほしいのだけど。
とりあえず、表を挿入して、各セルに画像を挿入していけばどうにかなりそうかなと。ただ、エクスプローラから画像ファイルをD&Dした際に、元々挿入済みだった画像がD&Dした画像で上書き消去されてしまう時があって悩んだり。
なんとなく分かってきた。あらかじめ、挿入したいセルをクリックしてカーソル位置を合わせておいて、その状態でD&Dすれば狙ったセルに対して挿入できる模様。
ググってみたら、 _アルバム作成Wordマクロ なるものを公開してくれている方が。ありがたや。しかし試してみたところ、画像の縦横比がおかしなことになってしまってガックリ。縦横比は元画像の縦横比を維持してほしいのだけど。
◎ OpenOffice Draw で作業してもらったり。 :
親父さんも Word + 表で作業したのだけど、やはり何かの拍子に、表内がグチャグチャになったそうで、こんなことやってられないと。
別のソフトを使ったほうがいいのかなと思えてきたので、OpenOffice Draw を薦めたり。
いざとなれば、好きなだけチマチマと、手作業で位置を調整すれば済むし。
配置時の自由度・妙な動作に遭遇せずに済むことを考えたら、OpenOffice Draw や LibreOffice Draw は、見た目を気にする印刷物を作成する場合の選択肢として、結構アリなんじゃないかと思えてきたり。
別のソフトを使ったほうがいいのかなと思えてきたので、OpenOffice Draw を薦めたり。
- OpenOffice Draw なら、自由自在に画像を配置できる。
- グリッドや補助線を表示すれば、配置作業も楽。
- 変更 → 配置 → 中央揃え(垂直)、を選べば、縦方向の位置合わせができる。
- 変更 → 分布 → 左右 → 間隔、を選べば、横方向の位置合わせもできる。
いざとなれば、好きなだけチマチマと、手作業で位置を調整すれば済むし。
配置時の自由度・妙な動作に遭遇せずに済むことを考えたら、OpenOffice Draw や LibreOffice Draw は、見た目を気にする印刷物を作成する場合の選択肢として、結構アリなんじゃないかと思えてきたり。
◎ ダミーテキストの作成。 :
操作方法を調べてる最中、ダミーテキストが欲しくなったのでググってみたら、Word も OpenOffice Writer もそういう機能があるようで。ありがたや。
_3分LifeHacking:オフィスソフトで100段落の“長文”ダミーテキストを自動生成する - 誠 Biz.ID
_一目で分かるOpenOffice 2.x の使い方 - Writer 第7回 新聞のようなレイアウト:ITpro
_3分LifeHacking:オフィスソフトで100段落の“長文”ダミーテキストを自動生成する - 誠 Biz.ID
_一目で分かるOpenOffice 2.x の使い方 - Writer 第7回 新聞のようなレイアウト:ITpro
- Word の場合は、=rand()[Enter]
- OpenOffice Writer の場合は、dt[F3キー]、can[F3]、q[F3]、cp[F3] 等
*1: 自分は Word 2007 も持っているので、セキュリティ面を考慮すれば本来そちらを使うべきだろうけど。周囲で Word 2003 を使ってる事例が多いこと、また、Word 2003 / 2007 は起動するたびに、「.doc に対するデフォルトアプリは俺だ!」とレジストリの書き換え合戦をし始めるので、Word を起動する場合は仕方なく Word 2003 を起動することが多かったりするのです。まあ、そもそも、自分しか使わない文書を作るのであれば、自分は LibreOffice Writer を起動してしまうのですけど…。
[ ツッコむ ]
#2 [zatta] 画像の縦横比を気にしない人をたまに見かけるのは何故なんだろう
ウチの親父さんもそうだし、お袋さんもそうなのだけど、画像・映像の縦横比をほとんど気にしないのが不思議なのです。ブラウン管TVで地上波TV放送を見ていた頃、4:3映像を16:9で表示していても、二人とも気にしていなかったりで。
そして、どうも世の中、画像の縦横比がおかしいことをおかしいと思わない、そんな方々が結構多いような気もするわけで。
例えば、上記記事でメモしたアルバム作成Wordマクロも、画像の縦横比を維持せずに全画像を同じ縦横比にしちゃうあたり、その事例じゃないのかなと。フツー、元画像の縦横比ぐらいは維持するもんだよなあ…。見た目が明らかにおかしくなるのだし…。いや、おかしいと思わないから、そういう仕様なのだろうけど。
更にこのあたり、何十年も前から一定数、そういう方々が存在するような気もしていて。例えば、8bit PC + BASIC で、ミンキーモモとかリンミンメイとか描いてた時代も、そういう事例を見かけた記憶があって。PC雑誌上で、明らかにモニタの縦横比がおかしいまま画面撮影しちゃって、そのまま紙面に載せていた事例を思い出したりするわけですよ。
もしかすると、色盲・色覚異常みたいな感じで、縦横比盲・縦横比覚異常、という属性も世間にはあったりするんじゃないのかと…。そうとでも思わないと、この状況は理解しがたいというか。
まあ、人間誰しも異常な部分をどこかしらに持っているのが正常、だと思いますけど。 *1 縦横比に対する感覚を測定できるテスト、とか無いのかな…。
そして、どうも世の中、画像の縦横比がおかしいことをおかしいと思わない、そんな方々が結構多いような気もするわけで。
例えば、上記記事でメモしたアルバム作成Wordマクロも、画像の縦横比を維持せずに全画像を同じ縦横比にしちゃうあたり、その事例じゃないのかなと。フツー、元画像の縦横比ぐらいは維持するもんだよなあ…。見た目が明らかにおかしくなるのだし…。いや、おかしいと思わないから、そういう仕様なのだろうけど。
更にこのあたり、何十年も前から一定数、そういう方々が存在するような気もしていて。例えば、8bit PC + BASIC で、ミンキーモモとかリンミンメイとか描いてた時代も、そういう事例を見かけた記憶があって。PC雑誌上で、明らかにモニタの縦横比がおかしいまま画面撮影しちゃって、そのまま紙面に載せていた事例を思い出したりするわけですよ。
もしかすると、色盲・色覚異常みたいな感じで、縦横比盲・縦横比覚異常、という属性も世間にはあったりするんじゃないのかと…。そうとでも思わないと、この状況は理解しがたいというか。
まあ、人間誰しも異常な部分をどこかしらに持っているのが正常、だと思いますけど。 *1 縦横比に対する感覚を測定できるテスト、とか無いのかな…。
*1: 自分も、学生時代に友人から色彩感覚が狂ってることを指摘されたし、あるいはラクガキをしていると人体のバランスがおかしいままでも全然気づかなかったりするわけで。でもまあ、せめてどこの感覚がおかしいのか、自覚ぐらいはしておきたいなと…。
[ ツッコむ ]
2014/06/13(金) [n年前の日記]
#1 [pc] OpenOfficeのマクロを勉強中
OpenOffice というか LibreOffice のマクロを勉強中。ooo basic、という呼び方でいいのかな。
表内で挿入ができない件は、 _[Solved] Writer macro to insert an image into a table cell (View topic) - Apache OpenOffice Community Forum に説明があった。
以下はエラーが出る。
以下ならエラーが出ない。
◎ アルバムページ作成マクロを書きたい。 :
先日見かけたアルバム作成マクロは、画像の縦横比がおかしい状態で並べてしまうので、そこをどうにかできたらなと。しかし、マクロにパスワードがかけられているようで、内容を確認したり、修正したりはできないようで。
仕方ないので、自分で最初から書いてみようと思ったものの…。色々ハマっている状態。
仕方ないので、自分で最初から書いてみようと思ったものの…。色々ハマっている状態。
◎ 入門。ハローワールド。 :
ググった感じでは、そもそもどうやってマクロを書き始めればいいのか、そこからして分からなかったのだけど。
_Macroの一歩(「Macro使い」への8分間)
で Hello World の流れが解説されていて助かりました。ありがたや。
リストやら入力ボックスやらを並べたUIが欲しい場合は、ダイアログを作成する。
- LibreOffice Writer を起動。
- 文書を新規作成して、名前をつけて保存。
- ツール → マクロ → マクロの管理 → LibreOffice Basic。
- 左側のツリーで、現在開いてる文書を選択 → 右側の「新規作成ボタン」をクリック。任意の名前(モジュール名)を指定。
- ooo basic IDE が開く。
リストやら入力ボックスやらを並べたUIが欲しい場合は、ダイアログを作成する。
- ツール → マクロ → ダイアログの管理。
- 現在開いてる文書を選択 → 「新規作成」ボタン → 任意のダイアログ名を指定。
- ダイアログ名を選択 → 「編集」ボタンをクリック。
- ダイアログをデザインできるウインドウが開く。
◎ LibreOfficeの「Basic IDE オプション」が気になる。 :
LibreOffice のオプション項目を眺めていたら、「Basic IDE オプション」なる項目があったのだけど。コードの補完等、なんだか魅力的な項目が並んでいるものの、全項目がグレーアウトしていて、チェックを入れることができなくて。
コレは一体何だろう…。有効にすることが可能なのか、不可能なのか…。
もしかすると LibreOffice だからダメなのか、OpenOffice なら選べるのかと気になったので、OpenOffice もインストールして確認してみたのだけど。OpenOffice のほうは、そもそも「Basic IDE オプション」なる項目自体が存在しなかった。おそらく、LibreOffice で追加された部分、なのかな…。
コレは一体何だろう…。有効にすることが可能なのか、不可能なのか…。
もしかすると LibreOffice だからダメなのか、OpenOffice なら選べるのかと気になったので、OpenOffice もインストールして確認してみたのだけど。OpenOffice のほうは、そもそも「Basic IDE オプション」なる項目自体が存在しなかった。おそらく、LibreOffice で追加された部分、なのかな…。
◎ ハマった点。 :
- ダイアログ上のコンポーネントに対してアイテム追加や値を取得する処理を書く場合、Writer文書上からマクロを実行しないと正常動作しない。IDE上でF5キーを押して動作確認しようとしても、ダイアログ上のコンポーネントにアクセスできない。
- 表内にカーソルがある状態で、oDoc.Text.insertTextContent(oViewCursor, oImage, False) 等をしても Runtime Error になる。表の外で行うと動作する・挿入できるのだけど…。
表内で挿入ができない件は、 _[Solved] Writer macro to insert an image into a table cell (View topic) - Apache OpenOffice Community Forum に説明があった。
以下はエラーが出る。
oCursor = oTable.getCellByPosition(0,0).createTextCursor() oDoc.getText.insertTextContent( oCursor, oImage, False )
以下ならエラーが出ない。
oCell = oTable.getCellByPosition(0,0) oCell.getText.insertTextContent( oCell, oImage, False )
この記事へのツッコミ
- Re: OpenOfficeのマクロを勉強中 by 名無しさん 2014/08/05 09:42
- はじめまして。
Option→詳細→実験的(不安定)なオプションを有効にすると利用できましたよ
[ ツッコミを読む(1) | ツッコむ ]
2014/06/14(土) [n年前の日記]
#1 [libreoffice] OpenOffice/LibreOffice Writerでアルバムページを作成するマクロ
たぶんそれっぽく書けた、ような気がするので一応アップロード。
◎ 概要。 :
◎ 操作方法。 :
_album_make_macro_20140614.zip
をDL・解凍して、album_make.odt を、OpenOffice / LibreOffice Writer で開いてみてください。
「アルバムを挿入」ボタンそのものは、印刷には出ない設定にしてありますので、印刷時にわざわざボタンを削除しなくてもOKです。
- 「マクロを有効化するか?」と尋ねてくるので、有効を選びます。
- 「アルバムを挿入」ボタンを押せば、ダイアログが開きます。
- 「画像を追加」ボタンを押して、画像を選んでください。複数の画像を選択できます。
- 列数その他を入力して、「画像サイズ算出」ボタンを押してください。目標画像サイズが大雑把に計算されます。
- 「アルバム作成」ボタンを押せば、文書の最後に、表形式でアルバムが挿入されます。
「アルバムを挿入」ボタンそのものは、印刷には出ない設定にしてありますので、印刷時にわざわざボタンを削除しなくてもOKです。
◎ 動作確認環境。 :
- Windows7 x64
- LibreOffice Writer 4.2.4.2
- Apache OpenOffice Writer 4.1.0
◎ ソース。 :
ooo BASIC 部分は以下の通り。
_make_album.bas
ダイアログ部分は以下の通り。
_MakeAlbumDialog.xdl
一応、ソースの中身も列挙しておきます。実験用のコードも多々残ってますが…。
_make_album.bas
ダイアログ部分は以下の通り。
_MakeAlbumDialog.xdl
一応、ソースの中身も列挙しておきます。実験用のコードも多々残ってますが…。
OPTION EXPLICIT Public oDialog as Object Public oListBox as Object Public oField1 as Object Public oField2 as Object Public oField3 as Object Public oField4 as Object Sub Main ' 表示するダイアログを指定 DialogLibraries.LoadLibrary("Standard") oDialog = CreateUnoDialog(DialogLibraries.Standard.MakeAlbumDialog) oListBox = oDialog.getControl("ListBox1") oField1 = oDialog.getControl("Field1") oField2 = oDialog.getControl("Field2") oField3 = oDialog.getControl("Field3") oField4 = oDialog.getControl("Field4") ' ダイアログを表示 If oDialog.execute() = 1 Then ' OKボタンが押された Dim itemSize as Integer itemSize = oListBox.getItemCount() ' リストボックス項目数を取得 If itemSize > 0 Then Dim oDoc as Object Dim oTbl as Object Dim oUndoMng as Object oDoc = ThisComponent ' Undo制御 oUndoMng = oDoc.getUndoManager() ' undo コンテキストの開始 oUndoMng.enterUndoContext("Undo Make Album Macro") ' 表を新規作成 MakeNewtable(GetTableColSize(), itemSize, GetTableMargin()) oTbl = GetTable If IsEmpty(oTbl) Then MsgBox "表が見つかりません" Else ' 表内に要素を挿入 AccessRowColumns(oTbl, GetImageTargetSize()) End If ' undo コンテキストを終了 oUndoMng.leaveUndoContext() End If Else ' Cancelボタンが押された Exit Sub End If End Sub ' 表の列数を取得 Function GetTableColSize GetTableColSize = CInt(oField1.getText()) End Function ' 画像目標サイズを取得 Function GetImageTargetSize GetImageTargetSize = CInt(oField2.getText()) End Function ' 表の左右マージン値を取得 Function GetTableMargin GetTableMargin = CInt(oField3.getText()) End Function ' 画像の左右マージン値を取得 Function GetImageMargin GetImageMargin = CInt(oField4.getText()) End Function ' ---------------------------------------- ' ファイル選択ダイアログを開く Sub SelectFile Dim f as Object f = createUnoService("com.sun.star.ui.dialogs.FilePicker") f.initialize( Array(com.sun.star.ui.dialogs.TemplateDescription.FILEOPEN_SIMPLE)) ' ファイルの複数選択を可能にする f.setMultiSelectionMode(True) ' 表示フィルタを追加 f.appendFilter("All Files (*.*)", "*.*") f.appendFilter("Image File", "*.bmp;*.jpg;*.gif;*.png") f.setCurrentFilter("Image File") ' デフォルトフィルタを指定 If f.execute() = 1 Then ' 選択された Dim sz as Integer Dim i as Integer Dim sFilePath as String sz = Ubound(f.selectedFiles()) For i = 0 To sz Dim nCnt as Integer ' sFilePath = ConvertFromURL(f.selectedFiles(i)) sFilePath = f.selectedFiles(i) ' リストボックスに追加 nCnt = oListBox.getItemCount() oListBox.addItem(sFilePath, nCnt) Next i End If End Sub ' ---------------------------------------- ' 1セルの幅を大雑把に取得 Sub CalcImageSize Dim pw as Long Dim cols as Integer Dim iw as Long ' ページ横幅を取得 pw = GetPagePrintWidth() ' 表の左右マージン分を減らす pw = pw - (GetTableMargin() * 2) ' 表の列数を取得 cols = CInt(oField1.getText()) ' 列数で割る iw = pw / cols ' 画像の左右マージン分を減らす iw = iw - (GetImageMargin() * 2) ' 画像サイズ指定用 InputBox に代入 oField2.setText(CStr(iw)) End Sub ' ---------------------------------------- ' 最後に挿入した表を取得 Function GetTable Dim oDoc as Object Dim oTbls as Object oDoc = ThisComponent oTbls = oDoc.TextTables If oTbls.hasElements = False Then ' 表が無い GetTable = Empty Else ' 1つ目の表オブジェクトを取得する場合 ' oTbl = oTbls.getByIndex(0) ' 最後に挿入した表を取得する場合 GetTable = oTbls.getByIndex(oTbls.getCount() -1) End If End Function ' ---------------------------------------- ' 表を新規作成 ' Sub MakeNewTable(iCols as Integer, iCellMax as Integer, margin as Integer) Dim oDoc as Object Dim iRows as Integer Dim oTbl as Object Dim oCurs as Object ' 文書を新規作成する場合 ' Dim Dummy() ' oDoc = StarDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, Dummy()) ' 現在開いてる文書を対象にする場合 oDoc = ThisComponent ' 行数を算出 iRows = iCellMax / iCols If iCellMax - (iRows * iCols) > 0 Then iRows = iRows + 1 iRows = iRows * 2 ' 表オブジェクトを作成 oTbl = oDoc.createInstance("com.sun.star.text.TextTable") oTbl.setName("AlbumTable") oTbl.initialize(iRows, iCols) ' サイズを指定 oTbl.HoriOrient = 0 ' com.sun.star.text.HoriOrientation.NONE oTbl.LeftMargin = margin oTbl.RightMargin = margin ' 文書の最終位置に表オブジェクトを挿入 oDoc.Text.insertTextContent(oDoc.Text.getEnd(), oTbl, False) ' 枠線を設定 ' SetTableBorder(oTbl) End Sub ' ---------------------------------------- ' 表の枠線設定を変更する ' Sub SetTableBorder(oTbl) Dim border as Object border = oTbl.TableBorder border.TopLine.OuterLineWidth = 0 border.BottomLine.OuterLineWidth = 0 oTbl.TableBorder = border End Sub ' ---------------------------------------- ' 行と列にアクセスする ' Sub AccessRowColumns(oTbl as Object, iw as Long) Dim ridx as Integer Dim cidx as Integer Dim rcnt as Integer Dim ccnt as Integer Dim i as Integer i = 0 rcnt = oTbl.getRows.getCount() ' 行数 ccnt = oTbl.getColumns.getCount() ' 列数 For ridx = 1 to rcnt For cidx = 1 to ccnt Dim cellname as String Dim cell as Object cellname = Chr(64 + cidx) & ridx ' "A1" "B2" 等のセル名を生成 cell = oTbl.getCellByName(cellname) ' セルにアクセス If ridx mod 2 = 0 Then ' 作者名等記入欄 ' セル内を縦方向で上揃えにする cell.VertOrient = com.sun.star.text.VertOrientation.TOP Else ' 画像欄 If i < oListBox.getItemCount() Then ' 画像ファイル名をリストボックス内から取得 Dim sUrl as String oListBox.selectItemPos(i, True) sUrl = oListBox.getSelectedItem() ' セル内容を変更する例。行:列を挿入 ' cell.string = CStr(ridx) & " : " & CStr(cidx) ' 画像を挿入 InsertTextGraphic(oTbl, cidx - 1, ridx - 1, sUrl, iw) i = i + 1 End If ' セル内を縦方向でセンタリング cell.VertOrient = com.sun.star.text.VertOrientation.CENTER End If ' セル内を横方向でセンタリング cell.createTextCursor().paraAdjust = com.sun.star.style.ParagraphAdjust.CENTER Next Next End Sub ' ---------------------------------------- ' 画像を挿入 Sub InsertTextGraphic(oTbl, col, row, sUrl, iTargetSize) Dim oDoc as Object Dim dispather as Object Dim oText as Object Dim oViewCursor as Object Dim aSize Dim aArgs(0) As New com.sun.star.beans.PropertyValue Dim oGp as Object Dim oImage as Object Dim oTxtGrp as Object oDoc = ThisComponent oViewCursor = oDoc.getCurrentController().getViewCursor() oGp = CreateUnoService("com.sun.star.graphic.GraphicProvider") aArgs(0).Name = "URL" aArgs(0).Value = sUrl oImage = oGp.queryGraphic(aArgs) oTxtGrp = oDoc.createInstance("com.sun.star.text.TextGraphicObject") oTxtGrp.Graphic = oImage aSize = oImage.Size ' Print aSize.Width & " x " & aSize.Height Dim fScale as Double If aSize.Width > aSize.Height Then fScale = CDbl(iTargetSize) / aSize.Width Else fScale = CDbl(iTargetSize) / aSize.Height End If aSize.Width = CLng(aSize.Width * fScale) aSize.Height = CLng(aSize.Height * fScale) With oTxtGrp .setSize(aSize) .VertOrient = com.sun.star.text.VertOrientation.CENTER .HoriOrient = com.sun.star.text.HoriOrientation.CENTER ' .VertOrientRelation = com.sun.star.text.RelOrientation.PAGE_PRINT_AREA ' .HoriOrientRelation = com.sun.star.text.RelOrientation.PAGE_PRINT_AREA ' .Surround = com.sun.star.text.WrapTextMode.THROUGHT ' 画像を文字として挿入 .AnchorType = com.sun.star.text.TextContentAnchorType.AS_CHARACTER End With Dim oCell as Object oCell = oTbl.getCellByPosition(col, row) ' 列、行で指定 ' oDoc.getCurrentController().select(oCell) oCell.getText.insertTextContent(oCell, oTxtGrp, True) End Sub ' 画像挿入のテスト Sub InsertTextGraphicTest Dim oTbl as Object Dim sUrl as String Dim fScale as Single sUrl = "file:///C:/home/Pictures/pub_pictures/pcd01.jpg" fScale = 2540.0 / 3 oTbl = GetTable InsertTextGraphic(oTbl, 0, 0, sUrl, fScale) End Sub ' ---------------------------------------- ' 表内のカーソル位置を取得、その1 Sub GetPosInTable Dim oDoc as Object Dim oTbl as Object Dim oVCur as Object Dim oCurCell as Object Dim oDisp as String oDoc = ThisComponent oVCur = oDoc.getCurrentController().getViewCursor() If IsEmpty(oVCur.TextTable) Then Print "The cursor is NOT in a table" Else oTbl = oVCur.TextTable oDisp = "The cursor is in cell " & oVCur.Cell.CellName Msgbox(oDisp, 0, "Curor Position in Table") End If End Sub Function InTable Dim oDoc as Object Dim oVCur as Object oDoc = ThisComponent oVCur = oDoc.getCurrentController().getViewCursor() If IsEmpty(oVCur.TextTable) Then CheckPosInTable = Empty Else CheckPosInTable = oVCur.Cell End If End Function ' ---------------------------------------- ' 表内に画像を文字として挿入してみる例 Sub InsertGraphicToTbl Dim oDoc as Object Dim oTbl as Object Dim oImage as Object Dim oCell as Object Dim sUrl as String sUrl = "file:///C:/home/Pictures/pub_pictures/pcd02.jpg" oDoc = ThisComponent oTbl = GetTable oImage = oDoc.createInstance("com.sun.star.text.GraphicObject") oImage.GraphicURL = sUrl oImage.AnchorType = com.sun.star.text.TextContentAnchorType.AS_CHARACTER oImage.Width = 3000 oImage.Height = 3000 oCell = oTbl.getCellByPosition(0,0) oCell.getText.insertTextContent( oCell, oImage, False ) End Sub ' ---------------------------------------- ' 画像をリンク形式で挿入する例 Sub InsertTextGraphicLink(sUrl as String, enableChara as Boolean) Dim oDoc as Object Dim oViewCursor as Object Dim oImage as Object Dim aSize As New com.sun.star.awt.Size oDoc = ThisComponent oViewCursor = oDoc.getCurrentController().getViewCursor() aSize.Width = 2000 aSize.Height = 2000 oImage = oDoc.createInstance("com.sun.star.text.TextGraphicObject") oImage.GraphicURL = sUrl oImage.Size = aSize If enableChara Then ' 画像を文字として挿入 oImage.AnchorType = com.sun.star.text.TextContentAnchorType.AS_CHARACTER End If ' 表内には挿入できない oDoc.Text.insertTextContent(oViewCursor, oImage, False) End Sub Sub InsertTextGraphicLinkTest InsertTextGraphicLink("file:///C:/home/Pictures/pub_pictures/pcd03.jpg", True) End Sub ' ---------------------------------------- ' 画像のサイズを取得 ' ' OOoBasic/Generic/Image - ...? ' http://hermione.s41.xrea.com/pukiwiki/index.php?OOoBasic%2FGeneric%2FImage Function GetImageSize(sUrl) Dim oGP as Object Dim oSFA as Object Dim oImgInput as Object Dim oGraphic as Object Dim aSizePixel as Object Dim aSize(2) as Integer oGP = CreateUnoService("com.sun.star.graphic.GraphicProvider") oSFA = CreateUnoService("com.sun.star.ucb.SimpleFileAccess") oImgInput = oSFA.openFileRead(sUrl) Dim aImgDesc(0) As New com.sun.star.beans.PropertyValue aImgDesc(0).Name = "InputStream" aImgDesc(0).Value = oImgInput oGraphic = oGP.queryGraphic(aImgDesc) aSizePixel = oGraphic.SizePixel aSize(0) = aSizePixel.Width aSize(1) = aSizePixel.Height oImgInput.closeInput() GetImageSize = aSize End Function Sub GetImageSizeTest Dim ret(2) as Integer ret = GetImageSize("file://C:/home/Pictures/pub_pictures/pcd09.jpg") msgbox "Width x height = " & CStr(ret(0)) & " x " & CStr(ret(1)) End Sub ' ---------------------------------------- ' 表の幅を取得してみるテスト ' ' 表を新規作成した場合、巨大な値しか返ってこない… Sub GetCellSize Dim oDoc as Object Dim oTbl as Object Dim csize as Integer Dim w as Integer Dim tw as Long Dim margin as Long margin = 100 oDoc = ThisComponent oTbl = GetTable ' print oTbl.TableColumnRelativeSum If False Then ' 表の幅を、左マージン・右マージン指定により設定し直す oTbl.HoriOrient = com.sun.star.text.HoriOrientation.NONE oTbl.LeftMargin = margin oTbl.RightMargin = margin End If ' 列数を取得 csize = oTbl.getColumns.getCount() ' 表の幅を取得 tw = oTbl.Width ' tw = oTbl.RelativeWidth Dim oTblColSeps oTblColSeps = oTbl.TableColumnSeparators ' print "ColumnSeparators (1) = " & oTblColSeps(1).Position w = tw / csize - 400 print "Table Width = " & tw & " cell w = " & w End Sub ' ---------------------------------------- ' ページの印刷可能範囲の横幅を取得 Function GetPagePrintWidth Dim oDoc As Object Dim oStyleFamilies As Object Dim oPageStyles As Object Dim oPageStyle As Object Dim pagePrintWidth as Long oDoc = ThisComponent oStyleFamilies = oDoc.StyleFamilies oPageStyles = oStyleFamilies.getByName("PageStyles") oPageStyle = oPageStyles.getByName("Standard") pagePrintWidth = oPageStyle.Width - oPageStyle.LeftMargin - oPageStyle.RightMargin ' print pagePrintWidth GetPagePrintWidth = pagePrintWidth End Function ' ---------------------------------------- ' ページスタイルを取得してみるテスト Sub pagestylescontainer_elements Dim oDoc As Object Dim oStyleFamilies As Object Dim oPageStyles As Object Dim oPageStyle As Object Dim aStyleNames() As String Dim i As Integer Dim str as String Dim pagePrintWidth as Long oDoc = ThisComponent oStyleFamilies = oDoc.StyleFamilies oPageStyles = oStyleFamilies.getByName("PageStyles") aStyleNames() = oPageStyles.getElementNames() str = "" For i = 0 To UBound(aStyleNames()) str = str & aStyleNames(i) & Chr(10) Next i MsgBox str oPageStyle = oPageStyles.getByName("Standard") print "page width = " & oPageStyle.Width print "page left margin = " & oPageStyle.LeftMargin print "page right margin = " & oPageStyle.RightMargin pagePrintWidth = oPageStyle.Width - oPageStyle.LeftMargin - oPageStyle.RightMargin print "page width = " & oPageStyle.Width & " print width = " & pagePrintWidth End Sub
◎ 参考ページ。 :
_Macroの一歩(「Macro使い」への8分間)
_OSS( Open Source Software )でいこう!!「 OpenOffice.org / LibreOfficeを使おう編 」
_OpenOffice.org Basic - Wikibooks
_OOoBasic - ...?
_[Solved] Writer macro to insert an image into a table cell (View topic) - Apache OpenOffice Community Forum
_OpenOffice.org BASIC プログラミングガイド - Apache OpenOffice Wiki
_文書ドキュメント: テキスト以外のオブジェクト - Apache OpenOffice Wiki
_LibreOffice Calc Basic fun!!!: リストボックスを操作する (1)
_System-9 - Libre Office Basic マクロ 1
_System-9 - Libre Office Basic マクロ 6
_グローバル変数を使用してマクロを分かりやすくする LibreOffice Calc Basic:ubuntu10-12 LibreOffice4:So-netブログ
_Service TextTable
_OSS( Open Source Software )でいこう!!「 OpenOffice.org / LibreOfficeを使おう編 」
_OpenOffice.org Basic - Wikibooks
_OOoBasic - ...?
_[Solved] Writer macro to insert an image into a table cell (View topic) - Apache OpenOffice Community Forum
_OpenOffice.org BASIC プログラミングガイド - Apache OpenOffice Wiki
_文書ドキュメント: テキスト以外のオブジェクト - Apache OpenOffice Wiki
_LibreOffice Calc Basic fun!!!: リストボックスを操作する (1)
_System-9 - Libre Office Basic マクロ 1
_System-9 - Libre Office Basic マクロ 6
_グローバル変数を使用してマクロを分かりやすくする LibreOffice Calc Basic:ubuntu10-12 LibreOffice4:So-netブログ
_Service TextTable
◎ まだ分かってない点。 :
どう書けばいいのか分からなくて結局諦めてしまったのですが、LibreOffice Writer 上で、表(TextTable)の横幅、もしくはセルの横幅が取得できないという問題が残っていて。セル一つ分の横幅を取得したいけどやり方が分からず。であれば、表の横幅を列数で割れば求められるかな、と思ったのだけど、これも上手く行かず。
表を新規作成して挿入した直後、.Width で表の横幅を取得すると、とんでもなく大きな値(Long値)が返ってきてしまう。これでは計算に使えない…。ややこしいことに、マウスで表の外枠をちょっとでもドラッグして表のサイズを変更した後なら、Integer で収まる値が返ってくるようになる。どうしてこんなことになるのか…。訳が分かりません。
仕方ないので、ページ横幅やページ余白から、表の横幅を大雑把に求めて誤魔化してみたけれど。表の横幅、もしくはセルの横幅を取得できればもっとすっきり書けそう。
困ったことに、「openoffice cell width」等で検索しても、Openoffice Calc (表計算ソフト)の情報ばかり出てきてしまう。Calc じゃなくて Writer(ワープロソフト)上でどう書けばいいのかを知りたいのだけど…。
表を新規作成して挿入した直後、.Width で表の横幅を取得すると、とんでもなく大きな値(Long値)が返ってきてしまう。これでは計算に使えない…。ややこしいことに、マウスで表の外枠をちょっとでもドラッグして表のサイズを変更した後なら、Integer で収まる値が返ってくるようになる。どうしてこんなことになるのか…。訳が分かりません。
仕方ないので、ページ横幅やページ余白から、表の横幅を大雑把に求めて誤魔化してみたけれど。表の横幅、もしくはセルの横幅を取得できればもっとすっきり書けそう。
困ったことに、「openoffice cell width」等で検索しても、Openoffice Calc (表計算ソフト)の情報ばかり出てきてしまう。Calc じゃなくて Writer(ワープロソフト)上でどう書けばいいのかを知りたいのだけど…。
◎ 分かった点をメモ。 :
ダイアログ上で、OKボタン、キャンセルボタンを押した際に違う値が返ってくる、と解説ページには書いてあったのだけど。そのOKボタン、キャンセルボタンってどれよ…。と思ったら、フツーにボタンを配置して、ボタンの種類を、OK/キャンセルに設定すればよかったようで。
Writer上の表・セルの中で、縦方向にセンタリング(中央揃え)をする方法が分からなかったのだけど。
Writer上の表・セルの中で、縦方向にセンタリング(中央揃え)をする方法が分からなかったのだけど。
cell.VertOrient = com.sun.star.text.VertOrientation.CENTERといった指定でできるらしい、とメモ。
[ ツッコむ ]
2014/06/15(日) [n年前の日記]
#1 [python] Python 2.7.6でsetuptoolsやpipをインストールしようとしてハマった
以下の症状でハマりました。
_2013/12/19 Python-2.7.6がWindows環境でmimetypes.init()に失敗する場合がありsetuptoolsがインストールできない話 - 清水川Web
_[Python-ml-jp 5663] Windows 用の Python 2.7.6 に setuptools 2.0.1 を設置できなかった話
_[Python-ml-jp 5664] Re: Windows 用の Python 2.7.6 に setuptools 2.0.1 を設置できなかった話
_姫踊子草の楽屋裏 Windows 用の Python 2.7.6 に setuptools 2.0.1 を設置できなかった話
_Issue 9291: mimetypes initialization fails on Windows because of non-Latin characters in registry - Python tracker
_cpython: 18cfc2a42772
以下を参考にして作業。
_http://hg.python.org/cpython/raw-file/18cfc2a42772/Lib/mimetypes.py から、mimetypes.py をDLして、Python2.7.6インストールフォルダ\Lib\mimetypes.py を置き換えました。
と、ここまでやってたら、 _Windows 7 / Python 2.7.6 にて ez_setup.py にて UnicodeDecodeError が出て困ったけど解決した件 - secretbase.log という記事に遭遇。
_2013/12/19 Python-2.7.6がWindows環境でmimetypes.init()に失敗する場合がありsetuptoolsがインストールできない話 - 清水川Web
_[Python-ml-jp 5663] Windows 用の Python 2.7.6 に setuptools 2.0.1 を設置できなかった話
_[Python-ml-jp 5664] Re: Windows 用の Python 2.7.6 に setuptools 2.0.1 を設置できなかった話
_姫踊子草の楽屋裏 Windows 用の Python 2.7.6 に setuptools 2.0.1 を設置できなかった話
_Issue 9291: mimetypes initialization fails on Windows because of non-Latin characters in registry - Python tracker
_cpython: 18cfc2a42772
以下を参考にして作業。
ノート 2014/5/5追記
Python本家のバグチケット( http://bugs.python.org/issue9291 )がクローズされたようです。 http://hg.python.org/cpython/rev/18cfc2a42772 にある差分(か http://hg.python.org/cpython/raw-file/18cfc2a42772/Lib/mimetypes.py のファイル) をPython-2.7.6に適用したところ、問題が再現しなくなりました。2013/12/19 Python-2.7.6がWindows環境でmimetypes.init()に失敗する場合がありsetuptoolsがインストールできない話 - 清水川Web より
_http://hg.python.org/cpython/raw-file/18cfc2a42772/Lib/mimetypes.py から、mimetypes.py をDLして、Python2.7.6インストールフォルダ\Lib\mimetypes.py を置き換えました。
と、ここまでやってたら、 _Windows 7 / Python 2.7.6 にて ez_setup.py にて UnicodeDecodeError が出て困ったけど解決した件 - secretbase.log という記事に遭遇。
Python 2.7.7 にて下記不具合として修正されていますので、2.7.7を使いましょう。2.7.7が出てたのかー。Windows 7 / Python 2.7.6 にて ez_setup.py にて UnicodeDecodeError が出て困ったけど解決した件 - secretbase.log より
◎ Python 2.7.7 をインストール。 :
Python 2.7.6 をアンインストールして、Python 2.7.7 をインストールした。
ふと気づいたら、GIMP 2.6.12 の Python-fu が動かなくなっていた。Python 2.6.6 をアンインストールしてインストールし直したり。
相変わらず Python-fu が動かない。何度かアンインストール、再インストールを繰り返したけど問題解決せず。
ふと、別のショートカットファイルから GIMP を起動したら、Python-fu が動くことに気付いた。ショートカットファイルの設定で、作業フォルダに %USERPROFILE% を指定している場合は、Python-fu が動くらしい。…なんでだろ。
ふと気づいたら、GIMP 2.6.12 の Python-fu が動かなくなっていた。Python 2.6.6 をアンインストールしてインストールし直したり。
相変わらず Python-fu が動かない。何度かアンインストール、再インストールを繰り返したけど問題解決せず。
ふと、別のショートカットファイルから GIMP を起動したら、Python-fu が動くことに気付いた。ショートカットファイルの設定で、作業フォルダに %USERPROFILE% を指定している場合は、Python-fu が動くらしい。…なんでだろ。
[ ツッコむ ]
#2 [windows] Windows7 x64 に curl をインストール
Python 関係のパッケージ?インストール解説記事中で curl というコマンドラインのダウンローダ?を使っていたので、試しに自分も導入。
_cURL - Download の下の方にある 「Win32 - Generic」のどれかを選択。
今回は、 _cURL groks URLs - CURL 7.37.0 から、curl_737_0_ssl.zip をDLした。
解凍して、curl.exe を、パスの通ったところにコピー。
このままだと、https でアクセスできないらしいので、以下を参考に作業。
_Why can't cURL properly verify a certificate on Windows? - Super User
_cURL - Extract CA Certs from Mozilla
cacert.pem をDLして、curl.exe と同じ階層に、curl-ca-bundle.crt というファイル名でコピー。
あるいは、--insecure をつけることでも、https でアクセスできる?
_WindowsR環境にcURLコマンドを実行できるようにインストールする手順 | ええかげんブログ(本店)
_cURL - Download の下の方にある 「Win32 - Generic」のどれかを選択。
今回は、 _cURL groks URLs - CURL 7.37.0 から、curl_737_0_ssl.zip をDLした。
解凍して、curl.exe を、パスの通ったところにコピー。
このままだと、https でアクセスできないらしいので、以下を参考に作業。
_Why can't cURL properly verify a certificate on Windows? - Super User
_cURL - Extract CA Certs from Mozilla
cacert.pem をDLして、curl.exe と同じ階層に、curl-ca-bundle.crt というファイル名でコピー。
あるいは、--insecure をつけることでも、https でアクセスできる?
_WindowsR環境にcURLコマンドを実行できるようにインストールする手順 | ええかげんブログ(本店)
curl --insecure https://www.google.co.jp/といった指定でもイケるらしい。
[ ツッコむ ]
#3 [python] 画像の周辺の黒い部分をトリミングするPythonスクリプト
Python + PIL で、トリミング作業の実験。
getbbox() で、周辺の黒い部分を取り除いた領域の値を得られるらしい。
そんな便利なメソッドがあったとは知らなかったものだから、画像のドット数分、getpixel() を使って1ドットずつチマチマと全部チェックして、コレはさすがに処理が遅すぎるわ、高速化できんかなー、とか思ってました。getbbox() を使ったら一瞬で処理が終わってしまった…。
from optparse import OptionParser import os.path import glob try: import Image except ImportError: from PIL import Image ver = "0.0.1" def chk_args(): """コマンドラインオプションを解析.""" parser = OptionParser(usage = "%prog [--trim] img\*.png", version = "%prog " + ver) parser.add_option("--trim", dest="trim", action="store_true", default=False, help="Trim exec") (opts, args) = parser.parse_args() if len(args) == 0: parser.print_help() exit return (opts, args) def open_image(fn, enable_trim): """画像ファイルを開いて情報を調べる.""" if not os.path.isfile(fn): print "Not Found %s" % fn return im = Image.open(fn).convert('RGB') w, h = im.size xmin, ymin, xmax, ymax = im.getbbox() xw = xmax - xmin yh = ymax - ymin print "DrawArea (%d, %d) - (%d, %d) : %d x %d : Img Size %d x %d : %s" % \ (xmin, ymin, xmax, ymax, xw, yh, w, h, fn) if enable_trim: region = im.crop((xmin, ymin, xmax, ymax)) dn = os.path.dirname(fn) bn = os.path.basename(fn) new_fn = os.path.join(dn, "trim_%s" % bn) region.save(new_fn) def main(): (opts, args) = chk_args() for fng in args: for fn in glob.glob(fng): open_image(fn, opts.trim) if __name__ == '__main__': main()
getbbox() で、周辺の黒い部分を取り除いた領域の値を得られるらしい。
そんな便利なメソッドがあったとは知らなかったものだから、画像のドット数分、getpixel() を使って1ドットずつチマチマと全部チェックして、コレはさすがに処理が遅すぎるわ、高速化できんかなー、とか思ってました。getbbox() を使ったら一瞬で処理が終わってしまった…。
◎ 2014/06/17追記。 :
[ ツッコむ ]
2014/06/16(月) [n年前の日記]
#1 [nitijyou] 朝方に地震
AM03:19と、AM05:14頃に地震。特に後者は揺れが激しく。急いで部屋の出口まで走ったぐらいに揺れました。
[ ツッコむ ]
#2 [golang] Go言語を少しだけ勉強中
昨日 Python + PIL でちょっとしたスクリプトを書いた際に処理が遅いなと感じたので、もっと高速に処理ができて、かつ、簡単に書ける何かって無いのかなと興味が湧いたわけで。ということで、今頃になって、Go言語とやらをちょっと調べて触ってみたり。
フツーに「go」で検索すると関係ないページが次々にリストアップされてしまうので、「golang」と呼んでる場合が多いらしい。「Processing」を「proce55ing」と呼んだりするようなもんかな…。どうしてこの手の言語は、検索しにくい単語をわざわざ選ぶんだろう。まあ、「Apple」とか「Windows」も、たいがいにせえやって感じではありますけど。
フツーに「go」で検索すると関係ないページが次々にリストアップされてしまうので、「golang」と呼んでる場合が多いらしい。「Processing」を「proce55ing」と呼んだりするようなもんかな…。どうしてこの手の言語は、検索しにくい単語をわざわざ選ぶんだろう。まあ、「Apple」とか「Windows」も、たいがいにせえやって感じではありますけど。
◎ コンパイラのインストール。 :
_Downloads - The Go Programming Language
から、go1.2.2.windows-386.msi をDLして実行。C:\Go\ にインストールした。.msi でインストールしたので、環境変数 PATH も設定してくれた。
DOS窓で go[Enter] と入力。ヘルプが表示されたらインストールは成功している。
以下のソースを hello.go として作成。
DOS窓で go[Enter] と入力。ヘルプが表示されたらインストールは成功している。
以下のソースを hello.go として作成。
package main import "fmt" func main() { fmt.Printf("Hello World\n") }go run hello.go を実行。「Hello World」とメッセージが表示された。ビルドも実行も成功しているらしい。
◎ Go言語用のIDEを導入。 :
Go言語には、LiteIDE なるIDEが存在するらしいので、試しに導入してみる。
_liteide | Free software downloads at SourceForge.net から、liteidex22.windows.7z をDLして解凍。任意のフォルダにコピー。
インストールフォルダ\liteide\bin\liteide.exe を実行すれば、起動する。
環境変数 GOROOT を設定する。ツールバー上で「System」を選んで、右側のボタンを押す。設定ファイルが開かれるので、GOROOT と書かれてる行を修正。C:\Go\ を設定すればいいのかな。たぶん。
環境変数 GOPATH を設定する。View → Manage GOPATH → 下の欄に追加。自分のプロジェクトを保存する場所を指定すればいいらしいけどよくわかってない。
_liteide | Free software downloads at SourceForge.net から、liteidex22.windows.7z をDLして解凍。任意のフォルダにコピー。
インストールフォルダ\liteide\bin\liteide.exe を実行すれば、起動する。
環境変数 GOROOT を設定する。ツールバー上で「System」を選んで、右側のボタンを押す。設定ファイルが開かれるので、GOROOT と書かれてる行を修正。C:\Go\ を設定すればいいのかな。たぶん。
環境変数 GOPATH を設定する。View → Manage GOPATH → 下の欄に追加。自分のプロジェクトを保存する場所を指定すればいいらしいけどよくわかってない。
◎ Mercurial をインストール。 :
godef なる便利ツールをインストールする際に Mercurial というバージョン管理システムが必要になるらしいので、一応インストール。
Mercurial をインストールする場合、一般的には TortoiseHg という、GUIで操作可能、かつ、Windowsのエクスプローラに組み込むような感じのツールを導入すると簡単らしいのだけど。自分の環境は、既に _TortoiseSVN と _TortoiseGit をインストールしてあって。これ以上エクスプローラにこの手のツールを組み込むとますます不安定になりそうなので、今回 TortoiseHg はインストールしないことにした。
_JapaneseDownload - Mercurial から、mercurial-3.0.1-x86.msi をDLして実行。デフォルト設定でインストールした。C:\Program Files (x86)\Mercurial\ にインストールされたらしい。.msi でインストールしたので、環境変数 PATH も設定された模様。DOS窓で hg help とか hg version と打ち込んだら色々表示された。
Mercurial をインストールする場合、一般的には TortoiseHg という、GUIで操作可能、かつ、Windowsのエクスプローラに組み込むような感じのツールを導入すると簡単らしいのだけど。自分の環境は、既に _TortoiseSVN と _TortoiseGit をインストールしてあって。これ以上エクスプローラにこの手のツールを組み込むとますます不安定になりそうなので、今回 TortoiseHg はインストールしないことにした。
_JapaneseDownload - Mercurial から、mercurial-3.0.1-x86.msi をDLして実行。デフォルト設定でインストールした。C:\Program Files (x86)\Mercurial\ にインストールされたらしい。.msi でインストールしたので、環境変数 PATH も設定された模様。DOS窓で hg help とか hg version と打ち込んだら色々表示された。
◎ EmacsにGo言語用のアレコレを設定。 :
勉強するだけなら LiteIDE を使えば十分のような気もするのだけど、EmacsでGo言語を書くためのlispが用意されてるらしいので試しにそちらも導入。
C:\Go\misc\emacs\*.el を emacs のロードパスの通った場所にコピー。
gocode と godef をインストール。この段階で、Mercurial (hg)が必要になる。また、環境変数 GOPATH が設定されてる必要があるらしい。
gocode に何か色々設定。
go-autocomplete.el も、emacsのロードパスの通った場所にコピー。%GOPATH%\src\github.com\nsf\gocode\emacs\go-autocomplete.el からコピーしてくる。
~/.emacs に以下を追加。
*.go を開いたら色分け表示されるようになった。また、例えば fmt. と打つと候補がリストアップされた。auto-complete.el とやらを有効にしてる場合は、そういう動作になるらしい。
C:\Go\misc\emacs\*.el を emacs のロードパスの通った場所にコピー。
gocode と godef をインストール。この段階で、Mercurial (hg)が必要になる。また、環境変数 GOPATH が設定されてる必要があるらしい。
go get code.google.com/p/rog-go/exp/cmd/godef go get -u github.com/nsf/gocode
gocode に何か色々設定。
> gocode set propose-builtins true propose-builtins true > gocode set lib-path "C:\home\mieki256\gocode\pkg\windows_386" lib-path "C:\home\mieki256\gocode\pkg\windows_386" > gocode set propose-builtins true lib-path "C:\home\mieki256\gocode\pkg\windows_386" autobuild false
go-autocomplete.el も、emacsのロードパスの通った場所にコピー。%GOPATH%\src\github.com\nsf\gocode\emacs\go-autocomplete.el からコピーしてくる。
~/.emacs に以下を追加。
;; ---------------------------------------- ;; Golang (require 'go-mode-load) (require 'go-autocomplete) (require 'auto-complete-config) ;; (speedbar-add-supported-extension ".go") (add-hook 'go-mode-hook '(lambda() (auto-complete-mode 1) (setq ac-sources '(ac-source-go)) (setq c-basic-offset 4) (setq indent-tabs-mode t) (local-set-key (kbd "M-.") 'godef-jump) (local-set-key (kbd "C-c C-r") 'go-remove-unused-imports) (local-set-key (kbd "C-c i") 'go-goto-imports) (local-set-key (kbd "C-c d") 'godoc) (define-key ac-mode-map (kbd "M-TAB") 'auto-complete))) (add-hook 'before-save-hook 'gofmt-before-save)
*.go を開いたら色分け表示されるようになった。また、例えば fmt. と打つと候補がリストアップされた。auto-complete.el とやらを有効にしてる場合は、そういう動作になるらしい。
◎ 参考ページ。 :
_Go言語のインストール - golang.jp
_Downloads - The Go Programming Language
_Windowsユーザがgo言語の開発環境を構築する ・ さにあらず
_golangide - LiteIDE Released for Go - Google Project Hosting
_liteide | Free software downloads at SourceForge.net
_Go言語の初心者が見ると幸せになれる場所 - Qiita
_JapaneseDownload - Mercurial
_バージョン管理「Mercurial」の導入 - DateBooks
_EmacsでのGo言語編集環境 - unknownplace.org
_EmacsでのGo言語編集環境(Linux編) - Life is very short
_Emacsを使ったGo言語開発手法(2013.07版) - YAMAGUCHI::weblog
_Downloads - The Go Programming Language
_Windowsユーザがgo言語の開発環境を構築する ・ さにあらず
_golangide - LiteIDE Released for Go - Google Project Hosting
_liteide | Free software downloads at SourceForge.net
_Go言語の初心者が見ると幸せになれる場所 - Qiita
_JapaneseDownload - Mercurial
_バージョン管理「Mercurial」の導入 - DateBooks
_EmacsでのGo言語編集環境 - unknownplace.org
_EmacsでのGo言語編集環境(Linux編) - Life is very short
_Emacsを使ったGo言語開発手法(2013.07版) - YAMAGUCHI::weblog
[ ツッコむ ]
2014/06/17(火) [n年前の日記]
#1 [golang] Go言語とGUI
Go言語を使ってGUIアプリは作れないのかなと気になったのです。ググってみたら、以下のページで解説が。
_WindowsでGo言語でGUIするにはWALKがいいかもしれない - Qiita
_Golang GUI (Windows) | Labelier
_Go Bindings for Various External APIs
Windows環境の場合、walk というライブラリを使うといいらしいので、少し触ってみようかなと。
インストールは以下。
例えば、hoge.go , hoge.exe を作るなら、hoge.exe.manifest も必要になる。
サンプルは、%GOPATH%\src\github.com\lxn\walk\examples\ 以下に入ってる。manifestの書き方も、サンプルを参考にすればいい。
*.go が置いてあるフォルダで、
サンプルをビルドして確認していたけど。たしかに、VisualuRuby っぽい感じがする…。
_WindowsでGo言語でGUIするにはWALKがいいかもしれない - Qiita
_Golang GUI (Windows) | Labelier
_Go Bindings for Various External APIs
Windows環境の場合、walk というライブラリを使うといいらしいので、少し触ってみようかなと。
インストールは以下。
go get github.com/lxn/walk
例えば、hoge.go , hoge.exe を作るなら、hoge.exe.manifest も必要になる。
サンプルは、%GOPATH%\src\github.com\lxn\walk\examples\ 以下に入ってる。manifestの書き方も、サンプルを参考にすればいい。
*.go が置いてあるフォルダで、
go buildまたは
go build -ldflags="-H windowsgui"でビルドできる。(.exeが出来上がる)
サンプルをビルドして確認していたけど。たしかに、VisualuRuby っぽい感じがする…。
◎ go-gtkも気になるのだけど。 :
go-gtk も Windows上で動くらしいので気になったのだけど、導入の仕方がさっぱり分からなくて諦めました。たぶん GTK からしてインストールしないといかんのだろうけど、バージョン決め打ちだったりしそう…。
ていうか個人的に GTK はなんだか怖くて。
以前 Windows環境で GTK をインストール・アンインストールしたら、環境変数 PATH を全消去してくれやがったのです。つまりはOSをぶっ壊しやがったんです。まあ、GTK自体がアレじゃなくて、インストーラのバグだったらしいですけど。しかし、そんな怖いバグ入り版を配布していても、誰も気づいてなかった・報告しなかった・改善版が出てこなかったあたりが、ますます怖くて。開発状況はどうなってるんだろう…。
自分の環境だけなら、その手の問題があってもどうにかできるかもしれんけど。他の環境でも使えるようにと考えたりするなら、ちょっと怖いよなと…。
ていうか個人的に GTK はなんだか怖くて。
以前 Windows環境で GTK をインストール・アンインストールしたら、環境変数 PATH を全消去してくれやがったのです。つまりはOSをぶっ壊しやがったんです。まあ、GTK自体がアレじゃなくて、インストーラのバグだったらしいですけど。しかし、そんな怖いバグ入り版を配布していても、誰も気づいてなかった・報告しなかった・改善版が出てこなかったあたりが、ますます怖くて。開発状況はどうなってるんだろう…。
自分の環境だけなら、その手の問題があってもどうにかできるかもしれんけど。他の環境でも使えるようにと考えたりするなら、ちょっと怖いよなと…。
◎ GUIとクロスプラットフォーム。 :
Go言語自体は、Linux、Mac、Windows で使えるらしいけど。GUIライブラリを使おうとすると、途端にクロスプラットフォームではなくなってしまうあたりが厳しいなと。
クロスプラットフォームでGUIアプリを、と考えたら Java でも使うしかないのかな…。
クロスプラットフォームでGUIアプリを、と考えたら Java でも使うしかないのかな…。
[ ツッコむ ]
#2 [anime][neta] ラブリーゴブリン
幸福充填プリキュアのOPで、毎回「ラブリーゴブリン」と歌っているように聞こえていたのですけど。
今日、たまたま画面を見ていたら、「ラブリーコンプリート」と歌詞テロップが表示されていて。自分の耳はもうダメだと思いました。
やっぱり歌詞テロップって大事だなと。
それはともかく今回のプリキュアって、ずっと作画が怪しいというか微妙な感じが続いているのだけど、一体どうしちゃったんだろう…。
今日、たまたま画面を見ていたら、「ラブリーコンプリート」と歌詞テロップが表示されていて。自分の耳はもうダメだと思いました。
やっぱり歌詞テロップって大事だなと。
それはともかく今回のプリキュアって、ずっと作画が怪しいというか微妙な感じが続いているのだけど、一体どうしちゃったんだろう…。
[ ツッコむ ]
#3 [firefox] Firefoxのスタートページのアニメ画像がウザい
ここ数日、Firefox起動時に、サッカーっぽい画像が強制的に表示されるのですけど。自分、スポーツは大嫌いなので、サッカー画像を目にするだけでゲンナリしていて。この動作、設定で変えられないのかな…。
「そのくらいでガタガタ言うな」とか「サッカーのどこがいかんのだ」とか「皆盛り上がってるだろ」とか言い出すヤツが居そうだけど。そういう考え方ではあかんよと。例えば、阪神ファンのブラウザ画面に巨人選手の画像を毎回強制表示するブラウザ仕様だったらどうよ? 「あかんわー。そりゃあかんですわー」ってわかるでしょ。要するに「自分の趣味が他の全員にも受け入れられるはずだと思い込んで」「ソレを不特定多数に強制的に見せつける」ことを「あかんわ」と思わないようではあかんわけですよ。だから、Firefox起動時のスタートページのサッカー画像はNG。趣味を強制してんじゃねえよと。
まあ、こんなの各個人の趣味に合わせてカスタマイズができれば済んでしまう話なんですけど…。
しかし、Firefox はそのあたり融通が利かなくて。ホームページそのものを変更する手段しか用意されてない。Firefox標準のスタートページって、下部の方によく使う機能へのショートカットが並んでたりするので、アニメ画像だけ差し替えられたらありがたいのだけど…。実機能と、趣味要素の強い画像を、同列に扱って1ページ内にレイアウトしちゃうなんて、一体何を考えてるんだ。バカじゃねえのか。プンスカ。
せめて、Google並みに、1日おきに画像を変える、てな根性見せるならともかく…。何日もの間、毎回必ずソレが出るからあかんわけですよ。頻繁に変化があるなら、「まあ、今日一日だけだし…」と我慢もできるわけですよ。しかし、そういうことができるほどのリソースもないくせして、なんとなくでGoogleの真似してんじゃねえよと。薄っぺらいんだよ。と思います。
ということで色々ググってみたけど、画像だけ差し替える設定は見つからず。これはもう、スタートページそのものを変更するしか手はないのかな…。
「そのくらいでガタガタ言うな」とか「サッカーのどこがいかんのだ」とか「皆盛り上がってるだろ」とか言い出すヤツが居そうだけど。そういう考え方ではあかんよと。例えば、阪神ファンのブラウザ画面に巨人選手の画像を毎回強制表示するブラウザ仕様だったらどうよ? 「あかんわー。そりゃあかんですわー」ってわかるでしょ。要するに「自分の趣味が他の全員にも受け入れられるはずだと思い込んで」「ソレを不特定多数に強制的に見せつける」ことを「あかんわ」と思わないようではあかんわけですよ。だから、Firefox起動時のスタートページのサッカー画像はNG。趣味を強制してんじゃねえよと。
まあ、こんなの各個人の趣味に合わせてカスタマイズができれば済んでしまう話なんですけど…。
しかし、Firefox はそのあたり融通が利かなくて。ホームページそのものを変更する手段しか用意されてない。Firefox標準のスタートページって、下部の方によく使う機能へのショートカットが並んでたりするので、アニメ画像だけ差し替えられたらありがたいのだけど…。実機能と、趣味要素の強い画像を、同列に扱って1ページ内にレイアウトしちゃうなんて、一体何を考えてるんだ。バカじゃねえのか。プンスカ。
せめて、Google並みに、1日おきに画像を変える、てな根性見せるならともかく…。何日もの間、毎回必ずソレが出るからあかんわけですよ。頻繁に変化があるなら、「まあ、今日一日だけだし…」と我慢もできるわけですよ。しかし、そういうことができるほどのリソースもないくせして、なんとなくでGoogleの真似してんじゃねえよと。薄っぺらいんだよ。と思います。
ということで色々ググってみたけど、画像だけ差し替える設定は見つからず。これはもう、スタートページそのものを変更するしか手はないのかな…。
◎ アドオンでどうにかなりそう。 :
_Mozilla Re-Mix: Firefoxの[新規タブ]ページと[ホーム]ページを統合できるアドオン「Homepage New Tab」
経由で、
_Homepage New Tab :: Add-ons for Firefox
をインストールしてみたり。
ウザいサッカー画像が消えてくれた。しばらくはこれで様子を見よう…。ホームページを表示するたび、再レイアウトするあたりがちょっと気持ち悪いけど。サッカー画像のほうがよほど気持ち悪いし。
ウザいサッカー画像が消えてくれた。しばらくはこれで様子を見よう…。ホームページを表示するたび、再レイアウトするあたりがちょっと気持ち悪いけど。サッカー画像のほうがよほど気持ち悪いし。
[ ツッコむ ]
#4 [nitijyou] 自転車で買い物に
リオンドールまで夕飯の食材を買いに行ったら、会計を済ませた頃に外は突然の豪雨。降水確率が20%前後だったから大丈夫かなと思ってたけど甘かった。
30分ほど入口で立ち往生。幸い小降りになってきたので急いで帰宅。しかし、駐輪場の自転車は突風で倒れて、ハンドルが微妙に曲がってしまって…。風で倒れるのはこれで2度目。電動自転車だから、充電池がついてる分、上の方に重心があって、そのせいで倒れやすいのだろうか。
30分ほど入口で立ち往生。幸い小降りになってきたので急いで帰宅。しかし、駐輪場の自転車は突風で倒れて、ハンドルが微妙に曲がってしまって…。風で倒れるのはこれで2度目。電動自転車だから、充電池がついてる分、上の方に重心があって、そのせいで倒れやすいのだろうか。
[ ツッコむ ]
2014/06/18(水) [n年前の日記]
#1 [ruby] 今時のRuby用GUIライブラリって何があるんだろう
もしかすると Ruby/Tk あたりが充実していたりしないのかなと思ったのだけど。ググってみたら、Windows + Ruby 1.9用の Tk拡張 (tcltklib.so) はあるけど、Rub 2.0用は無いらしくて。どうやら Ruby/SDL や Star Ruby と同様に、Ruby 2.0 には追随してこないライブラリになってしまったのかな…。
結局、今時の Windows + Ruby用のGUIライブラリって、何があるんだろう…。ほとんどが、Ruby 1.8、1.9 で開発停止になってるみたいだし…。
結局、今時の Windows + Ruby用のGUIライブラリって、何があるんだろう…。ほとんどが、Ruby 1.8、1.9 で開発停止になってるみたいだし…。
[ ツッコむ ]
#2 [python] Python + tkinter が気になり始めたり
_Need a GUI Builder for Tkinter / Python - Stack Overflow
というページを眺めていたら、Python+ tkinter 用のRADツール(ビルダー?)が紹介されていて、なんだか tkinter が気になってきました。
_Rapyd-Tk
_PAGE | Free Business & Enterprise software downloads at SourceForge.net
_Visual Tkinter Python IDE | Free software downloads at SourceForge.net
_alejandroautalan/pygubu
_SpecTcl - Browse /GUI Builder/2.5.20070129 at SourceForge.net
_SpecTcl Home Page
少し試用してみたり。環境は Windows7 x64。
_Rapyd-Tk
_PAGE | Free Business & Enterprise software downloads at SourceForge.net
_Visual Tkinter Python IDE | Free software downloads at SourceForge.net
_alejandroautalan/pygubu
_SpecTcl - Browse /GUI Builder/2.5.20070129 at SourceForge.net
_SpecTcl Home Page
少し試用してみたり。環境は Windows7 x64。
◎ pygubu をインストール。 :
_alejandroautalan/pygubu
から zip をDLして解凍。Python 2.7 以上を使って、python setup.py install を実行。Python 2.6 以下は対応してない。エラーが出る。
Pythonインストールフォルダ\Scripts\pygubu-designer.py を実行すれば起動する。動作はちょっとモッサリしてるけど、今風な操作感覚のように思えた。
Pythonインストールフォルダ\Scripts\pygubu-designer.py を実行すれば起動する。動作はちょっとモッサリしてるけど、今風な操作感覚のように思えた。
◎ Rapyd-Tk をインストール。 :
_Rapyd-Tk
から rapyd-1-0-0.zip をDLして解凍。rapyd.py を実行。
起動したように見えたのだけど、Project を Create new すると落ちる…。Project が作れないのでは話にならない…。
起動したように見えたのだけど、Project を Create new すると落ちる…。Project が作れないのでは話にならない…。
◎ Python + GUI。 :
_GuiProgramming - Python Wiki
を眺めてクラクラしてきた。比較的充実してるように見えるなあ…。
[ ツッコむ ]
2014/06/19(木) [n年前の日記]
#1 [emacs] NTEmacsのフォント設定を見直し
NTEmacs 24.3 上で、英数字フォントと日本語フォントの幅が合わないことに気がついたので、~/.emacs 内のフォント設定をちょっと見直し。
とりあえず、以下のような記述にした。
IME使用時のフォントの大きさが微妙に違ってしまうあたりも気になったので、色々試して以下のように。
とりあえず、以下のような記述にした。
(setq w32-enable-synthesized-fonts t) (set-default-font "Source Code Pro-9") (defvar japanese-font "MeiryoKe_Console") (dolist (target '(jisx0201 latin-jisx0201 japanese-jisx0208 japanese-jisx0208-1978 japanese-jisx0212 japanese-jisx0213-1 japanese-jisx0213-2 japanese-jisx0213-a japanese-jisx0213.2004-1 katakana-sjis katakana-jisx0201 cp932-2-byte cp932 (#x3040 . #x309f) (#x30a0 . #x30ff) (#xff00 . #xffef) (#x0370 . #x03ff))) (set-fontset-font (frame-parameter nil 'font) target japanese-font)) (setq face-font-rescale-alist '(("MeiryoKe_Console" . 1.12)))(setq face-font-rescale-alist '(("MeiryoKe_Gothic" . 1.12))) で、日本語フォントを微妙に大きくしてるのかな?
IME使用時のフォントの大きさが微妙に違ってしまうあたりも気になったので、色々試して以下のように。
(setq default-frame-alist (append '((ime-font . "MeiryoKe_Console-10")) default-frame-alist))これで合ってるのか・正しい指定なのかは分からないけど。
[ ツッコむ ]
2014/06/20(金) [n年前の日記]
#1 [emacs] NTEmacs上でrobeなるソレを使おうとしてるけど上手く行かず
以下のページを参考にしつつ、NTEmacs上で使おうとしてみたのだけど。
_auto-complete + rsense の代わりに auto-complete + robe をつかう - LGTM
_Emacs の ruby-mode で補完するのに『robe』を使ってみるメモ - 牌語備忘録 - pygo
M-x robe-start で動くはず、なのだけど、そんなコマンドは無いよと言われてしまったり、No matching directory found と言われてしまったりで。バージョンによって仕様が違っているのかな…。何にせよ、動いてる気配がありません。残念です。
_auto-complete + rsense の代わりに auto-complete + robe をつかう - LGTM
_Emacs の ruby-mode で補完するのに『robe』を使ってみるメモ - 牌語備忘録 - pygo
M-x robe-start で動くはず、なのだけど、そんなコマンドは無いよと言われてしまったり、No matching directory found と言われてしまったりで。バージョンによって仕様が違っているのかな…。何にせよ、動いてる気配がありません。残念です。
[ ツッコむ ]
#2 [anime] ピンポン最終回を視聴
なんだかスゴイアニメだったなと。映像がとにかく異質で。
漫画のようなコマ割りをしながら映像を見せていくあたりが好みでした。カッカッカッ、てな卓球の音と一緒に画面分割が進む、みたいな。
日本のアニメと言うと、萌えアニメっぽい、いかにもな方向でしかもう作れないのかな、などと思ってしまう時もあるのだけど。こういうアニメを目にすると、まだ日本のアニメは大丈夫っぽいなと…。
漫画のようなコマ割りをしながら映像を見せていくあたりが好みでした。カッカッカッ、てな卓球の音と一緒に画面分割が進む、みたいな。
日本のアニメと言うと、萌えアニメっぽい、いかにもな方向でしかもう作れないのかな、などと思ってしまう時もあるのだけど。こういうアニメを目にすると、まだ日本のアニメは大丈夫っぽいなと…。
[ ツッコむ ]
2014/06/21(土) [n年前の日記]
#1 [webgl] IE11だけガルガンティアが遅いんだけどなんでだろ
_翠星のガルガンティア 〜キミと届けるメッセージ〜
という、WebGLで動くゲームページがあるわけですけど。
IEのWebGL対応を宣伝するサイトのはずなのだけど、ウチの環境、Windows7 + IE11 で動かすと、3Dゲーム画面がガクガクしちゃってゲームどころではなくて。体感では、1〜2 FPSしか出てない印象。CPU使用率も4コア全部100%で回りっぱなしで、グラフ表示は真っ赤。
しかし、Google Chrome や Firefox で動かすとスルスル動くのです。CPU使用率もかなり低い。どうしてこんな結果になるんだろう?
IE11の設定がおかしいのかと思ってググってみたけど、それらしい情報に遭遇せず。F12キーを押して表示される開発者ツールで確認したけど、ドキュメントモードは Edgeになってるし…。アドオン?を色々無効にしてみたけど変化は無く。
そもそも、他のWebGLデモページに対しても、IE11で開くとCPU使用率が跳ね上がるのに、Google Chrome や Firefox は軽々と動くことに気付いたり。
ウチのメインPCは、GeForce 9800GTGE が載ってるのですけど。もしかして IE11 は、古いGPUは無視してCPUでレンダリングでもしてるんでしょうか…? あるいは、Windows7 + IE11 はソフトウェアレンダリングで、Windows8 + IE11 ならGPUを使うとか? そういう部分で、Windows7 と Windows8 の差別化をしてる?
もしかして、コレかな。
_【レビュー】Windows 7版Internet Explorer 11ファストレビュー - 高速化したJavaScript実行を検証 - ライブドアニュース
IE11がソフトウェアレンダリングしてるかどうかを判別する方法って無いのかな…?
IEのWebGL対応を宣伝するサイトのはずなのだけど、ウチの環境、Windows7 + IE11 で動かすと、3Dゲーム画面がガクガクしちゃってゲームどころではなくて。体感では、1〜2 FPSしか出てない印象。CPU使用率も4コア全部100%で回りっぱなしで、グラフ表示は真っ赤。
しかし、Google Chrome や Firefox で動かすとスルスル動くのです。CPU使用率もかなり低い。どうしてこんな結果になるんだろう?
IE11の設定がおかしいのかと思ってググってみたけど、それらしい情報に遭遇せず。F12キーを押して表示される開発者ツールで確認したけど、ドキュメントモードは Edgeになってるし…。アドオン?を色々無効にしてみたけど変化は無く。
そもそも、他のWebGLデモページに対しても、IE11で開くとCPU使用率が跳ね上がるのに、Google Chrome や Firefox は軽々と動くことに気付いたり。
ウチのメインPCは、GeForce 9800GTGE が載ってるのですけど。もしかして IE11 は、古いGPUは無視してCPUでレンダリングでもしてるんでしょうか…? あるいは、Windows7 + IE11 はソフトウェアレンダリングで、Windows8 + IE11 ならGPUを使うとか? そういう部分で、Windows7 と Windows8 の差別化をしてる?
もしかして、コレかな。
_【レビュー】Windows 7版Internet Explorer 11ファストレビュー - 高速化したJavaScript実行を検証 - ライブドアニュース
このセキュリティホールの問題があってか、WebGLコンテンツ実行をする前に内容をスキャンし、安全が確認されない場合はソフトウェアベースのレンダラーを用いるという。ガルガンティアは、IE11から「安全性が確認されないWebGLコンテンツ」として扱われているから、ソフトウェアレンダリングになっているのだろうか。【レビュー】Windows 7版Internet Explorer 11ファストレビュー - 高速化したJavaScript実行を検証 - ライブドアニュース より
IE11がソフトウェアレンダリングしてるかどうかを判別する方法って無いのかな…?
[ ツッコむ ]
2014/06/22(日) [n年前の日記]
#1 [dxruby] DXRubyで通路の奥に進むようなソレ
DXRubyを使って、通路の奥に進んでいくようなソレを実験。以下のような感じに。
うむ。レイフォースですな。あるいはギャラクシーフォース。
やってることは、真ん中に穴が開いた1枚画を、z値に基づいて、拡大縮小表示してるだけ。
予想では、描画面積がとんでもなく大きくなるから処理落ちするんじゃないか ―― 複数画像に分割して組み合わせて描画して、最低限の面積を描画するようにしないと実用にならないのでは、と思っていたけど。おそらくGPUがイイ感じに頑張ってくれているのか、分割せずに1枚画を連続でドドドと描画しても全然処理落ちせずに済みました。ありがたや。
ソースは以下。
_passagewaytypea.rb
他のスクリプトからも呼び出せるようにしておきました。以下のような感じで呼び出せます。
使用画像も置いときます。
_wall1.png
_wall2.png
_floor_fg.png
ソースと画像のライセンスは、 Public Domain または CC0 ってことで。
うむ。レイフォースですな。あるいはギャラクシーフォース。
やってることは、真ん中に穴が開いた1枚画を、z値に基づいて、拡大縮小表示してるだけ。
予想では、描画面積がとんでもなく大きくなるから処理落ちするんじゃないか ―― 複数画像に分割して組み合わせて描画して、最低限の面積を描画するようにしないと実用にならないのでは、と思っていたけど。おそらくGPUがイイ感じに頑張ってくれているのか、分割せずに1枚画を連続でドドドと描画しても全然処理落ちせずに済みました。ありがたや。
ソースは以下。
_passagewaytypea.rb
require 'dxruby' # # 通路を奥に進んでいく背景演出 # class PassageWayTypeA attr_accessor :walls # # 壁1枚分 # class Wall attr_accessor :image attr_accessor :x, :y, :z attr_accessor :sz attr_accessor :angle_z attr_accessor :shader # 明度調整用 @@hlsl = <<EOS float v; texture tex0; sampler Samp0 = sampler_state { Texture =<tex0>; }; float4 PS(float2 input : TEXCOORD0) : COLOR0 { float4 output; output = tex2D( Samp0, input ); output.rgb *= v; return output; } technique { pass { PixelShader = compile ps_2_0 PS(); } } EOS # # コンストラクタ # # @param [Object] img Imageオブジェクト # @param [Number] x 初期位置x # @param [Number] y 初期位置y # @param [Number] z 初期位置z # @param [Number] scr_z 視点からスクリーン(画面)までの距離 # def initialize(img, x, y, z, scr_z) self.image = img self.sz = scr_z self.angle_z = 0 self.x = x self.y = y self.z = z core = Shader::Core.new(@@hlsl, {:v => :float}) self.shader = Shader.new(core) self.shader.v = 1.0 end # # 座標を更新 # # @param [Number] dx 速度x # @param [Number] dy 速度y # @param [Number] dz 速度z # @param [Number] d_ang_z z軸回転速度 # def update(dx, dy, dz, d_ang_z = 0) self.x += dx self.y += dy self.z += dz self.angle_z += d_ang_z end # # 描画 # # @param [Number] bx 描画位置オフセットx # @param [Number] by 描画位置オフセットy # def draw(bx, by) sx = (self.sz * (bx + self.x) / self.z) + Window.width / 2 sy = (self.sz * (by + self.y) / self.z) + Window.height / 2 scale = self.sz / self.z a = 1.0 - (1.0 * (self.z - 300) / 2900.0) a = 0 if a < 0 a = 1.0 if a > 1.0 self.shader.v = a Window.drawEx(sx, sy, self.image, :scale_x => scale, :scale_y => scale, :center_x => self.image.width / 2, :center_y => self.image.height / 2, :angle => self.angle_z, :offset_sync => true, :z => -self.z, :shader => self.shader) end end # # コンストラクタ # # @param [Array] imgs Imageオブジェクトの配列 # @param [Number] scr_z 視点からスクリーン(画面)までの距離 # @param [Number] num 壁の枚数 # def initialize(imgs, scr_z, num = 8) self.walls = [] z = 3200.0 zadd = 3200 / num num.times do |i| x, y = 0, 0 self.walls.push(Wall.new(imgs[i % imgs.length], x, y, z, scr_z)) z += zadd end end # # 座標を更新 # # @param [Number] dx 速度x # @param [Number] dy 速度y # @param [Number] dz 速度z # @param [Number] d_ang_z z軸回転速度 # @param [Boolean] del_enable trueなら、スクリーン手前に来た段階で壁を消去 # @return [Number] 壁の数を返す # def update(dx, dy, dz, d_ang_z = 0, del_enable = false) self.walls.each do |spr| spr.update(dx, dy, dz, d_ang_z) if spr.z < spr.sz - 100 # 投影面より手前に来たので if del_enable self.walls.delete(spr) else # 遠方に配置し直し spr.z += 3200.0 spr.x, spr.y = 0, 0 end end end return self.walls.size end # # 描画 # # @param [Number] bx 描画位置オフセットx # @param [Number] by 描画位置オフセットy # def draw(bx, by) self.walls.each { |spr| spr.draw(bx, by) } end end if $0 == __FILE__ # ---------------------------------------- # 使用例 font = Font.new(14) wall_max = 8 scrz = 300 imgs = [ Image.load("wall1.png"), Image.load("wall2.png"), ] bg = PassageWayTypeA.new(imgs, scrz, wall_max) floor = Image.load("floor_fg.png") step = 0 mouse_move = false Window.loop do break if Input.keyPush?(K_ESCAPE) # Xキーでマウス移動を反映させるか否かを反転 mouse_move = !mouse_move if Input.keyPush?(K_X) if mouse_move mx = Input.mousePosX - Window.width / 2 my = Input.mousePosY - Window.height / 2 else mx, my = 0, 0 end case step when 0 # 通常描画 bg.update(0, 0, -25) bg.draw(mx, my) # zキーが押されたら壁が消えていく処理へ移行 step += 1 if Input.keyPush?(K_Z) when 1 # 壁が徐々に消えていく処理 if bg.update(0, 0, -25, 0, true) <= 0 # 壁がすべて消えた step += 1 end bg.draw(mx, my) when 2 # 壁を再発生 bg = PassageWayTypeA.new(imgs, scrz, wall_max) step = 0 end Window.draw(rand(8) - 4, rand(3), floor) s = "#{Window.real_fps.to_i} FPS CPU: #{Window.getLoad.to_i} %" Window.drawFont(4, 4, s, font) end end
他のスクリプトからも呼び出せるようにしておきました。以下のような感じで呼び出せます。
require "dxruby" require_relative "passagewaytypea" imgs = [ Image.load("wall1.png"), Image.load("wall2.png"), ] bg = PassageWayTypeA.new(imgs, 300) floor = Image.load("floor_fg.png") Window.loop do break if Input.keyPush?(K_ESCAPE) bg.update(0, 0, -25) bg.draw(0, 0) Window.draw(rand(8) - 4, rand(3), floor) end
使用画像も置いときます。
_wall1.png
_wall2.png
_floor_fg.png
ソースと画像のライセンスは、 Public Domain または CC0 ってことで。
[ ツッコむ ]
2014/06/23(月) [n年前の日記]
#1 [dxruby] DXRubyで円柱っぽいBG描画を実験中
円柱と言うか、パイプと言うか、スペースコロニー内部と言うか、そういう感じのBG描画を Shader を使って実験中。
_GeoGebra で図を描きながら、どういう処理をしたらいいのか悩んでおります。
_GeoGebra で図を描きながら、どういう処理をしたらいいのか悩んでおります。
[ ツッコむ ]
2014/06/24(火) [n年前の日記]
#1 [dxruby] DXRubyで円柱っぽいBG描画をしてみたり
円柱と言うか、パイプと言うか、スペースコロニー内部と言うか、そういう感じのBG描画を DXRuby の Shader を使って試してみたり。
こんな感じになりました。
ソースは以下。
_pipebg.rb
使用画像も置いときます。画像サイズは 960x480ドット。
_bg_960x480.png
他のスクリプトからも呼び出せるようにしておきました。以下は使用例。
_pipebg_test_main.rb
使用画像。
_bg_chip.png
_bg_star.png
以下のような感じの画面になります。
ソースや画像のライセンスは、Public Domain / CC0 ってことで。
一応、マップデータ(Tiled形式。.tmx) その他も含めて、一式置いときます。
_pipe_bg_20140624.zip (120KB)
こんな感じになりました。
ソースは以下。
_pipebg.rb
require 'dxruby' # # パイプ内のような背景描画を行う # class PipeBg @@hlsl = <<EOS float sz; float r; float angle_max; float start_x; float start_y; texture tex0; sampler Samp = sampler_state { Texture =<tex0>; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; // MinFilter = POINT; // MagFilter = POINT; // MipFilter = POINT; AddressU = BORDER; AddressV = WRAP; }; float4 PS(float2 input : TEXCOORD0) : COLOR0 { input.x = (input.x - 0.5) * (r * cos(atan2(input.y - 0.5, sz))) / sz + start_x + 0.5; input.y = (atan2(input.y - 0.5, sz) / angle_max) + start_y; return tex2D( Samp, input ); } technique { pass { PixelShader = compile ps_2_0 PS(); } } EOS attr_accessor :sz attr_accessor :r attr_accessor :angle_max attr_accessor :start_x attr_accessor :start_y attr_accessor :shader # # コンストラクタ # # @param [Number] sz スクリーンまでの距離 # @param [Number] r 壁までの距離 # @param [Number] start_x 初期位置 x # @param [Number] start_y 初期位置 y # def initialize(sz = 160, r = 280, start_x = 0.0, start_y = 0.0) self.sz = sz self.r = r self.start_x = start_x self.start_y = start_y core = Shader::Core.new(@@hlsl,{ :sz=>:float, :r=>:float, :angle_max=>:float, :start_x=>:float, :start_y=>:float }) self.shader = Shader.new(core) self.shader.sz = self.sz.to_f / (Window.height / 2) self.shader.r = self.r.to_f / (Window.width / 2) self.shader.start_x = self.start_x self.shader.start_y = self.start_y self.angle_max = Math.atan2(Window.height / 2, sz) # self.angle_max = 90.0 * Math::PI / 180.0 self.shader.angle_max = self.angle_max end # # 描画開始位置を更新 # # @param [Number] dx テクスチャ取得位置 x 増分(1.0より小さい値が望ましい) # @param [Number] dy テクスチャ取得位置 y 増分(1.0より小さい値が望ましい) # def update(dx, dy) self.start_x += dx self.start_y += dy self.shader.start_x = self.start_x self.shader.start_y = self.start_y end # # 描画 # # @param [Number] x 描画位置 x # @param [Number] y 描画位置 y # def draw(x, y, img) Window.drawEx(x, y, img, :shader => self.shader) end end if $0 == __FILE__ # ---------------------------------------- # 使用例 font = Font.new(14) img = Image.load("bg_960x480.png") bg = PipeBg.new(200, 360, 0.0, 0.0) Window.loop do break if Input.keyPush?(K_ESCAPE) bg.update(0.0, -0.005) bg.draw(-Window.width / 4, 0, img) s = "#{Window.real_fps.to_i} FPS CPU: #{Window.getLoad.to_i} % x = #{bg.start_x.to_i}" Window.drawFont(4, 4, s, font) end end
使用画像も置いときます。画像サイズは 960x480ドット。
_bg_960x480.png
他のスクリプトからも呼び出せるようにしておきました。以下は使用例。
_pipebg_test_main.rb
# # pipebg.rb の呼び出しテスト # require 'dxruby' require_relative 'pipebg' # 背景マップデータ mapdata = [ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, nil, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 2, 2, 2, 1, 1, 2, nil, nil, 2, 1, 2, 2, 2, 1, 1, 2, nil, nil, nil, 2, 1, 1, 1, 1, 1, 1, 1, 1, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 2, nil, nil, 2, 1, nil, 2, 1, 2, nil, 1, 2, nil, nil, 2, 1, 2, nil, nil, 2, 1, 2, nil, nil, 2, 1, 2, nil, nil, nil, 2, 1, 3, 3, 3, 3, nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 2, nil, nil, 2, 1, nil, nil, 2, nil, nil, 1, 2, nil, nil, 2, 1, 2, nil, nil, 2, 1, 2, nil, 2, 1, 1, 1, 2, nil, 2, 1, 1, 3, 3, 3, 3, 3, nil, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 2, nil, nil, 2, 1, nil, nil, 2, nil, nil, 1, 2, 2, 2, 1, 1, 2, nil, nil, 2, 1, 2, nil, nil, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 2, nil, nil, 2, 1, nil, 2, 1, 2, nil, 1, 2, nil, 2, 1, 1, 2, nil, nil, 2, 1, 2, nil, nil, 2, 1, 1, 1, 2, 1, nil, nil, nil, nil, 1, 3, 3, nil, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 2, nil, nil, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, nil, nil, nil, 3, 3, 3, nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, nil] ] font = Font.new(14) bg = PipeBg.new(160, 280) imgs = Image.loadTiles("bg_chip.png", 4, 1, true) star_bg = Image.load("bg_star.png") rt = RenderTarget.new(64 * 15, 64 * 8) bg_x, bg_y = 0, 0 Window.loop do break if Input.keyPush?(K_ESCAPE) # 星BG描画 Window.drawTile(0, 0, [[0, 0]], [star_bg], bg_x / 3, 0, 2, 1) # ReanderTargetにタイルBGを描画 rt.drawTile(0, 0, mapdata, imgs, bg_x, bg_y, 15, 8).update # RenderTarget を円柱のように描画 bg.draw(-Window.width / 4, -32, rt) bg_x += 3 bg_y += 2 s = "#{Window.real_fps.to_i} FPS CPU: #{Window.getLoad.to_i} %" Window.drawFont(4, 4, s, font) end
使用画像。
_bg_chip.png
_bg_star.png
以下のような感じの画面になります。
ソースや画像のライセンスは、Public Domain / CC0 ってことで。
一応、マップデータ(Tiled形式。.tmx) その他も含めて、一式置いときます。
_pipe_bg_20140624.zip (120KB)
◎ 処理内容について。 :
どうやって実現したのか自分自身が忘れそうなので、考え方をメモ。
Shader (HLSL) で、Input.x と Input.y の値を変化させてやれば、こういう円柱っぽい表示ができるわけですが…。
とりあえず、横から見た図で考えてみるとして。
点B、原点、点A でできる角度 a は、アークタンジェントを使えば求められます。この場合は、atan2(sy, sz) で得られるはず。
この、角度 a を、テクスチャを参照する際のuv値 ―― Input.y を変化させる値としてそのまま利用すれば、y方向に関しては円柱っぽい見た目になりそうだなと。Input.y は、0,0〜1.0 の値を取るので、角度 a も 0,0〜1.0 に収まるように変換してやればいいわけで。
さらに、角度 a が分かれば、点Aを通る直線と円の交点、のz値も、r * cos(a) で求められます。z値が得られたら、各ラスターを横方向にどれだけ拡大縮小すればいいのか計算可能になるわけで。
今度は上から見た図で考えるとして。
注意点としては…。Input.x も Input.y も、0.0〜1.0 として得られるので、0.5 を引くことで、画面の中心が 0.0 になるようにしてから計算に使ってます。
また、Shader は、与えられた画像 or RenderTarget を円柱っぽく描画する処理しかしていません。スクロール処理は…。
Shader (HLSL) で、Input.x と Input.y の値を変化させてやれば、こういう円柱っぽい表示ができるわけですが…。
とりあえず、横から見た図で考えてみるとして。
- 原点 (0,0) が、視点。
- スクリーンまでの距離が、sz。テキトーに決めておく。
- 青い線で描かれた円が、壁に相当するところ。半径 r の円。
点B、原点、点A でできる角度 a は、アークタンジェントを使えば求められます。この場合は、atan2(sy, sz) で得られるはず。
この、角度 a を、テクスチャを参照する際のuv値 ―― Input.y を変化させる値としてそのまま利用すれば、y方向に関しては円柱っぽい見た目になりそうだなと。Input.y は、0,0〜1.0 の値を取るので、角度 a も 0,0〜1.0 に収まるように変換してやればいいわけで。
さらに、角度 a が分かれば、点Aを通る直線と円の交点、のz値も、r * cos(a) で求められます。z値が得られたら、各ラスターを横方向にどれだけ拡大縮小すればいいのか計算可能になるわけで。
今度は上から見た図で考えるとして。
- z値は ―― 図で言うところの pz 値は、r * cos(a) で得られた。
- sz はテキトーに決めてある。
- sx も HLSL内では Input.x として得られると分かってる。
sx : sz = px : pz sz * px = sx * pz px = sx * pz / szpx が求まったら、それを Input.x に反映してやれば、拡大縮小ができるわけで。
注意点としては…。Input.x も Input.y も、0.0〜1.0 として得られるので、0.5 を引くことで、画面の中心が 0.0 になるようにしてから計算に使ってます。
また、Shader は、与えられた画像 or RenderTarget を円柱っぽく描画する処理しかしていません。スクロール処理は…。
- テクスチャuv値をちょっと弄る。
- もしくは、RenderTarget にスクロールした状態の画を描画しておいて、その RenderTarget を Shader に渡す。
◎ 課題。 :
y値に応じてラスター単位で明るさを変えたら、もうちょっと見た目がリアルっぽくなるのかもしれず。
◎ 実装してみたものの。 :
この手の処理はどうやって実現していたのか、個人的に気になっていたので、今回一応試してみたものの。例えば Unityあたりを使うなら、円柱っぽいモデルを配置・回転させて、それで終わりだろうなと予想するわけで。
3D描画が当たり前の現代においては、こういう処理ができたからと言って、何に使えるのか、どこで使えるのかと言う問題があるなと…。
でもまあ、プログラマーにとっての頭の体操、プログラマー向けのパズル、としてならアリかなと…。
3D描画が当たり前の現代においては、こういう処理ができたからと言って、何に使えるのか、どこで使えるのかと言う問題があるなと…。
でもまあ、プログラマーにとっての頭の体操、プログラマー向けのパズル、としてならアリかなと…。
[ ツッコむ ]
#2 [dxruby] マップエディタ Tiled でエクスポートしたjsonに対して処理
マップエディタ
_Tiled Map Editor
は、json ファイルでエクスポートすることもできるのだけど。その json ファイルを Ruby で読み込んで、DXRuby で使える形に変換して出力できないかなと。
とりあえず、レイヤー情報だけでも取り出せないか、少し実験。
_convtmxjson.rb
使い方。
例えば、以下のような json ファイルを読みこませると。
_bg.json
以下のような出力結果に。
コピーして、DXRuby スクリプトに貼り付ければOK。
しかしコレ、jsonファイルをDXRubyスクリプトから直接読み込んで使ったほうがいいのかも…? Ruby 1.9 以降は、jsonを扱うためのライブラリが標準添付されているらしいので、新規にライブラリをインストールする必要もなさそうだし。ただ、Tiled で毎回、json のエクスポート操作をするのが、ちょっと面倒臭い気もする。
とりあえず、レイヤー情報だけでも取り出せないか、少し実験。
_convtmxjson.rb
# マップエディタ Tiled でエクスポートした json から # DXRuby用のマップデータを取り出してみるテスト require 'json' require 'pp' if ARGV.size == 0 puts "usage: ruby #{$0} json_file" exit end infile = ARGV[0] unless File.file?(infile) puts "#{infile} not found" exit 1 end d = JSON.parse(File.open(infile).read) # レイヤー枚数分ループ d["layers"].each do |layer| name = layer["name"] w = layer["width"].to_i h = layer["height"].to_i ndt = layer["data"].map {|c| (c == 0 or c== 1)? nil : (c - 1)} a = ndt.each_slice(w).to_a puts "# name=#{name},w=#{w},h=#{h}" puts "mapdata = [" a.each { |aa| puts " #{aa}," } puts "]" end exit
使い方。
ruby convtmxjson.rb hoge.json ruby convtmxjson.rb hoge.json > map.txt
例えば、以下のような json ファイルを読みこませると。
_bg.json
{ "height":8, "layers":[ { "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 2, 2, 3, 2, 2, 2, 3, 2, 3, 3, 3, 2, 2, 3, 1, 1, 3, 2, 3, 3, 3, 2, 2, 3, 1, 1, 1, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 1, 1, 3, 2, 1, 3, 2, 3, 1, 2, 3, 1, 1, 3, 2, 3, 1, 1, 3, 2, 3, 1, 1, 3, 2, 3, 1, 1, 1, 3, 2, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 3, 2, 1, 1, 3, 1, 1, 2, 3, 1, 1, 3, 2, 3, 1, 1, 3, 2, 3, 1, 3, 2, 2, 2, 3, 1, 3, 2, 2, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 3, 2, 1, 1, 3, 1, 1, 2, 3, 3, 3, 2, 2, 3, 1, 1, 3, 2, 3, 1, 1, 3, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 1, 1, 3, 2, 1, 3, 2, 3, 1, 2, 3, 1, 3, 2, 2, 3, 1, 1, 3, 2, 3, 1, 1, 3, 2, 2, 2, 3, 2, 1, 1, 1, 1, 2, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 2, 2, 3, 2, 2, 2, 3, 2, 3, 1, 1, 3, 2, 2, 3, 3, 2, 2, 3, 3, 3, 2, 2, 2, 2, 3, 2, 1, 1, 1, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], "height":8, "name":"layer1", "opacity":1, "type":"tilelayer", "visible":true, "width":60, "x":0, "y":0 }], "orientation":"orthogonal", "properties": { }, "tileheight":64, "tilesets":[ { "firstgid":1, "image":"bg_chip.png", "imageheight":64, "imagewidth":256, "margin":0, "name":"bg_chip", "properties": { }, "spacing":0, "tileheight":64, "tilewidth":64 }], "tilewidth":64, "version":1, "width":60 }
以下のような出力結果に。
# name=layer1,w=60,h=8 mapdata = [ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, nil, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 2, 2, 2, 1, 1, 2, nil, nil, 2, 1, 2, 2, 2, 1, 1, 2, nil, nil, nil, 2, 1, 1, 1, 1, 1, 1, 1, 1, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 2, nil, nil, 2, 1, nil, 2, 1, 2, nil, 1, 2, nil, nil, 2, 1, 2, nil, nil, 2, 1, 2, nil, nil, 2, 1, 2, nil, nil, nil, 2, 1, 3, 3, 3, 3, nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 2, nil, nil, 2, 1, nil, nil, 2, nil, nil, 1, 2, nil, nil, 2, 1, 2, nil, nil, 2, 1, 2, nil, 2, 1, 1, 1, 2, nil, 2, 1, 1, 3, 3, 3, 3, 3, nil, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 2, nil, nil, 2, 1, nil, nil, 2, nil, nil, 1, 2, 2, 2, 1, 1, 2, nil, nil, 2, 1, 2, nil, nil, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 2, nil, nil, 2, 1, nil, 2, 1, 2, nil, 1, 2, nil, 2, 1, 1, 2, nil, nil, 2, 1, 2, nil, nil, 2, 1, 1, 1, 2, 1, nil, nil, nil, nil, 1, 3, 3, nil, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 2, nil, nil, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, nil, nil, nil, 3, 3, 3, nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, nil], ]
コピーして、DXRuby スクリプトに貼り付ければOK。
しかしコレ、jsonファイルをDXRubyスクリプトから直接読み込んで使ったほうがいいのかも…? Ruby 1.9 以降は、jsonを扱うためのライブラリが標準添付されているらしいので、新規にライブラリをインストールする必要もなさそうだし。ただ、Tiled で毎回、json のエクスポート操作をするのが、ちょっと面倒臭い気もする。
[ ツッコむ ]
#3 [pc][neta] OneDrive(SkyDrive)とGoogleドライブの同期ソフトをアンインストールした
_米Microsoft、無料で使えるOneDrive容量を15GBに -INTERNET Watch
という記事を見かけたのだけど。はてブのコメントを眺めてたら、「OneDriveはエロ画像を入れてるとアカウント削除されるから気をつけろ」という話を見かけて、なんだか気になったわけで。
ググってみたら、実際そうらしく。利用規約に違反する画像を入れてるだけで、問答無用で何の連絡も無くアカウント削除されるそうで。
_MicrosoftのOneDrive、検閲されている模様。エロ画像をアップロードすると垢停止
_クラウドにエロ画像を上げると非公開であってもBANされることが判明 不便すぎワロタ
_やはり画像が原因か - Aruyo
_Windows8.1に統合されたSkyDriveに間違ってもエロ絵を入れてはいけない - 仮想と現実
_ITライフハック |突然のアカウントBANを防ぐ その便利さの裏にある危険「Google+」の設定を確認すべし
_え、この写真がポルノ扱い? 非公開なのに? Googleアカウントを停止された とあるユーザーの悲劇 - エキサイトニュース(1/2)
_tappli blog: Googleアカウントを消されてしまった話
非公開フォルダに入れていてもアカウント削除・アカウント停止されるなんて、酷い話だなと。
自分はその手の画像なんか入れてないつもりだけど、しかし全然安心できないよなと。と言うのも、その手の画像かどうか判別する作業は、コンピュータ上の画像認識プログラムを使ってやってるらしいので。であれば、ガンガン誤認識するだろうし、バグも残ってるはずだよなと。
例えば、 _相撲取りが光学合成エフェクトを出しながら戦うアニメgif などを、面白いからと、うっかり OneDrive や Google ドライブに保存してしまったら、Microsoft や Google のプログラムは「肌色成分が多いからコイツはエロ画像だ! けしからん!」と誤認識してアカウント削除しやがるだろうなと予想できるわけで。
ということで、そんな酷い目には会いたくないので、OneDrive も Googleドライブも、今後は画像保存場所として使わないことにしました。OneDrive と Googleドライブの同期ソフトを、メインPC上からアンインストール。
そもそも、Windowsをログオフする際、その手のソフトだけが妙に終了処理を遅らせていたりもしたので、これはこれで問題が一つ解消できたような気もしてきたり。
zipを置いておくとか、そういう用途なら使えるのかしら。でも、実はzipの中身まで検閲して、しかも誤認識したら嫌だなあ…。一体何が置けるんだよ。
余談。
_孫が水浴びしている写真をパソコンの中に保存したおじいさん、児童ポルノ単純所持の罪で警察に捕まり起訴される - GIGAZINE
家庭内でそういう目に会う児童が多いから、という事情があるのだろうけど。それにしてもこの世界はもう滅茶苦茶だなと思います。
ググってみたら、実際そうらしく。利用規約に違反する画像を入れてるだけで、問答無用で何の連絡も無くアカウント削除されるそうで。
_MicrosoftのOneDrive、検閲されている模様。エロ画像をアップロードすると垢停止
_クラウドにエロ画像を上げると非公開であってもBANされることが判明 不便すぎワロタ
_やはり画像が原因か - Aruyo
_Windows8.1に統合されたSkyDriveに間違ってもエロ絵を入れてはいけない - 仮想と現実
_ITライフハック |突然のアカウントBANを防ぐ その便利さの裏にある危険「Google+」の設定を確認すべし
_え、この写真がポルノ扱い? 非公開なのに? Googleアカウントを停止された とあるユーザーの悲劇 - エキサイトニュース(1/2)
_tappli blog: Googleアカウントを消されてしまった話
非公開フォルダに入れていてもアカウント削除・アカウント停止されるなんて、酷い話だなと。
自分はその手の画像なんか入れてないつもりだけど、しかし全然安心できないよなと。と言うのも、その手の画像かどうか判別する作業は、コンピュータ上の画像認識プログラムを使ってやってるらしいので。であれば、ガンガン誤認識するだろうし、バグも残ってるはずだよなと。
例えば、 _相撲取りが光学合成エフェクトを出しながら戦うアニメgif などを、面白いからと、うっかり OneDrive や Google ドライブに保存してしまったら、Microsoft や Google のプログラムは「肌色成分が多いからコイツはエロ画像だ! けしからん!」と誤認識してアカウント削除しやがるだろうなと予想できるわけで。
ということで、そんな酷い目には会いたくないので、OneDrive も Googleドライブも、今後は画像保存場所として使わないことにしました。OneDrive と Googleドライブの同期ソフトを、メインPC上からアンインストール。
そもそも、Windowsをログオフする際、その手のソフトだけが妙に終了処理を遅らせていたりもしたので、これはこれで問題が一つ解消できたような気もしてきたり。
zipを置いておくとか、そういう用途なら使えるのかしら。でも、実はzipの中身まで検閲して、しかも誤認識したら嫌だなあ…。一体何が置けるんだよ。
余談。
_孫が水浴びしている写真をパソコンの中に保存したおじいさん、児童ポルノ単純所持の罪で警察に捕まり起訴される - GIGAZINE
家庭内でそういう目に会う児童が多いから、という事情があるのだろうけど。それにしてもこの世界はもう滅茶苦茶だなと思います。
[ ツッコむ ]
2014/06/25(水) [n年前の日記]
#1 [dxruby] DXRubyでラスタースクロールを使ったレースゲームの画面を再現できないか実験してみたり
昔、ラスタースクロールを利用した、レースゲーム・ドライブゲームが結構ありましたけど。例えば、
_ポールポジション
とか。
_アウトラン
とか。…ラスタースクロールと言うか、ラスター割り込み、水平帰線期間割り込み処理を利用したレースゲーム、と言えばいいのかな。
個人的に、あの仕組み、よく分からんのですよ…。ラスター単位で上手いことやればできるよーと先輩に教えてもらった記憶はあるのだけど、具体的にどういう処理をすればそうなるのか分かってなくて。
気になり始めてググってみたところ、一応、解説ページは見かけたのですが。
_Lou's Pseudo 3d Page
_Code inComplete - How to build a racing game
_Code inComplete - How to build a racing game - straight roads
_Code inComplete - How to build a racing game - curves
_Code inComplete - How to build a racing game - hills
_Code inComplete - How to build a racing game - conclusion
英文ページなので、何が何やら。
とりあえず、まっすぐな道路なら、以下のような仕組みで表現できそうかなと思えたので、DXRuby で実験開始。 *1
_raster_drive.rb
スクリプトを実行して、Zキーを押していけば描画が変わります。
ちなみに、z値は以下の式で求められます。
さて、ストレートな道路なら、これでなんとかなりそうだけど。カーブや丘は、どう表現すればいいのやら…。
個人的に、あの仕組み、よく分からんのですよ…。ラスター単位で上手いことやればできるよーと先輩に教えてもらった記憶はあるのだけど、具体的にどういう処理をすればそうなるのか分かってなくて。
気になり始めてググってみたところ、一応、解説ページは見かけたのですが。
_Lou's Pseudo 3d Page
_Code inComplete - How to build a racing game
_Code inComplete - How to build a racing game - straight roads
_Code inComplete - How to build a racing game - curves
_Code inComplete - How to build a racing game - hills
_Code inComplete - How to build a racing game - conclusion
英文ページなので、何が何やら。
とりあえず、まっすぐな道路なら、以下のような仕組みで表現できそうかなと思えたので、DXRuby で実験開始。 *1
_raster_drive.rb
require 'dxruby' font = Font.new(24) imgs = Image.loadTiles("road_bg.png", 1, 480) bgimg = Image.load("road_bg.png") Window.bgcolor = [68, 97, 255] mode = 0 bz = 0 start_y = 1 Window.loop do break if Input.keyPush?(K_ESCAPE) # Zキーで描画を変更 mode = (mode + 1) % 6 if Input.keyPush?(K_Z) case mode when 0 Window.draw(-320, 0, bgimg) Window.drawFont(4, 4, "BG全体を描画", font) when 1 start_y.step(240-1, 1) { |y| i = y Window.draw(-320, y + 240, imgs[i]) } Window.drawFont(4, 4, "上半分だけ描画", font) when 2 start_y.step(240-1, 1) { |y| i = y + 240 Window.draw(-320, y + 240, imgs[i]) } Window.drawFont(4, 4, "下半分だけ描画", font) when 3 start_y.step(240-1, 1) { |y| i = y + 240 * ((y / 16) & 0x01) Window.draw(-320, y + 240, imgs[i]) } Window.drawFont(4, 4, "上と下を、ラスター単位で交互に描画 (一定間隔)", font) when 4 sz = 320 h = 240 start_y.step(240-1, 1) { |y| z = (h * sz / y) # y座標毎のz値を求める i = y + 240 * ((z.to_i / 128) & 0x01) Window.draw(-320, y + 240, imgs[i]) } Window.drawFont(4, 4, "上と下を、ラスター単位で交互に描画 (z値に基づく)", font) when 5 sz = 320 h = 240 start_y.step(240-1, 1) { |y| z = (h * sz / y) + bz i = y + 240 * ((z.to_i / 128) & 0x01) Window.draw(-320, y + 240, imgs[i]) } Window.drawFont(4, 4, "上と下を、ラスター単位で交互に描画 (z値を加算)", font) bz += 8 end end背景画像は以下。
スクリプトを実行して、Zキーを押していけば描画が変わります。
ちなみに、z値は以下の式で求められます。
h : 視点の高さ sz : 視点からスクリーンまでの距離 y : スクリーン上のy座標 z = h * sz / y_Code inComplete - How to build a racing game - straight roads の図が分かりやすい、かもしれず。
さて、ストレートな道路なら、これでなんとかなりそうだけど。カーブや丘は、どう表現すればいいのやら…。
*1: レースゲーム・ドライブゲームと言えば3DCGで表現するのが当たり前になってしまったこの御時勢に、自分は一体何をやってるのかという気もするけれど。仕組みが気になり始めてしまったのだから仕方ない。考えてみたら、30〜40年前の技術、というか工夫なんだよなあ…。
[ ツッコむ ]
2014/06/26(木) [n年前の日記]
#1 [dxruby] カーブの表現で悩んでいたり
_昨日の日記
で、ストレートな道路の表現はできたのだけど。カーブをどうやって表現したらいいのか、そのあたりで悩んでいたり。
_Code inComplete - How to build a racing game - curves で解説されているのだけど、英文ページなので、何が何やら。とりあえず、「セグメント」「二次曲線」という単語が鍵っぽい気がしますけどよく分かりません。
とりあえず、件のページに「ease In」「ease Out」「ease In Out」なる単語もあったので、そのあたりから調べてみようかと。
_イージング処理の計算式 - 強火で進め
_Easing Equations
_anything from herejquery.js のアニメーションコードの解読 ( 10 ) 番外編 easing関数解読
おそらくだけど、 quadratic easing in とやらの式が使えそう。
_Code inComplete - How to build a racing game - curves で解説されているのだけど、英文ページなので、何が何やら。とりあえず、「セグメント」「二次曲線」という単語が鍵っぽい気がしますけどよく分かりません。
とりあえず、件のページに「ease In」「ease Out」「ease In Out」なる単語もあったので、そのあたりから調べてみようかと。
_イージング処理の計算式 - 強火で進め
_Easing Equations
_anything from herejquery.js のアニメーションコードの解読 ( 10 ) 番外編 easing関数解読
おそらくだけど、 quadratic easing in とやらの式が使えそう。
[ ツッコむ ]
#2 [prog] Light Game Programmingとやらが少し気になる
色々ググってたら、Light Game Programming なる、ゲーム開発にフォーカスしたBASIC環境があるらしいと知ったのです。
_LightGameProgramming - Wikipedia
_プログラミング/言語・コンパイラ/LGP - game-develop.com wiki
exe化ができるらしいあたりはなんだかヨサゲ。
パッと見、HSPと似てるように思えたのだけど。開発が始まったのも結構古い時期らしいし。しかし、どうしてHSPほど広まってないのだろう…? 気になってググっていたら、どうやら最初の頃はシェアウェアだったようで。
_窓の杜 - 【NEWS】BASIC風言語によるDirectXゲーム作成ソフト「Light Game Programming」
もしかすると、そのせいで普及しなかった・ブレーキがかかってしまったのかな。他にも、環境によってはフリーズするバグがいつまでも放置されてた時期があった、てな話も見かけたり。また、ライブラリ種類も、HSPに比べたらはるかに少なく。マニュアルを眺めてみたけど、自作ハードウェアの制御、簡易GUI作成等はできないように見えた。
HSPならゲーム以外のアプリも作成できるけど、LGPは、よりゲーム作成に特化したツールとして捉えるのが正しいのでしょうな。
_LightGameProgramming - Wikipedia
_プログラミング/言語・コンパイラ/LGP - game-develop.com wiki
exe化ができるらしいあたりはなんだかヨサゲ。
パッと見、HSPと似てるように思えたのだけど。開発が始まったのも結構古い時期らしいし。しかし、どうしてHSPほど広まってないのだろう…? 気になってググっていたら、どうやら最初の頃はシェアウェアだったようで。
_窓の杜 - 【NEWS】BASIC風言語によるDirectXゲーム作成ソフト「Light Game Programming」
もしかすると、そのせいで普及しなかった・ブレーキがかかってしまったのかな。他にも、環境によってはフリーズするバグがいつまでも放置されてた時期があった、てな話も見かけたり。また、ライブラリ種類も、HSPに比べたらはるかに少なく。マニュアルを眺めてみたけど、自作ハードウェアの制御、簡易GUI作成等はできないように見えた。
HSPならゲーム以外のアプリも作成できるけど、LGPは、よりゲーム作成に特化したツールとして捉えるのが正しいのでしょうな。
◎ Basic4GLも気になる。 :
◎ DarkBasicなるものも見かけたけど。 :
[ ツッコむ ]
2014/06/27(金) [n年前の日記]
#1 [dxruby] DXRubyでラスタースクロールを使ったレースゲームの画面を再現できないか実験その2
一応見た目だけはカーブっぽくなった、のかな。どうなんだろう。ちょっと自信無いですけど。
ソースは以下。
_raster_drive2.rb
_road_bg1.png
_road_bg2.png
横方向への移動は、y座標毎に求めたz値から移動量を求める、みたいな感じでやってるけど。考えてみたら画面の中央から斜めの直線を引くような感じでずらせばいいだけのような気もしてきたり。
カーブは、道路の画像をラスター単位で横方向にずらすことでそれっぽく見せるわけだけど。最初は x = y * y でずらしてみたけど、何か不自然な感じがしたので、x = y * y * y にしてみたり。
不自然さはあるものの、カーブまではなんとかなったとして。丘というか、坂の表現はどうすればいいのやら…。
ソースは以下。
_raster_drive2.rb
# ラスター処理でドライブゲームの画面を作る # 左右に移動できる処理を追加 require 'dxruby' def ease_in(a, b, percent); return a + (b - a) * (percent.to_f ** 2); end def ease_in_cubic(a, b, percent); return a + (b - a) * (percent.to_f ** 3); end def ease_out(a, b, percent); return a + (b - a) * (1 - ((1 - percent).to_f ** 2)); end def ease_in_out(a, b, percent); return a + (b - a) * ((-Math.cos( percent * Math::PI ) / 2 ) + 0.5); end font = Font.new(12) imgs_a = Image.loadTiles("road_bg1.png", 1, 480) imgs_b = Image.loadTiles("road_bg2.png", 1, 480) Window.bgcolor = [37, 150, 255] mode = 0 bz = 0 start_y = 1 z_spd = 1.0 z_spd_add = 0.5 x = 0 x_spd = 48 x_max = 3000 curve_dx = 0 curve_dx_spd = 16 curve_dx_max = 480 h = 1000 # 道路までの距離(高さ) fov = 100 sz = (640 / 2) / Math.tan((fov / 2) * Math::PI / 180.0) # 画面までの距離 Window.loop do break if Input.keyPush?(K_ESCAPE) # 上下キーで、奥方向の速度を変更 z_spd += z_spd_add if Input.keyDown?(K_UP) z_spd -= z_spd_add if Input.keyDown?(K_DOWN) # 左右キーで、横方向の移動量を変更 x += x_spd if Input.keyDown?(K_RIGHT) x -= x_spd if Input.keyDown?(K_LEFT) x = -x_max if x < -x_max x = x_max if x > x_max # D,Aキーで、カーブの量を変更 curve_dx += curve_dx_spd if Input.keyDown?(K_D) curve_dx -= curve_dx_spd if Input.keyDown?(K_A) curve_dx = curve_dx_max if curve_dx > curve_dx_max curve_dx = -curve_dx_max if curve_dx < -curve_dx_max # 道路を描画 start_y.step(240-1, 1) { |y| z = (h * sz / y) # y値に対応したz値を得る sx = x * sz / z # 横方向のスクリーン移動量を得る # カーブらしく見せるための横方向の移動量を得る if curve_dx == 0 cx = 0 else cx = ease_in_cubic(0, curve_dx, 1.0 - (y / 240.0)) end # 2枚の画像のどちらを描くか、z値を見て判別 i = y + 240 * (((z + bz).to_i / 320) & 0x01) Window.draw(0, y + 240, imgs_b[i]) # 地面を描く Window.draw(-160 + sx + cx, y + 240, imgs_a[i]) # 道路を描く } bz += z_spd # 速度を加算 [ "#{Window.real_fps.to_i} fps CPU: #{Window.getLoad.to_i} %", "Push Up, Down, Left, Right, A, D key", ].each_with_index {|s,i| Window.drawFont(4, 4 + i * 20, s, font) } end使用画像は以下。
_road_bg1.png
_road_bg2.png
- 上下キーを押すとz方向の速度を変更。
- 左右キーを押すと横方向へ移動
- A,Dキーを押すとカーブ量を変更。
横方向への移動は、y座標毎に求めたz値から移動量を求める、みたいな感じでやってるけど。考えてみたら画面の中央から斜めの直線を引くような感じでずらせばいいだけのような気もしてきたり。
カーブは、道路の画像をラスター単位で横方向にずらすことでそれっぽく見せるわけだけど。最初は x = y * y でずらしてみたけど、何か不自然な感じがしたので、x = y * y * y にしてみたり。
不自然さはあるものの、カーブまではなんとかなったとして。丘というか、坂の表現はどうすればいいのやら…。
[ ツッコむ ]
2014/06/28(土) [n年前の日記]
#1 [unity] Unity 4.5 の奇妙な挙動
_2014/02/17の日記
で公開してた、Unityのプロジェクトフォルダ一式について。コメント欄で、「DLしたけどキャラクター達が地面の下に落ちていく」と報告していただけたので、自分も検証作業を。
Unity を、4.3 → 現行版 4.5.1f3 に更新してから試したのですけど。自分の環境でも、キャラクター達が地面の下に落ちていくことを確認しました。
地面の下に落ちていく条件、落ちていかない条件について調べましたが、どうやら Plane + Box Collider 2D を使って地面を表現しようとすると、すり抜けてしまうようで。
で、どうしてこうなるかと言うと。
ということで。とりあえずですが、Plane を Quad に変更した版をアップロードしておきました。
最新版の Unity を使うと、過去に作ったプロジェクトを読み込んでも正常動作しない、ってのはなんだか痛いですな…。
Unity を、4.3 → 現行版 4.5.1f3 に更新してから試したのですけど。自分の環境でも、キャラクター達が地面の下に落ちていくことを確認しました。
- DLしたzipを解凍して、プロジェクトとして開いてもそうなるし。
- 以前保存していた、HDD内の元プロジェクトを開いてもそうなるし。
地面の下に落ちていく条件、落ちていかない条件について調べましたが、どうやら Plane + Box Collider 2D を使って地面を表現しようとすると、すり抜けてしまうようで。
- Sprite + Box Collider 2D なら、すり抜けない。
- Quad + Box Collider 2D も、すり抜けない。
- Plane + Box Collider 2D は、すり抜けちゃう。
で、どうしてこうなるかと言うと。
- Plane を2Dゲームっぽく表示するためには回転しないといけない。
- 現在の Unityは、Box Collider 2D が、x軸回転、y軸回転、z軸回転をちゃんと反映する仕様になってる。
- Sprite と Quad は、x軸回転、y軸回転しなくても、2Dゲーム画面っぽく表示できるので、Box Collider 2D の指定値・アタリ範囲がそのまま使われる。
- Plane は x軸で90度回転、y軸で180度回転、等をしないと2Dゲームっぽく表示されない。そのせいで Box Collider 2D のアタリ範囲までグルグルと3D計算で回転しちゃって、アタリ範囲が思ったような状態にならない。
ということで。とりあえずですが、Plane を Quad に変更した版をアップロードしておきました。
最新版の Unity を使うと、過去に作ったプロジェクトを読み込んでも正常動作しない、ってのはなんだか痛いですな…。
[ ツッコむ ]
2014/06/29(日) [n年前の日記]
#1 [cg_tools] アプリの普及はどこで明暗が分かれるのだろう
_2Dキャラアニメ作成ツール「えもふり」公開!なにこれすごい | オタク.com
という記事を眺めてるうちに、なんだか疑問が湧いて。
随分前から、Xprite という、同種の処理をするソフトがあったわけですけど。
_STUDIO yu- | Xprite特設ページ
_【レビュー】ゲームやアニメに使える2Dスプライトアニメーション作成ツール「Xprite」 - 窓の杜
でも、あまり注目されてる感じがしなくて。しかし、「えもふり」は、なんだか注目されてる…。一体どこで差がついてるんだろう…。
パッと見の印象が違うのだろうか。しかし、どっちも女の子を動かしてるように見えるのだけど。
それとも、仕様が関係してるのかな。「えもふり」の、「psdファイルを渡せば作業が始められる」てなあたりが効いてたり? あるいは、人の顔を動かすことに特化してるように見せたあたりがポイントなのかしら。
そこそこ似たようなことをしていても、注目のされ方が違うあたり、なんだか気になります。一体どこらへんが肝なんだろう。
とりあえず、 _E-mote があまり話題になってなかったのに、無料版の「えもふり」が出てきたら急に話題になったあたり、無料版が存在すると宣伝効果がかなり期待できるのは間違いなさそうだなと思いました。
考えてみたら Unity もそうか。Unity も、仮に有償版しか無かったら、あれほど注目されてなかっただろうな…。
随分前から、Xprite という、同種の処理をするソフトがあったわけですけど。
_STUDIO yu- | Xprite特設ページ
_【レビュー】ゲームやアニメに使える2Dスプライトアニメーション作成ツール「Xprite」 - 窓の杜
でも、あまり注目されてる感じがしなくて。しかし、「えもふり」は、なんだか注目されてる…。一体どこで差がついてるんだろう…。
パッと見の印象が違うのだろうか。しかし、どっちも女の子を動かしてるように見えるのだけど。
それとも、仕様が関係してるのかな。「えもふり」の、「psdファイルを渡せば作業が始められる」てなあたりが効いてたり? あるいは、人の顔を動かすことに特化してるように見せたあたりがポイントなのかしら。
そこそこ似たようなことをしていても、注目のされ方が違うあたり、なんだか気になります。一体どこらへんが肝なんだろう。
とりあえず、 _E-mote があまり話題になってなかったのに、無料版の「えもふり」が出てきたら急に話題になったあたり、無料版が存在すると宣伝効果がかなり期待できるのは間違いなさそうだなと思いました。
考えてみたら Unity もそうか。Unity も、仮に有償版しか無かったら、あれほど注目されてなかっただろうな…。
◎ SpriteStudioてのもあるけれど。 :
_ウェブテクノロジ OPTPiX SpriteStudio
も同種の処理をしていると捉えることもできそうな気もする。ただ、ここまで来ると、Adobe Flash との違いが分かりづらいけど。
自由度が高いと、何に使えるのかイメージしづらくて不利になる、てなところもあるのかな。分かりませんけど。
自由度が高いと、何に使えるのかイメージしづらくて不利になる、てなところもあるのかな。分かりませんけど。
[ ツッコむ ]
#2 [pc][web] 体験版のダウンロード時までメールアドレスや名前の入力を要求する必要はないだろうと思うのだけど
SpriteStudio についてメモってる際になんとなく思い出したのでメモ。メモと言うか、愚痴と言うか。
例えば、ウェブテクノロジは体験版のダウンロード時ですらメールアドレスや名前の入力を要求してくるのですが。大変失礼ながらアレはアホだわと常々思っておりまして。特に、コミPo!の体験版すらメールアドレスを要求することには呆れていて。
例えばの話、デパ地下で、客が試食しようとするたびに、一々記帳を要求してたら、売れる商品も売れないだろうなと。皆、味見もせずに立ち去るよなと。無意味な記帳を要求することで、一体どれだけ客になりそうな人をみすみす逃しているのか、少し想像したら、たちまち血の気が引いていきそうなものだけど。
まあ、件の会社に限った話じゃないですけど、そういうアレなことを平気でしてる会社が多過ぎて。「ちゃんと考えた上でその情報を集めてんの?」と問い詰めたくなる時が多々あって。
例えば Unity は、ダウンロード時にメールアドレスや名前なんか要求してません。Unity って1GB以上もあるアプリですけど、ダウンロードページから、「たったのワンクリック」でダウンロードできる。それでいて、あんなに注目されてるし、話題にもなってる。 *1
そういう事例と比べると、体験版ダウンロード時にメールアドレスを要求する会社なんて、こりゃアホですわ。いい製品作ってるのに、もったいない。せっかく製品に興味を持ってくれた人を追い返してどうするんだろうと。
でもまあ、あの状態でも飯が食えてるのだろうから、このあたり余計なお世話だろうな…。おそらく、競争相手が居ないブルーオーシャンだから、のんびりしていられるのかもしれず。そもそも、あの製品群、個人相手に商売する気も無さそうだし…。
例えば、ウェブテクノロジは体験版のダウンロード時ですらメールアドレスや名前の入力を要求してくるのですが。大変失礼ながらアレはアホだわと常々思っておりまして。特に、コミPo!の体験版すらメールアドレスを要求することには呆れていて。
- 今までにないジャンルのソフトだから、より多くの人に、とにかく触ってもらって、変な遊び方を見つけてもらわないと話にならない。
- そのためには、気軽にカチカチとクリックしていくだけで、すんなり体験できるかどうかが重要。
- しかし、そのための体験版ダウンロード時からして、「メルアドを入力しろ!」と…。
例えばの話、デパ地下で、客が試食しようとするたびに、一々記帳を要求してたら、売れる商品も売れないだろうなと。皆、味見もせずに立ち去るよなと。無意味な記帳を要求することで、一体どれだけ客になりそうな人をみすみす逃しているのか、少し想像したら、たちまち血の気が引いていきそうなものだけど。
まあ、件の会社に限った話じゃないですけど、そういうアレなことを平気でしてる会社が多過ぎて。「ちゃんと考えた上でその情報を集めてんの?」と問い詰めたくなる時が多々あって。
- メールアドレスや名前という個人情報を集めて、そこから何か売上げに繋がる結果は、ちゃんと出てるの?
- なんとなくで集めて、客にとって興味が無いSPAMを送り付けて、それっきりじゃねえの?
- 万が一、客の個人情報が流出したら、お前達は、どう責任取るつもり?
- 流出時、どのくらい損害を出すか見積もった上で、それでも自社に利がある! と踏んだ上で集めてんの?
例えば Unity は、ダウンロード時にメールアドレスや名前なんか要求してません。Unity って1GB以上もあるアプリですけど、ダウンロードページから、「たったのワンクリック」でダウンロードできる。それでいて、あんなに注目されてるし、話題にもなってる。 *1
そういう事例と比べると、体験版ダウンロード時にメールアドレスを要求する会社なんて、こりゃアホですわ。いい製品作ってるのに、もったいない。せっかく製品に興味を持ってくれた人を追い返してどうするんだろうと。
でもまあ、あの状態でも飯が食えてるのだろうから、このあたり余計なお世話だろうな…。おそらく、競争相手が居ないブルーオーシャンだから、のんびりしていられるのかもしれず。そもそも、あの製品群、個人相手に商売する気も無さそうだし…。
*1: ただ、Unity は、インストール後に、何か登録作業があったような気もする…。
[ ツッコむ ]
#3 [anime] プリキュアの髪の毛のグラデーション
幸福充填プリキュアを眺めていたら、髪の毛にグラデーションがかかっていることに気がついて。
プリキュアに、グラデーション塗りって必要なのかな…。個人的には、要らないんじゃないかと一瞬思えてしまったり。と言うのも、(大変失礼ながら)作画はヘロヘロなのにグラデはキッチリかけるとか、ちょっと馬鹿馬鹿しいよなと。別のところに力を入れたほうがいいんじゃないのかと。
でも、原動画ではない部署で手を入れることができるから、これはこれでアリなのかな。よくよく見てみたら、グラデというより、色の境界線をぼかすような処理に近い気もするし。このくらいならフィルタをかければ一発だからそんなに負担ではない、みたいな話かも。であれば、やらないよりはやったほうがいいのだろうか。どうなんだろう。
そういえば、番組の冒頭で登場する過去作品のキャラ達も、それっぽい処理をかけた状態で仕上げてるようで。一番最初の黒いプリキュアですら、見た目艶々していて。当時の映像と比較してみたい気もしてきたり。
何時頃からこういう塗りになったのか気になってググってみたけど、前作の「ドキドキプリキュア」の時点ではパキッとした塗りがほとんどのように見えた。 *1 どうして今作からこういう塗りに…? 今作から3DCG映像が本編に挿入されるから、せめて塗りだけでも3DCGに近づけよう、てな試みだったりするのかな。
このあたり、 _1stガンダムのアレなカットの数々にレタッチした例の画像 を思い出して、なんだか考え込んでしまうわけで。例の画像を見て…。
プリキュアに、グラデーション塗りって必要なのかな…。個人的には、要らないんじゃないかと一瞬思えてしまったり。と言うのも、(大変失礼ながら)作画はヘロヘロなのにグラデはキッチリかけるとか、ちょっと馬鹿馬鹿しいよなと。別のところに力を入れたほうがいいんじゃないのかと。
でも、原動画ではない部署で手を入れることができるから、これはこれでアリなのかな。よくよく見てみたら、グラデというより、色の境界線をぼかすような処理に近い気もするし。このくらいならフィルタをかければ一発だからそんなに負担ではない、みたいな話かも。であれば、やらないよりはやったほうがいいのだろうか。どうなんだろう。
そういえば、番組の冒頭で登場する過去作品のキャラ達も、それっぽい処理をかけた状態で仕上げてるようで。一番最初の黒いプリキュアですら、見た目艶々していて。当時の映像と比較してみたい気もしてきたり。
何時頃からこういう塗りになったのか気になってググってみたけど、前作の「ドキドキプリキュア」の時点ではパキッとした塗りがほとんどのように見えた。 *1 どうして今作からこういう塗りに…? 今作から3DCG映像が本編に挿入されるから、せめて塗りだけでも3DCGに近づけよう、てな試みだったりするのかな。
このあたり、 _1stガンダムのアレなカットの数々にレタッチした例の画像 を思い出して、なんだか考え込んでしまうわけで。例の画像を見て…。
- 原動画がヘロヘロでは、いくらレタッチしてもダメ、と判断すべきなのか。
- 原動画がヘロヘロでも、塗りや撮影でいくらでもそれっぽくなる、と判断すべきなのか。
*1: 昔の作品も、変身バンク等では、ぼかしだかグラデだかがかかってるみたいだけど。
[ ツッコむ ]
#4 [zatta][neta] サイコって何だろう
_「このタイミングでサッカー嫌いを表明する人間はサイコ」
なる言説を目にして、先日このタイミングでサッカー嫌いをわざわざ表明する羽目になってしまった自分としてはちょっとグサッときたのだけど。
Firefoxが毎回起動するたびにサッカー画像をネット上からロードして表示してしまうから、自分だってそんなことをわざわざこのタイミングで表明する羽目になったわけで。あっちから強制的に見せつけといて、「いや、俺はソレ興味無いんで。ていうか嫌いなんで」と少し洩らしただけなのにサイコ呼ばわりなんて酷いなー、てなことを思いました。
それはともかく、そこで言ってるサイコって何だろう? と疑問が湧いたわけで。言葉としてはよく聞くのだけど、恥ずかしながら正確な意味・定義を知らないのですよ…。
Firefoxが毎回起動するたびにサッカー画像をネット上からロードして表示してしまうから、自分だってそんなことをわざわざこのタイミングで表明する羽目になったわけで。あっちから強制的に見せつけといて、「いや、俺はソレ興味無いんで。ていうか嫌いなんで」と少し洩らしただけなのにサイコ呼ばわりなんて酷いなー、てなことを思いました。
それはともかく、そこで言ってるサイコって何だろう? と疑問が湧いたわけで。言葉としてはよく聞くのだけど、恥ずかしながら正確な意味・定義を知らないのですよ…。
◎ ググってみたけどよくわからず。 :
_サイコ - Wikipedia
を眺めたら、たくさんあり過ぎて、何が何やら。
とりあえず、 _サイコ (1960年の映画) のヒットで、この単語が普及したらしいけど。恥ずかしながら自分は未見で。映画を見ていれば定義が分かるのだろうか。でもホラー映画だから…今後も怖くて見ないであろう予感。
「サイコパス」で辿ってみたら、 _精神病質 - Wikipedia に転送されたのだけど、眺めているうちにゲンナリ。これに全く当てはまらない人が居たら、ソイツはもう人間じゃねえよ…。いやまあ、それぞれの要素について社会的許容範囲を超えたらこういう分類されちゃうよ、という話に過ぎないのだろうけど。
よくよく読んでみると、「サイコパス」と「サイコ」は違うんじゃないかと思えてきたり。件の文章に「サイコパス」の定義を当てはめてみると、文として成立しない感じ。
とりあえず、 _サイコ (1960年の映画) のヒットで、この単語が普及したらしいけど。恥ずかしながら自分は未見で。映画を見ていれば定義が分かるのだろうか。でもホラー映画だから…今後も怖くて見ないであろう予感。
「サイコパス」で辿ってみたら、 _精神病質 - Wikipedia に転送されたのだけど、眺めているうちにゲンナリ。これに全く当てはまらない人が居たら、ソイツはもう人間じゃねえよ…。いやまあ、それぞれの要素について社会的許容範囲を超えたらこういう分類されちゃうよ、という話に過ぎないのだろうけど。
よくよく読んでみると、「サイコパス」と「サイコ」は違うんじゃないかと思えてきたり。件の文章に「サイコパス」の定義を当てはめてみると、文として成立しない感じ。
◎ 正確な定義を知っていても意味が無いことに気付いた。 :
考えてみたら、「サイコ」発言してる各人にとって、「サイコ」の定義がそれぞれ違うだろうから、調べてみても意味が無いような気がしてきたり。
例えば、「ハッカー」「ホームページ」「インターネット」と呼んでる人相手に、「クラッカー」「Webサイト」「電子メール」等の正しい定義を持ち出してみても意味が無いわけで。「サイコ」も同じだよなと。相手がどんな定義で使ってるつもりなのか、こっちが空気を読んで察してあげないといかんのではないか、と。
おそらくだけど、世間一般では、「キチガイ」の代わりに、上品(?)ぶって「サイコ」と言ってるだけじゃないか、という気もしてきたり。「お前、おかしいよ」と言いたいけれど、そのままだとあまりに素朴な物言いでダサイから、「サイコ」という外来語を持ち出してちょっとカッコイイ物言いをしたつもりになってみました、みたいな。
コンサルタントが「ソリューション」「シナジー」「コンプライアンス」とかその手の単語をやたらと使って武装するソレに近いんじゃないか。たぶん。まあ、自分もそういう物言いはよくやっちゃってる気がしますけど。
てな想像をしているうちに、もしかするとそのうち「サイコ」という単語も余計なトラブルを招くことが多くなって、別の単語を使い始めたりしないだろうか、てなくだらない妄想を。…星新一作品等で既にそういう作品がありそうな。
その手のくだらない妄想を作品レベルまで持っていける・昇華できる人なら、サイコ呼ばわりされずに済むのかしら。例えば宮崎駿監督が名監督と呼ばれてるように、創作側になれたら社会的に許容される幅が大きくなるような気がする。というか創作者なら、サイコ呼ばわりされても、それがむしろ、ある種の称号・褒め言葉になる時もありそうな。
こんな風にどうでもいいことをだらだらメモってるだけで、またサイコ呼ばわりされそう。ていうか長文ブロガーと呼ばれる方々も、ほとんどがサイコ扱いされそうな気もしてきたり。気がするだけで実際どうかは分かりませんが。
例えば、「ハッカー」「ホームページ」「インターネット」と呼んでる人相手に、「クラッカー」「Webサイト」「電子メール」等の正しい定義を持ち出してみても意味が無いわけで。「サイコ」も同じだよなと。相手がどんな定義で使ってるつもりなのか、こっちが空気を読んで察してあげないといかんのではないか、と。
おそらくだけど、世間一般では、「キチガイ」の代わりに、上品(?)ぶって「サイコ」と言ってるだけじゃないか、という気もしてきたり。「お前、おかしいよ」と言いたいけれど、そのままだとあまりに素朴な物言いでダサイから、「サイコ」という外来語を持ち出してちょっとカッコイイ物言いをしたつもりになってみました、みたいな。
コンサルタントが「ソリューション」「シナジー」「コンプライアンス」とかその手の単語をやたらと使って武装するソレに近いんじゃないか。たぶん。まあ、自分もそういう物言いはよくやっちゃってる気がしますけど。
てな想像をしているうちに、もしかするとそのうち「サイコ」という単語も余計なトラブルを招くことが多くなって、別の単語を使い始めたりしないだろうか、てなくだらない妄想を。…星新一作品等で既にそういう作品がありそうな。
その手のくだらない妄想を作品レベルまで持っていける・昇華できる人なら、サイコ呼ばわりされずに済むのかしら。例えば宮崎駿監督が名監督と呼ばれてるように、創作側になれたら社会的に許容される幅が大きくなるような気がする。というか創作者なら、サイコ呼ばわりされても、それがむしろ、ある種の称号・褒め言葉になる時もありそうな。
こんな風にどうでもいいことをだらだらメモってるだけで、またサイコ呼ばわりされそう。ていうか長文ブロガーと呼ばれる方々も、ほとんどがサイコ扱いされそうな気もしてきたり。気がするだけで実際どうかは分かりませんが。
[ ツッコむ ]
#5 [web][neta] ネット上ではどうして正直に全部喋ってしまうんだろう
「サッカーに限らずスポーツは嫌い」と、自分は正直に表明しちゃってるけど。これがネット上ではなくて、リアルワールドだったら、「いやあ、自分、○○は全然詳しくないんですけど…。日本って結構強いんですか?」と、完全に興味ゼロのくせして実に白々しく相手に質問したりして会話を繋げるんだろうなー、と思えてきたわけで。
ネット上の振舞いを、リアルワールドでもそのまんましてるわけねえよな…。世間話の最中に「○○は嫌い」と言い出して、場の雰囲気を悪化させることなんて、そんなに無いはず…。いや、うっかりやらかして、数日経ってから「うわああ」と頭を壁に打ち付けたくなる時も結構あるのですけど、それでも基本的には、相手のソレを否定も肯定もせず、上手に受け流せるのが賢いやり取り、と思いながら会話を試みているつもりで…。
なのにどうしてネット上では、正直に好き嫌いまで言ってしまって、余計なトラブルを招いてしまうのだろう。
待てよ? 考えてみたら、ネット上ではそもそも会話なんかしてないのか。blog にしろ、Web日記にしろ、自分はこう思った、こういうことがあった、とかそういうことしか書いてないわけだし。コレ、会話じゃなくて記録だよな。だから正直に書いてしまうのかも。
これが逆に、正直になるどころか、自身のWeb日記にあらゆる嘘八百を書き連ねてる姿がそこにあったとしたら、ソレもちょっとどうかと思えるし。あるいは、自身の考えや感想を一切書かず、ひたすら大量にはてブしてたりする姿も、なんだか気持ち悪いものがあるし。そう考えると、まだ正直にアレコレ書き残してるほうが、人としてはマシだったりするのかなと思えてきたりもしたけどよくわからないです。仮面をつけて、相手の顔色を伺ってばかりいるほうが、人としては正常なのだろうか…?
てなことをぼんやり思ったとメモ。オチなんか無いです。ココは、自分の思考メモ・作業メモを書き散らかすだけの場でしかないので。
ネット上の振舞いを、リアルワールドでもそのまんましてるわけねえよな…。世間話の最中に「○○は嫌い」と言い出して、場の雰囲気を悪化させることなんて、そんなに無いはず…。いや、うっかりやらかして、数日経ってから「うわああ」と頭を壁に打ち付けたくなる時も結構あるのですけど、それでも基本的には、相手のソレを否定も肯定もせず、上手に受け流せるのが賢いやり取り、と思いながら会話を試みているつもりで…。
なのにどうしてネット上では、正直に好き嫌いまで言ってしまって、余計なトラブルを招いてしまうのだろう。
待てよ? 考えてみたら、ネット上ではそもそも会話なんかしてないのか。blog にしろ、Web日記にしろ、自分はこう思った、こういうことがあった、とかそういうことしか書いてないわけだし。コレ、会話じゃなくて記録だよな。だから正直に書いてしまうのかも。
これが逆に、正直になるどころか、自身のWeb日記にあらゆる嘘八百を書き連ねてる姿がそこにあったとしたら、ソレもちょっとどうかと思えるし。あるいは、自身の考えや感想を一切書かず、ひたすら大量にはてブしてたりする姿も、なんだか気持ち悪いものがあるし。そう考えると、まだ正直にアレコレ書き残してるほうが、人としてはマシだったりするのかなと思えてきたりもしたけどよくわからないです。仮面をつけて、相手の顔色を伺ってばかりいるほうが、人としては正常なのだろうか…?
てなことをぼんやり思ったとメモ。オチなんか無いです。ココは、自分の思考メモ・作業メモを書き散らかすだけの場でしかないので。
[ ツッコむ ]
2014/06/30(月) [n年前の日記]
#1 [cg_tools] えもふりを試用
この手のツールは触ってみないと何とも言えないところがあるので、試しにインストールして、少し触ってみたり。
同梱のサンプルファイルを読みこんでちょっと動かしてみたけれど。なるほど、これは面白いなあ…。静止画がぬるぬる動き始めるあたりに、純粋な驚きが。いやまあ、仕組みは別に新しいわけではないのですけど。既存技術のまとめ方、あるいは見せ方が上手い、と思ったわけで。
可愛い女の子をぬるぬる動かせるという点を前面に押し出しているあたりはグッドのような気がしたり。同じ仕組みでも、狼、スライム、実写取り込みの外国人の顔が動くデモ映像より、人目を引くよなと。
全パーツを1つのpsdファイルでインポートするあたり、賢いなと感心。これがもし…。
ただ、Adobeのクローズドなフォーマットであるpsdファイルを頼ってしまって大丈夫なのかな…。と思ったけど、ググってみたら今時は _Adobe Photoshop File Formats Specification で仕様が公開されてるの? 知らなかった! だったら問題無いか…。レイヤーを内包できて、そこそこ普及しちゃってるメジャーな画像フォーマットと言うとpsdしか無いわけで。今後もその手の用途では、psd一択になりそうな。それにしても何時公開したんだろう…。ググってみても、ニュースになってないみたいだけど…。
各パーツの可動範囲を、レイヤー上の矩形領域で指定するあたりも、これは頭がいいなと。富豪的プログラミングに近い発想を感じたり。リソースをたくさん使うことで利便性が増すなら、今時ソレをやらない理由はないですな。
何より、 _E-mote/えもふりが元々は多関節キャラエディタだった という話を目にして、なんだか目頭が熱く…。メガドラのタイトルを作ってた頃、先輩が、「本当は多関節キャラエディタを作って、プログラマー以外も多関節キャラを作れるようにしたいんだけど、そこまで手が回らないんだ」と悔やんでたことを思い出したりして。やっぱりエディタが存在する・エディタを作っておくのが正解だよなと。どう考えてもM2さんは正しい。それにしても、あの頃どうにかその手のエディタを作っておけば、3Dときメモを作り始める前に、2Dでぬるぬる動くときメモを出せて、展開が違っていたのかも、などと妄想したりもして。 *1
同梱のサンプルファイルを読みこんでちょっと動かしてみたけれど。なるほど、これは面白いなあ…。静止画がぬるぬる動き始めるあたりに、純粋な驚きが。いやまあ、仕組みは別に新しいわけではないのですけど。既存技術のまとめ方、あるいは見せ方が上手い、と思ったわけで。
可愛い女の子をぬるぬる動かせるという点を前面に押し出しているあたりはグッドのような気がしたり。同じ仕組みでも、狼、スライム、実写取り込みの外国人の顔が動くデモ映像より、人目を引くよなと。
全パーツを1つのpsdファイルでインポートするあたり、賢いなと感心。これがもし…。
- 1パーツにつき、1つのpngファイルという仕様だったら、膨大な画像数を前にしてゲンナリ。
- 1つのpngファイルに全パーツが収まってる、スプライトシートのような状態では、各パーツの領域を指定する作業だけでウンザリ。
ただ、Adobeのクローズドなフォーマットであるpsdファイルを頼ってしまって大丈夫なのかな…。と思ったけど、ググってみたら今時は _Adobe Photoshop File Formats Specification で仕様が公開されてるの? 知らなかった! だったら問題無いか…。レイヤーを内包できて、そこそこ普及しちゃってるメジャーな画像フォーマットと言うとpsdしか無いわけで。今後もその手の用途では、psd一択になりそうな。それにしても何時公開したんだろう…。ググってみても、ニュースになってないみたいだけど…。
各パーツの可動範囲を、レイヤー上の矩形領域で指定するあたりも、これは頭がいいなと。富豪的プログラミングに近い発想を感じたり。リソースをたくさん使うことで利便性が増すなら、今時ソレをやらない理由はないですな。
何より、 _E-mote/えもふりが元々は多関節キャラエディタだった という話を目にして、なんだか目頭が熱く…。メガドラのタイトルを作ってた頃、先輩が、「本当は多関節キャラエディタを作って、プログラマー以外も多関節キャラを作れるようにしたいんだけど、そこまで手が回らないんだ」と悔やんでたことを思い出したりして。やっぱりエディタが存在する・エディタを作っておくのが正解だよなと。どう考えてもM2さんは正しい。それにしても、あの頃どうにかその手のエディタを作っておけば、3Dときメモを作り始める前に、2Dでぬるぬる動くときメモを出せて、展開が違っていたのかも、などと妄想したりもして。 *1
◎ 仕組みについて。 :
仕組み自体は、失礼ながら、別に新しくもないよなと。
_Live2D
も似たような仕組みだろうし。
また、Flashアニメが流行ってた頃の、 _なつみSTEP! でも、こういう仕組みで動かしてるカットが多数あるし。あの作品って、何年頃に制作されたんでしたっけか。少なくとも10年以上前だと思うけど…。
そもそも、宮崎駿監督が絶賛したと言われる、 _霧につつまれたハリネズミ(霧の中のハリネズミ) も同じ仕組みだし。1975年のフィルム作品でもやってるわけで。
なので、「技術の進歩ってスゲー」等の感想を見かけると、なんだかもやもやしちゃったり。やってる人達は随分前からやってたわけで。ここに来て突然出現したものでもないよなと。
しかし…。
Flash、After Effects、 _Anime Studio _(Anime Creator) 等で、似たようなことはやれなくもないけど。それらは汎用性がある代わりに手間が増えて、「なんだか大変そう」「これは自分には無理じゃないか」と思えてくるわけで。
「このくらいなら自分もできるんじゃないか」と思ってもらえそうか、そこは大事だよなと。えもふりは、そこらへんがイイ感じだよなと。…考えてみたら、iPhone等のタッチパネル端末がウケたのもソレなのかな。既存の技術を上手に組み合わせて、「自分もできそう」と思わせられるところまで持っていけるかどうか、みたいな。
更に、Twitter や pixiv で、アニメgif相当を貼れるようになったタイミングで、無料版を発表できたあたりも上手いなと。とにかく、無料版の存在・出現は大きい。 _年間契約は最低でも30万円 てな状態では、個人で少し遊んでみるなんて無理なのでスルーするしか無く。
同じ技術も、周囲の状況をどう整えるかで、注目されたりされなかったりしてしまうのだなと再認識、でした。良い製品を作っていても、上手に宣伝できなかったら埋もれちゃうよなと。
また、Flashアニメが流行ってた頃の、 _なつみSTEP! でも、こういう仕組みで動かしてるカットが多数あるし。あの作品って、何年頃に制作されたんでしたっけか。少なくとも10年以上前だと思うけど…。
そもそも、宮崎駿監督が絶賛したと言われる、 _霧につつまれたハリネズミ(霧の中のハリネズミ) も同じ仕組みだし。1975年のフィルム作品でもやってるわけで。
なので、「技術の進歩ってスゲー」等の感想を見かけると、なんだかもやもやしちゃったり。やってる人達は随分前からやってたわけで。ここに来て突然出現したものでもないよなと。
しかし…。
- 専用ツールをちゃんと作って結構な部分を自動化できた点。
- やれることを制限した代わりに操作手順量を激減させて、誰でもできそうな雰囲気にした点。
- 昔のフィルム作品でやってたソレを、現代のデジタル機器の上でリアルタイムにやってみせるという点。
Flash、After Effects、 _Anime Studio _(Anime Creator) 等で、似たようなことはやれなくもないけど。それらは汎用性がある代わりに手間が増えて、「なんだか大変そう」「これは自分には無理じゃないか」と思えてくるわけで。
「このくらいなら自分もできるんじゃないか」と思ってもらえそうか、そこは大事だよなと。えもふりは、そこらへんがイイ感じだよなと。…考えてみたら、iPhone等のタッチパネル端末がウケたのもソレなのかな。既存の技術を上手に組み合わせて、「自分もできそう」と思わせられるところまで持っていけるかどうか、みたいな。
更に、Twitter や pixiv で、アニメgif相当を貼れるようになったタイミングで、無料版を発表できたあたりも上手いなと。とにかく、無料版の存在・出現は大きい。 _年間契約は最低でも30万円 てな状態では、個人で少し遊んでみるなんて無理なのでスルーするしか無く。
同じ技術も、周囲の状況をどう整えるかで、注目されたりされなかったりしてしまうのだなと再認識、でした。良い製品を作っていても、上手に宣伝できなかったら埋もれちゃうよなと。
◎ 妄想。 :
触っているうちに少し妄想。
自分は絵描きじゃないので、元画像を用意するのがちと大変というか、若干くじけてしまったので、サンプルpsdを少し多目にどこかで公開しておいたほうがいいような気もしたり。「絵描きさんしか使えないツールなのだ」と思い込まれたら、それはよろしくないよなと。
MMDと似たような感じで、色んな絵描きさんが「俺の描いたpsdを動かしてみてくれ」と公開する流れができたら、もう少し盛り上がりそうだけど。そこまで行くかどうかは、ちとよく分からず。
どこかのアニメ番組で、えもふりで動かすこと前提のpsdファイルを公式サイトで配布をしたら、宣伝効果が期待できないかなと思ったり。
いや、考えてみたら、アニメじゃなくてもいいのか。実写ドラマの俳優さんをレタッチしてパーツ分けpsdにして番組の公式サイトで公開、てのも宣伝になるかもしれない。おそらくキモイ動きになるあたり、少しは喜ばれそう。
でもまあ、わざわざpsdをDLさせなくても、公式サイトに JavaScript か Flash で貼っとけばいいだけの話なのかな。…そういう形にすると、ライセンス料が高くなりそうだし、インパクトも弱まりそうだけど。
Webサイト上のソレと、ローカルにDLするソレ。やれることは同じだとしても、ローカルにDLして好き勝手やれる、とユーザに思い込んでもらえるかどうかが結構大事だったりしないのかな。それとも、そのあたりの感覚を持ってるのはおじさんだけで、スマホでWebサービス・クラウドを使いこなす若い世代には、もう無かったりするのかな。どうなんだろう。
自分は絵描きじゃないので、元画像を用意するのがちと大変というか、若干くじけてしまったので、サンプルpsdを少し多目にどこかで公開しておいたほうがいいような気もしたり。「絵描きさんしか使えないツールなのだ」と思い込まれたら、それはよろしくないよなと。
MMDと似たような感じで、色んな絵描きさんが「俺の描いたpsdを動かしてみてくれ」と公開する流れができたら、もう少し盛り上がりそうだけど。そこまで行くかどうかは、ちとよく分からず。
どこかのアニメ番組で、えもふりで動かすこと前提のpsdファイルを公式サイトで配布をしたら、宣伝効果が期待できないかなと思ったり。
- プリキュアのように3DCGモデルを用意して配布、とかになってしまうと作業が大変過ぎるし、何に使われるか分からんという不安も出てくるので、とても無理だけど。
- これがもし、手描きでパーツ分けしたpsdを用意するだけなら、アニメーターさんにお願いすればどうにかなるし。決まった角度内で動かすことしかできないから、使われる範囲にも自ずと制限を与えられるし。
いや、考えてみたら、アニメじゃなくてもいいのか。実写ドラマの俳優さんをレタッチしてパーツ分けpsdにして番組の公式サイトで公開、てのも宣伝になるかもしれない。おそらくキモイ動きになるあたり、少しは喜ばれそう。
でもまあ、わざわざpsdをDLさせなくても、公式サイトに JavaScript か Flash で貼っとけばいいだけの話なのかな。…そういう形にすると、ライセンス料が高くなりそうだし、インパクトも弱まりそうだけど。
Webサイト上のソレと、ローカルにDLするソレ。やれることは同じだとしても、ローカルにDLして好き勝手やれる、とユーザに思い込んでもらえるかどうかが結構大事だったりしないのかな。それとも、そのあたりの感覚を持ってるのはおじさんだけで、スマホでWebサービス・クラウドを使いこなす若い世代には、もう無かったりするのかな。どうなんだろう。
*1: けれど、あの頃はそういうツールを動かせそうなハードが無かった・PCのハードウェアスペックが低かったから、やっぱり実現性は低かったかもしれない。いや、PC-9801じゃなくて、X68Kが開発機材として渡されてたら、違ったのかな。
[ ツッコむ ]
#2 [nitijyou] 首が痛い
首なのか右肩なのか分からないけど、なんだかそのあたりが痛いので寝ます。
犬の散歩をした際に、グイグイ引っ張られて、どこか痛めてしまったのかもしれない。
犬の散歩をした際に、グイグイ引っ張られて、どこか痛めてしまったのかもしれない。
[ ツッコむ ]
以上、30 日分です。
拝見いたしました、ちょっと興味がありましてメールさせていただきます
私もDrawgraphic 2のダウンロード版を使ってみました
というのもMicrographx Windows Draw6を前から使っていて 大変に良いソフトだったのですが今 セブン64Bit 以上で使えないのでこれを使ってみましたがインターネットに繋がっていないと編集が思うように出来なくて困っています 良い方法がないものでしょうか