1

tkを使用して大きな2Dプロットを視覚化するperlアプリケーションを作成したいと思います(2D画像と見なすことができます)。スクロールとサイズ変更が必要です。また、画像全体をメモリに保存する必要はありません。

大きすぎて1枚の大きな絵に保存することはできませんが、どの部分でも簡単に再描画できます。そこで、このデータをインタラクティブモードで表示するグラフィックアプリケーションを作成したいと思います。これは、xvcgがグラフに対して行うことと似ています:http://blogs.oracle.com/amitsaha/resource/blog-shots/apt-rdepends.png これはインターフェースの例です。xとyのスクロールバーとズームバーがあります)

私のデータはhttp://www.access-excel-vba.com/giantchart.pngに少し似ていますが、細い(1px)線のテキストがなく、ドットがたくさんあり、サイズは(現在)33000x23000です。大きくなります。ピクセルあたり2ビットの画像を使用しています。

では、perl / tkでスクロールおよびズーム可能な画像ビューアをプログラムするにはどうすればよいですか?要件は、画像全体をメモリに保存することではなく(190 Mbになり、今後さらに増える予定です!)、一部の関数に画像を部分的に描画するように依頼します。

言語/ツールキットの選択について。私のデータジェネレーターはperlで書かれており、OSはunix / POSIXなので、言語を切り替えたくありません。別のグラフィックツールキットに切り替えることはできますが、perl/tkはターゲットPCにプリインストールされています。

4

4 に答える 4

2

これは面白そうに聞こえるかもしれませんが、効率的な2Dタイルスクロールゲームの作成に関するいくつかの記事を参照するのが最善の方法だと思います。以前にJavaで説明したようなものを書きましたが、コアの概念は同じです。画像を小さなタイルに分割する方法がわかれば、表示されている部分だけをストリーミングしてスケーリングするだけです。

または、画像全体をディスクにレンダリングしてから、 http: //www.labnol.org/internet/design/embed-large-pictures-panoramas-web-pages-google-maps-image-viewer/などを使用することもできます。 2606/。グーグルマップはあなたが言及したのと同じ問題に取り組みますが、はるかに大規模です。この手法により、作成した画像を分解して、ブラウザベースのソリューションにフィードできるようになります。念のために言っておきますが、これはPerl要件の範囲外ですが、ニーズに合う場合があります。

于 2011-01-08T22:56:25.990 に答える
2

キャンバスウィジェットを使用します。画像を配置したり、直接描画したりできます。その場合、組み込みscaleメソッドがサイズ変更を処理します。スクロール用の適切なハンドラーを使用すると、メモリの使用量を適切に保つために、動き回ったときにコンテンツを動的にロードおよびアンロードできます。たとえば、 のコールバックは-xscrollcommand、アンロードされた領域に右にスクロールして、その領域のコンテンツをロードしたことを検出します。アイテムを一度アンロードしてから、画面外に移動できます。

于 2011-01-09T15:51:28.533 に答える
1

<canvas>サンプル データを見ると、実行しようとしていることがさまざまな Web テクノロジ (背景色のある巨大なテーブル、または HTMLタグを使用して最初からレンダリングされたもの) に収まるように見えます。

Perlの場合、多くのサーバー側Web開発手法の1つを使用するか、 XUL::Guiのようなものを使用できます.XUL::Guiは、基本的にFirefox(または他のサポートされているブラウザ)をGUIレンダリングエンジンとして使用する私が書いたモジュールですパール。

要素の使用方法を示す短い例を次に示します<canvas>(この場合、モジュールの例からシェルピンスキーの三角形を描画します)。

use strict;
use warnings;
use XUL::Gui 'g->';

my $width = 400;
my $height = sqrt($width**2 - ($width/2)**2);

g->display(
    g->box(
        g->fill,
        g->middle,
        style => q{
            background-color: black;
            padding:          40px;
        },
        g->canvas(
            id     => 'canvas',
            width  => $width,
            height => int $height,
        )
    ),
    g->delay(sub {
        my $canvas = g->id('canvas')->getContext('2d');
        $canvas->fillStyle = 'white';

        my @points = ([$width/2, 0],
            [0, $height], [$width, $height],
        );
        my ($x, $y) = @{ $points[0] };
        my $num = @points;
        my ($frame, $p);
        while (1) {
            $p = $points[ rand $num ];
            $x = ($x + $$p[0]) / 2;
            $y = ($y + $$p[1]) / 2;

            # draw the point with a little anti-aliasing
            $canvas->fillRect($x + 1/4, $y + 1/4, 1/2, 1/2);

            if (not ++$frame % 1_000) {  # update screen every 1000 points
                $frame % 100_000
                       ? g->flush
                       : g->doevents # keeps firefox happy
            }
        }
    })
);
于 2011-01-10T22:28:46.380 に答える
1

キャンバスでタイル化された写真画像を操作してこれを処理したくない場合 (これは基本的に Michael Carman と NBJack が提案していることです)、独自のカスタム画像タイプを作成できます (C コードが必要です)。に実装する必要がある API は ですTk_CreateImageType。これにより、画像の 5 つの重要な側面 (画像の作成、表示可能なコンテキストへのインストール、描画、コンテキストからの解放、および削除の方法) をカスタマイズできます。確かに、これはかなり簡単に実装できる API であると言われていますが、経験からは言えません。これを行う利点の 1 つは、写真画像タイプ (まれな表示タイプの処理など、あらゆる種類の風変わりなものを含む) に存在するほど複雑にする必要がないため、より効率的なデータ構造をより高速に使用できることです。処理。

于 2011-01-10T09:08:14.353 に答える