Knowledge base func

Flex

Jsでクライアントマシンのフォント一覧情報を得るTIP

by on 2月.10, 2012, under as3, Flex

Share on TwitterSave on Delicious

2012年2月現在、Windowsかなにかのセキュリティパッチのおかげで使えなくなった
dlgHelper [DHTML Editing Control](.net Component+javascrip)
clsid:3050f819-98b5-11cf-bb82-00aa00bdce0b の代わりに、同じような機能をFlex-swfで提供するものを作りました。Javascriptでユーザーのマシンのフォント情報を取得することができます。

当方は帳票-印刷系でフォントを選択させるときなどに使います。
フォント情報を取得できればHTMLでcssなどをユーザーのマシンのフォントにあわせて変更などもできますのでご活用ください。

github.com/kuippa/FlexFontsdlgHelper
上記 Githubから取得できます。ソースコードも公開しています。

Flex SDK4.6でコンパイルしたフラッシュを、Javascriptで呼び出してつかっています。
サンプルは動作させるマシンのセキュリティ次第ではフラッシュのセキュリティでfile:// 呼び出しでは動かないかもしれません。その場合は、localhostやドメイン上に配置して動作をみてください。
サンプルHtmlのparam FlashVarsでviewmode=1にしてやると、Flash上のFontまわりの動作確認をすることもできます。

すべてのデバイスフォントを取得するようにしています。
JsとAs両方で監視しあうタイマーで動くので呼び込みに少し間をもたせています。
すこし読み込みがもっさりしていますが、ユーザートリガーならこんな作りにする必要もありませんし、ユーザー環境がもう少し想定できるのであれば、デバイスに読み込みにいっているのでタイマースパンをながめにとっていますが、これを短くすることもできます。

dlgHelperが使えなくて困ったのでちょっと作っただけなので、再び手を入れることはないかもしれません。
ライセンスはNYSL(煮るなり焼くなり好きにしろライセンス)です。
等間隔割付などのフォントまわりのクラスもつけておきました。
この辺の日本語とフォント挙動はActionScriptものすごく怪しいです。
4.6になって、日本語ホント/マルチデバイスフォントの挙動が4.0の時と比べてもおかしくなったようにおもいます。割り当てをSift-jisにすれば動くかなとかいろいろ試しましたがだめでした。困ったね。
諦めてJavascript+Canvasあたりで日本語フォント系なんとかできないか考えてみます。

2010年ごろに苦悶した
Flexディバイスフォントの記事
iteahelper.com/blog/2010/08/08/flex%e3%83%87%e3%82%a3%e3%83%90%e3%82%a4%e3%82%b9%e3%83%95%e3%82%a9%e3%83%b3%e3%83%88/

Leave a Comment more...

ActionScript DataGridでのCheckboxのあつかいかた

by on 2月.14, 2011, under as3, Flex

Share on TwitterSave on Delicious

リストから印刷する項目を選ぶアプリケーションをつくろうとして、DataGridにチェックボックスをつくって、項目を全選択したり解除したりというような機能をつけようとしただけなのにものすごい苦労した。
あまりにネット上にリソースがないので、人柱になっておきます。
こんな苦労はみんながしなくていい苦労 htmlですらできるものの実装にどんだけ苦労さすじゃと憤りました。

はまりどころメモ:

DataGridのdataProviderはArrayCollectionをつかわなきゃいけないのだけど、XMLをArrayCollectionにキャストしたぐらいでは動いてくれない。よぼぼん。for eachしてやるか、自前で連想配列に展開する必要がある。可逆性がないので残念。

length()とlengthの違いは毎度ぶっとばしたくなる。
例えばIListはlengthで、XMLはlength()じゃないと値が帰ってこないとか。

DataGridのredorwが明示的でない。コードからデータを書き換えたばあい dtgAttendant.dataProvider.refresh();こんな感じでリフレッシュしてやる必要がある。autoupdateみたいなメソッドがいたので、もしかしたらそれをセットするだけかもしれない。

値渡しなのか参照渡しなのかはっきりしてほしいが、getItemAtな名前なのに参照渡しのようだ。取得したオブジェクトを書きかえることでsetItemAtをつかわないでも書き換えられる。ぽかーん。

checkboxまわりの挙動がふざけてるのかと思うぐらいやってられなかった。どれだけ嵌ったことか。半日つぶれた。ここにはいくつもハマリポイントがある。checkboxを配置しチェックをつけてもdataProviderの実際のデータが書き換わらないことだ。いったいどうゆうことよ???
どうも、いろいろおまじないをしなければいけないようだ。とても無駄。

項目の書き換えをできるようDataGridのeditable=”true”にする必要がある。そのうえでmx:DataGridColumnで項目ごとのeditableを制御しなくてはならない。
グリッドのカラムにチェックボックスを配置するには itemRenderer=”mx.controls.CheckBox”こんな感じでコンポーネント呼び出しを行う。当然カスタムコンポーネントも使える。かなりの人がカスタムコンポーネントに逃げているようだ。しかし、そのためにコード側からの制御がmxmlにひきずられるのは納得いかない。そして、あまり実際的ではないように思う。
editorDataField=”selected”で、mx.controls.CheckBoxのselected値を直接参照してやればdataProviderの内容にも反映されることがわかった。本当におまじないで、それぞれのプロパティの設定組み合わせの妙で挙動がまるで違うので要注意だ。

サンプルコードをまるまる置いておきます。flex4の環境でflex3をかいているのと、コードの使い回しなので汚いですがゆるしてね。XMLは本来サーバーから取得するのを前提なのですが、ここではべた書き宣言にしておきました。
iteahelper.com/opendl/sand_datagrid.zip

Main.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	creationComplete="init()"
	>
	<mx:Script  source="main.as" />
	<!-- データグリッド -->
	<mx:Panel x="0" y="0" width="100%" height="100%" layout="absolute" id="dtgrid" visible="true">
		<mx:VBox>
			<mx:DataGrid id="dtgAttendant" width="100%" height="80%" editable="true">
				<mx:columns>
					<mx:DataGridColumn dataField="flg" editorDataField="selected"
						headerText="印刷" editable="true" 
						rendererIsEditor="true" itemRenderer="mx.controls.CheckBox" />
					<mx:DataGridColumn dataField="attendant_no" headerText="番号" />
					<mx:DataGridColumn dataField="test" headerText="test" />
					<mx:DataGridColumn dataField="attendant_name" headerText="名前" editable="true" />
					<mx:DataGridColumn dataField="honorific" headerText="敬称" editable="false" />
				</mx:columns>
			</mx:DataGrid>
			<mx:Button x="600" y="5" label="選択反転" click="chkReverse()" />
		</mx:VBox>
	</mx:Panel>
 
</mx:Application>

main.as

import mx.controls.*; 
import mx.core.*;
import mx.collections.ArrayCollection;
import mx.collections.IList;
import mx.formatters.NumberBase;
import mx.printing.*;
import mx.utils.*;
import mx.utils.ObjectUtil;
import mx.graphics.Stroke;
import mx.events.*;
import mx.events.ModuleEvent;
import mx.managers.CursorManager;
import mx.events.CloseEvent;
import mx.events.ResizeEvent;
 
private var obj:Object;
[Bindable]
public var data_attendant:ArrayCollection;	// データグリッドのデータコントロール
 
 
private function init():void
{
	obj = new Dtgctrl(data_attendant);
}
 
// 印刷指示反転
private function chkReverse():void 
{
	var list:IList = IList(dtgAttendant.dataProvider);
	for (var i :int = 0; i < list.length; i++ ) {
		var selectedItem:Object = Object(list.getItemAt(i));
		selectedItem.test = selectedItem.flg;
		selectedItem.flg = !selectedItem.flg;
	}
	dtgAttendant.dataProvider.refresh();
}

Dtgctrl.as

package  
{
	public class Dtgctrl
	{
		import mx.containers.Canvas;
		import mx.messaging.management.ObjectInstance;
		import mx.utils.ObjectUtil;
		import mx.graphics.Stroke;
		import mx.controls.*; 
		import mx.core.*;
		import mx.managers.CursorManager;
		import mx.collections.ArrayCollection;
		import mx.collections.IList;
		import mx.events.ListEvent;	
		import mx.events.SliderEvent;
		import mx.events.ModuleEvent;
 
		private var xml:XML = 
<tabletypes>
  <attendant>
    <attendant_no>1</attendant_no>
    <attendant_name>山田太郎</attendant_name>
    <honorific>くん</honorific>
  </attendant>
  <attendant>
    <attendant_no>2</attendant_no>
    <attendant_name>山田次郎</attendant_name>
    <honorific></honorific>
  </attendant>
  <attendant>
    <attendant_no>3</attendant_no>
    <attendant_name>山田花子</attendant_name>
    <honorific>さん</honorific>
  </attendant>
</tabletypes>;
		public var mAttendant:Array = new Array();		// 参列者情報
 
		public function Dtgctrl(data_attendant:ArrayCollection)
		{
			mAttendant = new Array();	// 参列者情報
			// 参列者情報を取得する
			for(var i:int=0;i<xml.attendant.length();i++){
				mAttendant[i] = xml.attendant[i];
			}
 
			var entries:Array = new Array();
			for (var k:String in mAttendant){
				entries.push(
					{
						flg : true,
						test : true,
						attendant_no : mAttendant[k].attendant_no,
						attendant_name : mAttendant[k].attendant_name,
						honorific : mAttendant[k].honorific
					}
				);
 
			}
			data_attendant = new ArrayCollection(entries);
			Application.application.dtgAttendant.dataProvider = data_attendant;
		}
 
	}
 
 
 
}
Leave a Comment more...

NET Vocaloid Flex APIを使用したアプリをつくりました

by on 11月.13, 2010, under Flex, WEBサービス, テクノロジー(兆し)

Share on TwitterSave on Delicious

作ったところで満足してそのままにわすれていたので、後追い報告。
マッシュアップアワード6の締め切り間際にAPIが公開になり、合間合間をみてやってきましたが、とりあえずここまでつくったのでご報告。


iteahelper.com/sandbox/netvocaloid/

ひらがなを入れるとそれをミクさんぽい何かが発声してくれます。
見た目より体験なのでさわってみてください。ミクあげを押すと音声データに変換します。

なんだただの読み上げソフトじゃないか!
と、思われてもいたしかなたいですが、技術的にはなかなか面白い取り組みがなされています。このアプリケーションは機械翻訳的な部分を中心につくっているのでユーザーの体験としてはほとんど面白みがないですよね。申し訳ない。

まず最初にNET Vocaloid Flexの概要からご説明します。
初音ミクなどで有名なYAMAHAのボーカロイドシリーズがあるのですが、これはその音声データを吐き出すためのエンジンをネットAPIという形式でインターネット上で提供される実験的で先鋭的なサービスです。

このAPIが何をしてくれるかというと、音声データを作成するための設計図(VSXML)をNET Vocaloid APIに渡すとMP3の音楽データにしてくれます。まだ本格公開前のサービスなので10秒制限や変換回数の制限があるなど、細かい制限があります。

問題はこのVSXMLなのですが、普通のひとには理解できない言葉で書かなければなりません。
変換のためのハマりどころは下記に軽くまとめておきました。
iteahelper.com/blog/2010/10/15/netvocaloid-flex-api%e3%81%8c%e7%99%bb%e5%a0%b4/
iteahelper.com/blog/2010/11/01/netvocaloid-flex%e3%82%92%e3%81%97%e3%82%89%e3%81%b9%e3%81%9f%e3%82%8a/

世間では楽譜を自由にかけるひとは少ないですが、VSXMLを手書きでかけるひとはきっともっとすくないでしょう。
で、今回は何をつくったかというと、日本人がつかいやすい「ひらがな」をマシンが理解しやすい「VSXML」に変換するエンジンをつくりました。いずれ優れたインターフェイスを持ったエディターが出てくることだとは思いますが、まずは手始めにマシンと人間をつなぐ翻訳サービスのようなものです。

 

ネットボーカロイドの意義

ボーカロイドの特徴は音調(調律、長さ、音圧)をいじることができるところです。
さらにこれがオンライン上でリアルタイムエンコーディングが可能になった場合の可能性は現段階でははっきりとイメージしきれませんが、かつて初音ミクがでてきたときと同じようなインパクトがあるのではないかと期待に胸がドキドキ。

ただ、いかんせんこれを利用するにはMIDIデータをバイナリエディタで手起こしをするようなわずらわしさがあります。
わずらわしさと言いましたが、障壁といっていい。
MIDIのような電子音楽だけでなく、イントネーションプロミネンスの分解や、ネットワークであったり、通信などを含むプログラミングなど、利用するために必要とされる知識が広すぎてしまって現段階では一般ユーザーや音楽関係のクリエイターが使うにはその壁が高すぎます。

そんなわけでプログラムサイドと音楽サイドから、その壁を乗り越えるためのはしごを作ろうかなと今回のこれをつくりました。内部的には音調や音階を調律可能な状態でデータを作成することができます。
次に必要なのはインターフェイスです。

ですが、その前に「なにをやりたいか」が問われています。

表現する技術があっても表現したいものがないと技術には意味がないのです。もちろんその逆でも足りません。
自分ではあまりいいアイディアが思い浮かびませんでした。
もし、こーしたい、あーしたい、などがあったらはしごを用意しますのでいいたいことを言うなら今のうちっ!
俺の背中を超えてみないかっ!

Leave a Comment more...

NetVocaloid-flexをしらべたり

by on 11月.01, 2010, under as3, Flex

Share on TwitterSave on Delicious

音のピッチ

<ctrl type=”PIT”>
<pos>0</pos>
<value>6900</value>
</ctrl>

VSMXLではcentでピッチを指定。PIT:valueにつっこむ。
440 [Hz](対数)=6,900[cent] = A4(ラ)
ヘルツは対数計算だがcentはそこまでの計算をすでにやってくれたもの。
1200centで1オクターブ、100centで半音(二度)。100centだが1ドルではない・・・。(笑え)
C5: 7200
B4: 7100
B-4: 7000
A4: 6900
A-4: 6800

音のポジション

<phoneme>
<pos>0</pos>
<duration>5000</duration>
<content><![CDATA[a]]></content>
</phoneme>
<phoneme>
<pos>1000</pos>
<duration>5000</duration>
<content><![CDATA[i]]></content>
</phoneme>

いろいろ試したが同音発声はできないようだ。
この場合aの音が5秒鳴ってからiの音が1秒発声する。

posは前の音の発声時からの間隔であるので、前の音のdurationを基底にしないと音が想定した長さ出ない。
すでに鳴っている音が優先される。仕様上はルートノードにpartを分けることができるようだが、現時点でpart要素を2つ以上いれるとConvertFailureでこける。number、offset、nameをデュプリケイトしないようにいじってみたがだめ。
Synthesis XML0.2.0.1仕様書にはトラックを分ければできる旨が書いてあるがおそらくは普通のDTMソフトのトラックのこと? 未実装かもしれない。今回は同時発声は見送り。

→違った! durationの設定が合計値で10秒しかないため溢れていただけだった。詳しくは後述。

mp3データ

VSMXLを投げるとサーバー側でmp3に吐き出してくれてそのURL(例 api-nv.y2lab.com/delivery.php?ticketid=4YM@vkfuhJTkc9QvUQo1f7eWUAg)にアクセスするとmp3をくれる。
ticketidがおそらくはPKだとはおもうのだけど、サーバー側にどの程度の期間保持されるのか不明。
現在のレスポンスはものすごく早い。細かいファイルが今後多くできたら今後どのようになるだろうか?まあ、俺が気にすることではないがファイルI/Oまわりサーバー側大変そう。
ユーザーをこのURLに飛ばしていいのかな?
API提供期間が短いのと規約をそこまで読み込んでいないのであとフォローを考えると、キャッシュせずにこのURLにナビゲートする方向で考える。

vsmxl要素

sentence、syllableは定義は予約はされているが未実装。つっこむとmp3データが帰ってこない。
sentenceは人間がXMLを見たときに読めるようにデータを突っ込んでおきたい気分。できればいれても落ちないようにしてほしい。

as3crypto.swc

cryptoをクリプトンだとおもって、VOCALOIDの独自ライブラリだと早とちりしてたらなんか様子が変。
Hex?Base64?なんだこれはと思ったらファイル通信暗号化のオープンソースライブラリだったよ。
cryptoってcryptのほうかっ!
FlashDevelopのパスの通しかたをちょっと勘違いしててlibをプロジェクトクラスパスに追加しただけじゃだめなのね。
Flex4のlibに突っ込んでもできなくて、あれーっと思ってGoogleMapとかのswcどうしてたっけと思ってみにいったら、flex_sdk_4.1\frameworks\libsのほうにいた。ちょっとはまった。そうだったそうだった。

<![CDATA[を含むXMLをFlexで

全力ではまった。
えー・・・。xmlnsではまったからもう大丈夫だとおもったら今度はCDATAがまっておった。
多分FlashDevelopのシンタックスチェックが引っかかっているだけで、他のやつをつかえばコンパイル通るのかな?
  testxml.appendChild(<content><![CDATA[u]]></content>);
こういう書き方のやりかたがわからない。うわぁぁん。。。なにこのざま。

cookbooks.adobe.com/post_Create_CDATA_tags_between_XML_nodes_using_AS-6142.html
ん~。みんな悩んでるんだね。
こんなくだらないことで・・・。くだらなすぎて致命的。
エスケープが効かないってどういうことざます?

var testxml:XML =
<phoneme>
<pos>10000</pos>
<duration>5000</duration>
</phoneme>;
testxml.appendChild(‘<content><’+'!’+’[CDATA[u]‘+’]></content>’);

できない・・・。
actionscriptは]]>が通るの?Flexは無理みたい。

jessewarden.com/2007/06/e4x-xml-binding-cdata.html
var cataxml:XML = new XML(“<![CDATA[" + "u" + "]]”+”>”);
var testxml:XML =
<phoneme>
<pos>10000</pos>
<duration>5000</duration>
<content>{cataxml}</content>
</phoneme>;

うぉぉぉ、あふぉくせぇぇぇぇええええ!!!けど、できた・・・!!

  var vsxml:XML = new XML(txtXml.text);
  var cataxml:XML = new XML(“<![CDATA[" + "M" + "]]”+”>”);
  var testxml:XML =
   <phoneme>
     <pos>5000</pos>
     <duration>5000</duration>
     <content>{cataxml}</content>
   </phoneme>;
  var mxl_ns:Namespace = vsxml.namespace();
  vsxml.mxl_ns::part.appendChild(testxml);
  txtXml.text = vsxml;

FlexのXMLとんでもないな・・・。扱いやすいようにみえてとんでもないよ。

あれれれれ・・・
xmlをDIFかけてもまったく一緒なのにConvertFailureが帰ってくる。
何が違うんだろう。改行コードとかかな・・・。調査調査。

durationが原因だった!
仕様書には上限値:300,000と書いてあるけど、合計10000=10秒を超えるとエラーっぽい。
リリースノートの関係で一母音5秒でやってたのが仇になった。3音目をappendChildしたらちょうど10秒を超えるのでなんと運の悪いことか・・・。
さらにいうと「う」は「u」じゃなくて「M」だ・・・。

durationの合計値を意識してpartを作ったら同時発声した。うそん・・・。

はふー。

触ってみた感じサクっとできるかなと思ったのだけど、予想外のところではまってしまった。
半日ありゃ自前クラスぐらいはつくれるかと思ってたのだけど残念でした。

4 Comments more...

flex4の印刷PrintJob

by on 10月.29, 2010, under Flex

Share on TwitterSave on Delicious

flexをつかっていてみえている実装にすんなりいけたことが殆ど無いので驚かなくなってしまったが、案の定印刷が黒く塗りつぶされてしまってなんじゃこりゃ状態。

意味がわからないのでググったら、

こういう同士の悲鳴しかひっかからない。。。

Flex4 FTETextFieldテキストがPrintJobで印刷できない???
a240712.cocolog-nifty.com/blog/2010/05/flex4-ftetextfi.html

もう慣れっこだぜ。自分の悲鳴しかでてこないよりはなんぼもまし。
そんなわけで、FTETextFieldとFlex4のdocsとにらめっこしてたら
FlexPrintJobというのがいた。flex3のときはこちらを使うといろいろ不都合があってうまく動かない記憶があるが、4だからということでこちらをつかったら出てきた…。
ほんとなんだろうね。驚かなくはなったけど・・・

さっくり該当部分だけのコード。

import mx.printing.*;
と
 
    var pagesToPrint:uint = 0;
	//var pj:Object = new PrintJob();
	var pj:Object = new FlexPrintJob();
 
	//cvsUI.scaleX = 0.1;
	//cvsUI.scaleY = 0.1;
 
	if (pj.start()) {
		// 印刷用パレットシート
		try {
			//pj.addPage(cvsUI);
			//pj.addPage(cvs_teng);
			//pj.addObject(cvsUI);
			pj.addObject(cvs_teng);
			pagesToPrint++;
		}
		catch(e:Error) {
			Alert.show("プリントエラー:"+e.message);
		}
		if(pagesToPrint &gt; 0) {
			pj.send();
		}
 
	} else {
		Alert.show("印刷はキャンセルされました");
	}

ちなみにFlexPrintJobのほうはUIComponentをわたしたらダメで(PrintJobのほうはUIComponentだったと思うけど)、
FlexPrintJobのほうはFTETextFieldをのっけてるUIのキャンパスコンポーネント(自分の場合s:BorderContainer)をaddObjectしたったら出ました。

ご一助に。
ちなみに
scaleをいじろうとした形跡があるのはFlex3でスプライトとフォント要素とかを同時に印刷しようとすると、
画面のスクロール位置によってずれるという意味のわからない苦しみを味わった経験があったから。
Flex4はどうだかしらないけど、今回はあまり関係ないので、コメントアウトしました。

Leave a Comment more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!