ヒマをみつけてWeb開発
その場の思い付きを、ヒマをみつけてWebサイトにしてみるブログ

Flashのお絵かきツールでアンチエイリアスをOFFにする

Sunday, 1 November 2009 14:05 by sabro

先日、Flashのお絵かきツールで描いた絵を、セカンドライフのボードに表示できるSLらくがきボードというのをリリースしました。実際のお絵かきツールは、こことかで見れます。

このツールではアンチエイリアスのON、OFFが可能になっていますが、実は先に実現可能かどうかは考えたわけではなく、そのうち出来るようにするからーとアナウンスして、とりあえずリリースしてしまったものなのです。
アンチエイリアス
後から調べたところ、ニコニコ大百科のお絵カキコや、Sumo Paintなどでも、アンチエイリアスOFFは実装されてないことを知って、出来ないのかなと慌てふためいたのですが、色々試したところなんとか出来たので、そのやり方を書いてみようと思います。

本格的な説明に行く前に、私が作ったお絵かきツールのキャンバスの構造の説明から。キャンバスは、もろもろの理由により以下のようになっています。
キャンバス
これは、5枚のレイヤーがあって、3枚目が選択されている場合の図です。3枚目の前に描画用のレイヤーがあり、ここへ描いた線や図形などを実際のレイヤーに、BitmapData.drawメソッドで転写する仕組みになっています。

Bitmap.drawメソッドの引数はいくつかありますが、ColorTransformクラスを渡すことで転写時の色合いや透明度を変化させることができます。ColorTransformのフィールドには、alphaOffsetという項目があり、これを255に設定すれば転写時の非透明度は常に最大になります。最初は、これでいいんじゃねと思ったんですけど、なぜかアンチエイリアスの効いた線になってしまいました( ̄□  ̄ ||

// 実際のレイヤーキャンバスのImageコントロールを取得
var image:Image = getImage();

// ImageコントロールからBitmapDataを取得
var bitmap:BitmapData = image.source.bitmapData;

// Bitmapへ描画用レイヤーの内容を転写
bitmap.draw(getDrawLayer(), 
			null, 
			new ColorTransform(1, 1, 1, 1, 0, 0, 0, 255),	// 透明Offset255
			null, 
			null, 
			false);

で、試行錯誤して辿り着いた結果が次のヤツです。まず一時的なBitmapDataへ描画用レイヤーの内容を転写し、その一時BitmapDataを実際のレイヤーキャンパスへ再転写しています。これでなぜかうまくいきました( ̄∇  ̄ )

// 一時ビットマップを作成
var tmpBitmapData:BitmapData = new BitmapData(width, 
											  height, 
											  true, 
											  0x00FFFFFF);
			
// 描画レイヤーの内容を一時ビットマップへ転写 
tmpBitmapData.draw(getDrawLayer(),
				   null, 
				   null, 
				   null, 
				   null, 
				   false);

// 実際のレイヤーキャンバスのImageコントロールを取得
var image:Image = getImage();

// ImageコントロールからBitmapDataを取得
var bitmap:BitmapData = image.source.bitmapData;

// Bitmapへ一時BitmapDataの内容を転写
bitmap.draw(tmpBitmapData, 
			null, 
			new ColorTransform(1, 1, 1, 1, 0, 0, 0, 255),	// 透明Offset255
			null, 
			null, 
			false);

仕組みとかどうなっているのかは、よく分かりません。描画用レイヤーは実際に画面に描画されるので、その際になにか特別な処理でもされているんでしょうか?

まあ、とにかくアンチエイリアスを切りたいときは、一時BitmapDataに転写しとこうってことですね。しかし、Flashでお絵かきツールを作ってる人って日本で100人いるのかな? とてつもなくニッチなネタになってしまった気がします。

Tags:   , ,
Categories:   Flash
Actions:   Permalink | Comments (1) | Comment RSSRSS comment feed

LSLのSyntaxHighlighter Plugin

Thursday, 24 September 2009 09:15 by sabro

SyntaxHighlighterという、ソースコード色付けツールがありますが、実は、さぶろーはそれのLSLプラグインを作ってます。今回そのプラグインをまとめたページを作った方がいまして、LSLプラグインも紹介していただけるとのことなので、ここに使い方を書いてみます。

List of available brushes for Gorbatchev’s SyntaxHighligher
http://www.undermyhat.org/blog/2009/09/list-of-brushes-syntaxhighligher/

LSL用のプラグインは、ここにあります。これは、Google Page Creator上に置いてあるのですが、ざっと規約を読んだところ、おそらく直接参照しちゃっても大丈夫だと思います(勘違いしてたら教えてください)。
for ver.1.5 http://public.webkai.net/shBrushLsl.js
for ver.2.0 http://public.webkai.net/shBrushLsl2.0.js

 

ver 2.0の設定

1、Webページのヘッダーに、以下を追記します。alexgorbatchev.comというのは公式のホスティング先なので、直接参照しちゃって大丈夫です。
<head>
・・・
・・・
<!-- ▼追加部分▼ -->
<link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" />  <link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" />  <script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js"></script>  <script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shLegacy.js"></script>  <script type="text/javascript" src="http://public.webkai.net/shBrushLsl2.0.js"></script> <script type="text/javascript">  window.onload = function () { SyntaxHighlighter.config.stripBrs=true; //←改行無視が不要なら消す SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf'; SyntaxHighlighter.all(); dp.SyntaxHighlighter.HighlightAll('code'); } </script> 
<!-- ▲追加部分▲ -->
</head>

2、LSLをブログに書き、preタグで囲みます。
<pre name="code" class="brush: lsl">
/*
   マルチラインコメント
*/

// 1行コメント

string single = "文字列";
string multi  = "マルチライン
                 文字列";

default
{
    state_entry()
    {
        if (TRUE) {
            llSay(0, "テスト");
        }
    }
}
</pre>

 

 

ver 1.5の設定

1、Webページのヘッダーに、以下を追記します。
<head>
・・・
・・・
<!-- ▼追加部分▼ -->
<link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/1.5.1/styles/SyntaxHighlighter.css" /> <script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/1.5.1/scripts/shCore.js"></script>  <script type="text/javascript" src="http://public.webkai.net/shBrushLsl.js"></script> <script type="text/javascript">  window.onload = function () { dp.SyntaxHighlighter.BloggerMode(); //←不要なら消す dp.SyntaxHighlighter.ClipboardSwf = 'http://alexgorbatchev.com/pub/sh/1.5.1/scripts/clipboard.swf'; dp.SyntaxHighlighter.HighlightAll('code'); } </script> 
<!-- ▲追加部分▲ -->
</head>

2、LSLをブログに書き、preタグで囲みます。
<pre name="code" class="lsl">
default
{
    state_entry()
    {
        llSay(0, "ご存じ、ないのですか!? これがSyntaxHighlighterです!!");
    }
}
</pre>

 

以上です( ̄∇  ̄ ) LSLをブログに書く方は、ぜひ使ってみてください。

CGIのURLエンコードと、JavascriptのURLエンコードは微妙に違う

Wednesday, 22 July 2009 07:48 by sabro

クリエモンでURLエンコード周りのバグを出してしまいました( ̄□  ̄ ||

原因はCGIとJavascriptでURLエンコードが微妙に違うことでした。WikipediaのURLエンコードのページをみると、Javascriptでは、スペースは「%20」にエンコードされるが、CGI側では普通は「+」に変換されると書いてあります。なんでそんなややこしいことになってんだろ。これって知らないの僕だけで他のWeb開発者の間では常識なのかな(_ _ ||

とりあえず、おかしくなっていた部分では、HttpUtilityクラスのUrlEncodeメソッドが使われていました。以下はPowerShellでちょっと確認してみたところ。HttpUtilityクラスは、そのままでは参照できないんでリフレクションで「System.Web.dll」を読み込んでいます。


PS C:> [System.Reflection.Assembly]::LoadWithPartialName("System.Web")

GAC    Version        Location
---    -------        --------
True   v2.0.50727     C:\Windows\assembly\GAC_32\System.Web\2.0.0.0__b03f5f7f11d50a3a\System.Web.dll

PS C:> [System.Web.HttpUtility]::UrlEncode("<hoge fuga>")
%3choge+fuga%3e


PowerShell覚えると、インタプリタで動作確認ができちゃって楽ちんだな~( ̄∇ ̄) で、結果を見ると確かに「+」にエンコードされていますね。

調べてみると、UriクラスのEscapeDataStringメソッドを使えばJavascript形式のエンコードが出来るらしいとのこと。どれどれ


PS C:> [Uri]::EscapeDataString("<hoge fuga>")
%3Choge%20fuga%3E


おお、たしかに「%20」にエンコードされました(^^) 結局、UrlEncodeメソッドを使用している箇所を、のきなみEscapeDataStringメソッドに置き換えて、問題は解決したのでした。

ちなみに、UriクラスにはEscapeUriStringというメソッドもあります。こちらがどんな動作をするのか気になったので、サクッと確認してみました。


PS C:> [Uri]::EscapeDataString("http://www.hogefuga.com/<hoge fuga>")
http%3A%2F%2Fwww.hogefuga.com%2F%3Choge%20fuga%3E

PS C:> [Uri]::EscapeUriString("http://www.hogefuga.com/<hoge fuga>")
http://www.hogefuga.com/%3Choge%20fuga%3E


EscapeDataStringメソッドは、URLのコロンやスラッシュもエンコードしてしまいますが、EscapeUriStringメソッドは、URLを構成するための記号はエンコードしていません。すでに、URLになっている文字列に対してエンコードしたい時はこちらを使えばいいわけですね( ̄∇  ̄ )

Tags:   , , ,
Categories:   .NET
Actions:   Permalink | Comments (0) | Comment RSSRSS comment feed

Android携帯、HT-03Aを購入しました

Monday, 20 July 2009 20:34 by sabro

モバイル端末は、イーモバイルなどを持ってるさぶろーですが、携帯は長らくmovaを使ってきました。きょーびmovaはないわ~ということで、昨日、意を決してAndroid携帯、HT-03Aを買ってきました。iPhoneなんかにも興味はあったんですが、メイン言語がC#だと、やっぱりApple製品を買うのは躊躇してしまいます。

購入価格は、2年縛りで、32200円になり、さらにキャンペーンで10000円引かれて、22200円でした。

料金プランは、こんな感じです。
・タイプSSバリュー & ひとりでも割50 980円
・moperaU ライト 315円
・Bizホーダイダブル 上限 5985円
------------------------------------------------
合計 7280円

ザッと触ってみた感想としては、思ったよりもっさりしてませんでした。まだ、アプリが少ないからかもしれませんが、イーモバイルより動作はサクサクしていると感じます。

HT-03Aは、基本的にiモードには対応しておらず、どうしても使いたい場合は「iモード.net」を契約することになるのですが、こちらは契約せず、iモードは完全に捨てることにしました。ただ、PCのメールアドレスだと携帯でフィルタリングされて相手に届かないことがあるらしいので、場合によっては再契約するかも。

Androidは、アプリの開発も出来ると言うことで、ちょっとやってみたいのですが、今のところセカンドライフでやることがあるので、こちらは出来なさそうです。うちの今のメインターゲットはあくまでも、セカンドライフでやってるクリエモンです。現在PVを作成中で、完成したらyoutubeやニコ動にアップ予定なので、ぜひご覧になってみてください(^^)

Tags:   ,
Categories:   Android
Actions:   Permalink | Comments (0) | Comment RSSRSS comment feed

PowerShellでWeb上のZipファイルをダウンロードして解凍する

Monday, 22 June 2009 09:45 by sabro

ちょっと、とあるWebサーバ上にあるZipファイルを定期的にダウンロードして解凍する必要が出てきたんで、適当な言語でスクリプト作ることにしました。ただ、要件としてWindows上で動作する必要があって、せっかくなんで、前から気になってたPowerShellでやってみることにしました。

# Zipファイル操作用のライブラリをロード
[System.Reflection.Assembly]::LoadFile('C:\temp\ICSharpCode.SharpZipLib.dll')

# WebClientクラスのインスタンスを作成
$wc = New-Object System.Net.WebClient

# Zipファイルをダウンロード
$wc.DownloadFile("http://www.hoge.com/fuga.zip","C:\temp\temp.zip") 

# Zipファイルを解凍
$zip = New-Object ICSharpCode.SharpZipLib.Zip.FastZip
$zip.ExtractZip("C:\temp\temp.zip", "C:\temp\" + [DateTime]::Now.ToString("yyyyMMdd"), "")



Zipファイルを解凍する方法は、COMを通してエクスプローラの機能を使うとか、コマンドラインで解凍ソフトを呼び出すとか色々あるみたいだけど、今回は、ICSharpCode.SharpZipLib.dllを使ってみました。PowerShell上で、外部アセンブリのクラスを使用したい場合は、リフレクションを使ってアセンブリをロードしておく必要があるみたいなので最初にロードしてます。[System.Reflection.Assembly]::LoadFileみたいな呼び方してるけど、静的なメンバを呼び出す時はこうしないといけないらしいです。

次にWebClientのインスタンス化、New-Objectコマンドでインスタンス作成です。そのインスタンスのDownloadFileメソッドを使用して、ファイルを同期的に取得しています。

最後に、ICSharpCode.SharpZipLib.dllのFastZipクラスを使用して解凍。解凍したファイルは、日付ごとのフォルダに格納してます。

とまあ、こんな感じで結構簡単にできました( ̄∇ ̄)でも、いざ実行してみるとエラーが・・・( ̄□  ̄ ||  どうやら、PowerShellではデフォルトの実行ポリシーが「Restricted」になっていて全てのスクリプトの実行が禁止されているとのこと。実行ポリシーは他に「AllSigned、RemoteSigned、Unrestricted」があるそうですが、今回はインターネット上のスクリプトのみ署名を求める「RemoteSigned」にポリシー変更してみました。

Set-ExecutionPolicy RemoteSigned


これをPowerShellのプロンプト上で実行してやれば動くようになりました(^^)

Tags:  
Categories:   .NET
Actions:   Permalink | Comments (0) | Comment RSSRSS comment feed

メタバース連動サービス、クリエモンを正式リリースしました

Saturday, 9 May 2009 21:28 by sabro

以前の記事で紹介したクリエモンを正式リリースしました。
クリエモン

クリエモンは、セカンドライフアバターの表情をWebに投稿、共有できる新感覚サービスです。アップロードされたパーツを組み合わせて表情を作成し、セカンドライフのアバターに適用できます。
クリエモンについて

もうすでにいろいろな表情がアップロードされていますよ。
表情パーツ

正式版での一番の変更点は、クリエモン対応アバター開発キットの提供です。
クリエモンアバター開発キット

これは、クリエモンの表情カスタマイズ機能をもったオリジナルアバターを開発するためのキットです。これでセカンドライフのアバターCGMが盛り上がる可能性がありますね。
きぐるみちゃん

クリエモンは、ちょっとWebサービスを組み合わせてみた程度のサービスではなく、全く新しいコンセプトのサービスとして、1年掛けてじっくり開発してきました。セカンドライフは、今明らかに下り坂であり、撤退企業もあいついでいる中で、あきらめかけたこともあったのですが、なんとか公開まで持って行けました。自分はそろそろWebだけで完結するサービスは衰退期に入っており、ちょっとの期間流行するようなものは出せても、個人ではメインストリームとなるようなものは作れなくなったのではと考えています。そんな環境の中で、メタバース連動サービスは、新規性があり、個人でもアイデア次第で大企業を凌駕できる可能性を秘めているのではないでしょうか。

Tags:  
Categories:   Second Life
Actions:   Permalink | Comments (0) | Comment RSSRSS comment feed

Linux Monoで、BlogEngine.NETを動かす

Sunday, 26 April 2009 11:44 by sabro

なんとかこのブログも、PebbleからBlogEngine.NETへ移行できました。

もちろん、Linux Mono上で動いているのですが、その設定を書いてみます。バージョンは、Monoが1.9.1、BlogEngine.NETが1.5.0です。

ホントはもっとバージョンが新しいMonoを使おうかと思ってたのですが、実は、クリエモンが、Mono1.9.1以下のバージョンでしか動かなかったんです(_ _ || Mono2.4は、MonoRailの、URL Routingがうまく動きませんでした。どうやら、System.Web.HttpApplicationクラスで、web.configから設定を取得するコードが2.4から修正されて、Routingの設定が読めなかったみたいです。Mono2.2と2.0では、正規表現のオプションRegexOptions.ReferenceIgnoreCaseがサポートされてないようで、正規表現でURL Routingを割り当てる部分でエラーがでました。ブログをホストするマシンをクリエモンと別にするという手もあったんですが、ブログのためにマシンを追加するのも億劫だったので( ̄∇ ̄)

さあ、設定の手順ですが、実は結構簡単です。ここにたどり着くまでは、すごく大変だったんですけどね( ̄□  ̄||

1、ドキュメントルートに、BlogEngine.NETを設置
BlogEngine.NETを本家からダウンロード・解凍すると、「BlogEngine.Web」というディレクトリが出来るのでドキュメントルートにコピーします。
2、Web.Configの修正
まず、Web.Configを小文字のweb.configに修正します。これをやっとかないと動かないページがありました。次に、web.configを開いて、System.Managementのアセンブリを読み込んでいる部分をコメントアウトします。これは、DBを使う場合で使用されるようなので、デフォルトのまま、データをXMLに保存する場合はコメントアウトしても問題ありません。たぶん・・・。
3、Tag Cloud Widgetの修正
Tag Cloudのコントロールが、そのままでは動かないので、「BlogEngine.Web/widgets/Tag cloud/edit.ascx」のReferenceディレクティブを修正します。
<%@ Reference VirtualPath="~/widgets/Tag cloud/widget.ascx" %>
↓
<%@ Reference Control="~/widgets/Tag cloud/widget.ascx" %>
たぶん、WindowsならVirtualPathで動くんでしょうねぇ。

これで一応動きますが、実はブログのインポートにハマりどころがありました( ̄□  ̄|| BlogEngine.NETのインポートは、インポートツールを使用して行うんですが、これがどうやらアプリ内部で設定しているURLが全て小文字になっていて、大文字小文字を区別するLinuxだと動かないようです。ちょっと調べてみるとCodePlexBlog Importerっていうプロジェクトがあって、これがBlogEngine.NETのインポートツールかなと思ったらビンゴだったので、ソースを見てみたのですが、あまりの酷さに愕然・・・。

  • URLが全て小文字で記述されていて、Linuxのサービスにアクセスできない
  • URLの最後に"/"をつける、CleanPath関数があるんだけど、それをインポートするRSSにも適用してる。だから、「http://○○/rss.xml/」みたいなURLにアクセスしにいく・・・orz
  • コンテンツのフィルタ部分にバグがある
ちょっと諦めて、RSSをRubyスクリプトでパースして、Firefoxを自動実行するiMacros用のマクロを生成、iMacrosを走らせて30分放置という荒技で対処しました( ̄∇ ̄)

まあ、こんなところです。コメントが移行できなかったのが少し残念ですがとりあえず、おkということで、やっとクリエモンの続きに入れるかな。

Tags:   , , ,
Categories:   .NET
Actions:   Permalink | Comments (0) | Comment RSSRSS comment feed

RSSの登録更新をお願いします

Sunday, 26 April 2009 05:19 by sabro

なんとか、BlogEngine.NETへの移行が終わりそうです。

トップページのURLは変わりませんが、RSSのURLが変わります。

今日の23:00くらいに、エイやッと入れ替える予定なので、RSSの更新をお願いしまーす。

Tags:  
Categories:   その他
Actions:   Permalink | Comments (0) | Comment RSSRSS comment feed

BlogEngine.NET on Monoハマり中( ̄□  ̄||

Tuesday, 14 April 2009 14:56 by sabro

BlogEngine.NETをMonoで動かすのは、やはりムズイです。環境は故合って、Mono 1.2.4 & BlogEngine.NET 1.4.5 でやってますが、うまく動いてくれません( ̄□  ̄||

BlogEngine.NET Modifications for Mono/Linuxを参考に、以下やったこと、binのリネーム以外は全てWeb.Configの修正です。

System.Managementの読み込みを削除
Mono 1.2.4では使えないNamespaceのようで、かつDBを使用せずXMLでやれば不要そうだったので削除。
Description属性を4つ削除
Web.Configのprovider定義タグではdescription属性が使えないらしいので削除。
DBBlogProviderタグ削除
SqlMembershipProvider削除
DbMembershipProvider削除
SqlRoleProvider削除
DbRoleProvider削除
XMLでやれば不要そうで、かつ動作不良の原因ぽかったので削除。
Compression HttpModuleを削除
ページに「?」が表示されるらしいので削除。
Binディレクトリをbinにリネーム
Linuxのファイル名が大文字、小文字を区別するので変更。
httpRuntimeを削除
クリエモンと同居させてるからか、Machine.Configで、httpRuntimeを読む時エラーになったのでWeb.Configのを削除したらなぜか直ったw。
StrageLocationを仮想パスでなく絶対パスで書く
Web.Configに「StorageLocation="~/App_Data/"」とあって、これを絶対パスで書かないとエラーになる部分があったので変更。しかし、絶対パスにしてもエラーになった・・・orz
最後のは、Mono1.2.4のHostingEnvironment.MapPathで、仮想パスをハジくチェックをしているのが原因だが、Mono 2.0のソースを見たらチェックしなくなっていたので、2.0以上でやらないと動かせないらしい。

 

public static string MapPath (string virtualPath)
{
if (virtualPath == null || virtualPath == "")
throw new ArgumentNullException ("virtualPath");

if (UrlUtils.IsRelativeUrl (virtualPath)) {
string msg = String.Format ("The relative virtual path '{0}', is not allowed here.", virtualPath);
throw new ArgumentException (msg);
}

HttpContext context = HttpContext.Current;
if (context == null)
return null;

return context.Request.MapPath (virtualPath);
}

というわけで、Mono 2.4も出てるらしいので、もうちょっとバージョンが上がったMonoVMで動かしてみようと思います。でも前、クリエモンを乗せたらうまく動かなかったんだよな~( ̄~ ̄)

あと、タイミングのいいことに、昨日、BlogEngine.NETが9ヶ月ぶりにバージョンアップして1.5になったそうなので、そっちも試してみようと思います。昨日、インストールがうまくいってたら、即、アップデートが必要だったと思えば失敗してよかったのかな(^^)

Tags:  
Categories:   .NET
Actions:   Permalink | Comments (0) | Comment RSSRSS comment feed

ブログエンジン移行計画中

Monday, 6 April 2009 16:57 by sabro

近々、ブログエンジンの移行を計画しています。

このブログは自宅サーバで運営してますが、CPUがPentium3というのもそろそろ限界かと思い始めて、先日NTT-X Storeで、HPのML115を買いました。年度末セールで、2台で21500円で買えて、ウホウホ言って喜んでたら、2日後に19500円になってました・・・orz

まあ、そんなわけでこの機会に、アプリも含めたサーバの再構築をしてみようと思ったわけです。最近は、Linux Monoでクリエモンとか動かしてるし、Monoで動くいいブログエンジンないかなーと探してたら、めっさいいのがありました。

BlogEngine.NET

BlogEngine.NETは、.netのブログエンジンを代表するようなプロダクトですが、Mono対応が売りのひとつになっています。いや素晴らしい(^^)

とりあえず、これでいってみようと思います。

Tags:  
Categories:   .NET
Actions:   Permalink | Comments (0) | Comment RSSRSS comment feed