2011-01-08 2 views
1

Я хочу написать приложение perl с помощью tk для визуализации большого 2d-графика (его можно рассматривать как изображение 2d). Мне нужно прокручивать и изменять размер. Также мне не нужно хранить целые изображения в памяти.perl-tk: Интерактивность визуализирует большие 2d растровые данные (например, xvcg)

Это слишком большое, чтобы быть спасенным на одной огромной картинке, но я могу легко перерисовать любую ее часть. Итак, я хочу написать графическое приложение для просмотра этих данных в интерактивном режиме. Это похоже на то, что xvcg сделать для графиков: http://blogs.oracle.com/amitsaha/resource/blog-shots/apt-rdepends.png (это пример интерфейса Есть хну полосы прокрутки и масштабирования полосы.)

Мои данные выглядит как http://www.access-excel-vba.com/giantchart.png без текста с более тонкими (1px) линиями, много точек на них и имеют размеры (в настоящее время) от 33000x23000 и будут больше. Я использую 2bit-per-pixel Images.

Итак, как я могу программировать прокручиваемый и масштабируемый просмотрщик изображений в perl/tk? Требование состоит не в том, чтобы хранить целые изображения в памяти (190 Mb сейчас и будет больше!), Но попросите какую-нибудь функцию нарисовать его по частям.

О языке/выбор инструментария. Мой генератор данных написан на perl, ОС - unix/POSIX, поэтому я не хочу переключать язык. Я могу переключиться на другой графический инструментарий, но perl/tk предварительно установлен на целевых ПК.

ответ

2

Используйте виджет Canvas. Вы можете размещать изображения или рисовать напрямую, и в этом случае встроенный метод scale будет обрабатывать изменение размера. С помощью правых обработчиков для прокрутки вы можете динамически загружать и выгружать контент при перемещении, чтобы разумно использовать память. например обратный вызов для -xscrollcommand будет обнаруживать, когда вы прокручиваете прямо в незагруженную область и загружаете контент для этой области. Вы можете выгружать элементы, а затем выходить за экран.

2

Это может показаться забавным, но я думаю, что ваш лучший подход состоял бы в том, чтобы взглянуть на несколько статей о написании эффективной 2D-прокрутки. Я написал что-то вроде того, что вы описали ранее в Java, но основные понятия одинаковы. Если вы можете понять, как разбить изображение на более мелкие плитки, это просто вопрос потоковой передачи и масштабирования только видимых частей.

В качестве альтернативы, вы можете отобразить все изображение на диске, а затем использовать что-то вроде http://www.labnol.org/internet/design/embed-large-pictures-panoramas-web-pages-google-maps-image-viewer/2606/. Google Maps решает ту же проблему, о которой вы говорили, но в гораздо большем масштабе. Этот метод может сломать созданное вами изображение, а затем позволить вам передать его в браузерное решение. Имейте в виду, что это делает шаг за пределами вашего требования к Perl, но это может удовлетворить ваши потребности.

+0

Это хорошо для общего случая, но я хочу, чтобы быстро разрешите мое дело. perl и tk позволяет мне быстро развиваться. Кроме того, я думаю, что минуту назад о плитки (например, gmaps) - мне они не нужны, потому что я могу очень быстро (0,5 секунды для 1Mpix) восстановить любой фрагмент изображения. Это утилита программиста, а не игра, поэтому нормально ждать некоторую часть секунды – osgx

+0

Если плитка имеет размер 256x256 пикселей, мне нужно для маленького корпуса 128х90 плит. И я хочу проанализировать множество разных изображений, поэтому мне нужно сохранить 11520 плиток и многое другое для каждого изображения ??? Но данные, используемые для создания изображения, хорошо структурированы и могут храниться в 1 файле. – osgx

1

Если вы не хотите справляться с этим, работая с черепичными фотоизображениями на холсте (что, по сути, предлагает Майкл Карман и NBJack), вы можете написать свой собственный тип изображения (требуется некоторый код C). API, который вам нужно реализовать, - это Tk_CreateImageType, который позволяет вам настроить пять ключевых аспектов изображений (как они созданы, установлены в отображаемый контекст, выведены, выпущены из контекста и удалены). Мне сказали - но не могу сказать по опыту, по общему признанию, что это достаточно простой API для реализации. Одно из преимуществ этого заключается в том, что вам не нужно иметь столько же сложности, сколько существует в типе фотоизображения (который включает в себя все виды экзотики, такие как обработка для редких типов отображения), и поэтому может использовать более эффективную структуру данных и быстрее обработка.

1

От взгляда на ваши данные образца, похоже, то, что вы пытаетесь сделать, может вписываться в различные веб-технологии (массивную таблицу с цветами фона или визуализированную с нуля с тегом HTML <canvas>).

Для Perl вы можете использовать один из многих методов веб-разработки на стороне сервера, или вы можете использовать что-то вроде XUL::Gui, которое является модулем, который я написал, который в основном использует Firefox (или другие поддерживаемые браузеры) как движок рендеринга gui для Perl.

Вот краткий пример, показывающий, как использовать <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 
      } 
     } 
    }) 
); 
+0

Нет-нет-нет. Это не для Интернета. Это инструмент для программистов на C, он может быть похож на xvcg (что является уродливым X-приложением). – osgx

+0

Данные не являются таблицей, это всего лишь много длинных строк 1 пикселя высоты. каждая строка имеет некоторые точки, отмеченные на ней. В типичном случае есть 23000 строк. – osgx

+0

есть также тег Tk, который не предназначен для Интернета – osgx