画像の貼り付け

マップに画像を貼り付ける事ができます。画像はノード・オブジェクトの内側に表示されます。つまり、画像を貼り付けたノード・オブジェクトをマップに置く形になります。画像の種類は、JPEG, PNG, GIF, SVGです。

画像の貼り付け手順は、画像をマップに取り込む処理と、シェイプに設定する処理に分かれます。マップには任意のファイルを埋め込む機能があります。画像を貼り付ける場合、まずマップに画像ファイルを埋め込みます。埋め込まれた画像ファイルは、jp.carabiner.inkpod.pi.model.EmbeddedResourceオブジェクトとして、取り扱うことができるようになります。矩形シェイプなどのノード・シェイプには、imageResourceプロパティがあり、ここに設定された画像ファイルを表示します。imageResourceプロパティに、画像ファイルのEmbeddedResourceオブジェクトを設定することで、画像を表示できます。

サンプル

「オブジェクト」メニューに、「画像の貼り付け」が追加されます。貼り付け先のノード・オブジェクトを選択し、「画像の貼り付け」を選ぶと、画像ファイルを選択するダイアログが表示されます。画像を選ぶと、ノード・オブジェクトに貼り付けられます。

function extendUI(event) {
    inkpod.ui.actions.addAction({
        id     : "SAMPLE_PASTE_IMAGE",
        text   : "画像の貼り付け",
        action : function(frame, event) {
            var model = frame.model;
            var object = model.singleSelectedObject;
            if(!object) {
                frame.alert("オブジェクトを選択してください");
                return;
            }
            if(!(object.shape instanceof Packages.jp.carabiner.inkpod.pi.shape.PAbstractRectangleShape)) {
                frame.alert("このオブジェクトには画像は貼り付けられません");
                return;
            }
            
            // ファイル選択ダイアログを表示
            var chooser = Packages.javax.swing.JFileChooser();
            chooser.multiSelectionEnabled = false;
            chooser.addChoosableFileFilter(new Packages.javax.swing.filechooser.FileFilter() {
                accept : function(f) {
                    var name = f.getName().toLowerCase();
                    return name.endsWith(".jpg") || name.endsWith(".png") || name.endsWith(".gif");
                },
                getDescription : function() {
                    return "Image Files";
                }
            });
            var result = chooser.showOpenDialog(frame.getJFrame());
            if(result == Packages.javax.swing.JFileChooser.APPROVE_OPTION) {
                // 選択されたファイルをソースとして、埋め込みリソースを作成
                var resource = model.createResource(chooser.selectedFile);
                // 画像を読み込む
                frame.loadResource(resource, new Packages.jp.carabiner.inkpod.pi.TaskObserver() {
                    taskSucceeded : function(resource) {
                        // 読み込みに成功したらshapeに設定する
                        object.shape.imageResource = resource;
                    },
                    taskFailed : function(throwable) {
                    }
                });
            }
        }
    });
    
    inkpod.ui.menuBar.objectMenu.addMenuItem("SAMPLE_PASTE_IMAGE");
}

function init()
{
    inkpod.ui.addUIExtensionListener(extendUI);
}

function dispose()
{
}

plugin = {
    init : init,
    dispose : dispose
}

ユーザーが画像ファイルを選択した後の以下の部分が、画像の貼り付けの主な処理です。

                // 選択されたファイルをソースとして、埋め込みリソースを作成
                var resource = model.createResource(chooser.selectedFile);
                // 画像を読み込む
                frame.loadResource(resource, new Packages.jp.carabiner.inkpod.pi.TaskObserver() {
                    taskSucceeded : function(resource) {
                        // 読み込みに成功したらshapeに設定する
                        object.shape.imageResource = resource;
                    },
                    taskFailed : function(throwable) {
                    }
                });

まず、PMapModelのcreateResource() メソッドで、ユーザーが選択した画像ファイルと結びつけられた、EmbeddedResourceオブジェクトを作成します。この段階では、EmbeddedResourceオブジェクトは、ローカルファイルを指しているだけで、まだ画像ファイルは読み込まれていません。

次の段階として画像ファイルを読み込みますが、画像ファイルは一般的にサイズが大きく、読み込みには時間がかかります。アクションの処理は、Swingのイベントディスパッチスレッドで処理されているため、ここで画像の読み込みを行うと、イベントディスパッチスレッドを占有して、読み込みの間、Inkpod全体が操作できない状態になります。そのため、Inkpodには、非同期に画像の読み込みを処理する方法が用意されています。

画像の非同期読み込みはフレーム(PInkpodFrame)のloadResource() メソッドで、実現できます。loadResource() メソッドは、まだ読み込んでいないEmbeddedResourceオブジェクトを渡すと、バックグラウンドのスレッドでファイルの読み込みを開始し、すぐに制御を戻します。ファイルの読み込みが成功した場合は、第2引数で渡した、jp.carabiner.inkpod.pi.TaskObserverオブジェクトの、taskSucceeded メソッドを呼び出します。読み込み完了後に処理したいことは、このメソッドに記述します。この呼び出しはイベントディスパッチスレッドで行われます。読み込みに失敗した場合は、taskFailed メソッドが呼ばれます。このサンプルでは、taskSucceededメソッドで、選択されたマップ・オブジェクトのシェイプのimageResourceプロパティに、読み込みが完了した画像ファイルを設定し、画像を貼り付けています。

imageResoruceプロパティは、jp.carabiner.inkpod.pi.PAbstractRectangleShapeインターフェースを持つ全てのシェイプに存在します。現在のところ、すべてのノード・シェイプはこのインターフェースを持ちます。

なお、読み込みに時間がかからない事がわかっているなどの場合に、同期的に画像を読み込むことも可能です。EmbeddedResourceのloadResource() メソッドを直接呼び出すことで、読み込むことができます。

関連するクラス/インタフェース