perl-tk: Interactividad visualiza un gran dato ráster 2d (como xvcg)

Quiero escribir una aplicación de Perl usando tk para visualizar un gran diagrama 2d (se puede considerar como una imagen 2d). Necesito desplazarme y cambiar el tamaño. Además, no necesito almacenar la imagen completa en la memoria.

Es demasiado grande para guardarlo en una imagen grande, pero puedo volver a dibujar fácilmente cualquier parte. Entonces, quiero escribir una aplicación gráfica para ver estos datos en modo interactivo. Esto es como lo que hace xvcg para los gráficos: http://blogs.oracle.com/amitsaha/resource/blog-shots/apt-rdepends.png (es un ejemplo de interfaz. Hay barras de desplazamiento xey y barras de zoom)

Mis datos se parecen un poco a http://www.access-excel-vba.com/giantchart.png sin ningún texto con líneas más delgadas (1px), muchos puntos en ellas y tienen tamaños (en este momento) de 33000x23000 y serán más grandes. Yo uso imágenes de 2 bits por píxel.

Entonces, ¿cómo puedo programar un visor de imágenes desplazable y ampliable en perl / tk? El requisito no es almacenar la imagen completa en la memoria (¡190 Mb ahora y serán más!), Sino pedirle a alguna función que la dibuje en partes.

Acerca de la selección de idioma / kit de herramientas. Mi generador de datos está escrito en perl, el sistema operativo es unix / POSIX, por lo que no quiero cambiar de idioma. Puedo cambiar a otro conjunto de herramientas gráficas, pero perl / tk está preinstalado en las PC de destino.

preguntado el 08 de enero de 11 a las 22:01

4 Respuestas

Utilizar Canvas widget. Puede colocar imágenes o dibujar directamente, en cuyo caso la función scale El método manejaría el cambio de tamaño. Con los controladores adecuados para el desplazamiento, puede cargar y descargar contenido dinámicamente a medida que se desplaza para mantener un uso de memoria razonable. por ejemplo, la devolución de llamada para el -xscrollcommand detectaría cuando se desplaza hacia la derecha en un área descargada y carga el contenido de esa área. Puede descargar elementos una vez y luego salir de la pantalla.

Respondido el 09 de enero de 11 a las 18:01

Esto puede sonar divertido, pero creo que su mejor enfoque sería echar un vistazo a algunos artículos sobre cómo escribir un juego eficiente de desplazamiento de mosaicos en 2D. He escrito algo parecido a lo que ha descrito antes en Java, pero los conceptos básicos son los mismos. Si puede descubrir cómo dividir su imagen en mosaicos más pequeños, es solo una cuestión de transmitir y escalar solo las partes visibles.

Alternativamente, puede renderizar la imagen completa en el disco y luego usar algo como http://www.labnol.org/internet/design/embed-large-pictures-panoramas-web-pages-google-maps-image-viewer/2606/ . Google Maps aborda el mismo problema que ha mencionado, pero a una escala mucho mayor. Esta técnica podría descomponer la imagen que ha creado para usted y luego permitirle ingresarla en una solución basada en navegador. Eso sí, esto se sale de los requisitos de Perl, pero puede adaptarse a sus necesidades.

Respondido el 09 de enero de 11 a las 01:01

Es bueno para casos generales, pero quiero resolver rápidamente mi caso. perl y tk me permiten desarrollarme rápidamente. Además, creo que hace un minuto sobre mosaicos (como gmaps): no los necesito porque puedo regenerar muy rápido (0.5 segundos para 1Mpix) cualquier fragmento de imagen. Esta es una utilidad del programador, no un juego, por lo que es normal esperar una parte del segundo - osgx

Si los mosaicos tienen un tamaño de 256x256 pix, necesito para el caso pequeño un mosaico de 128x90. Y quiero analizar muchas imágenes diferentes, así que necesito almacenar 11520 de mosaicos y más para cada imagen. Pero los datos utilizados para generar la imagen están bien estructurados y se pueden almacenar en 1 archivo. - osgx

Si no desea manejar esto trabajando con imágenes de fotos en mosaico en un lienzo (que es esencialmente lo que sugieren Michael Carman y NBJack), entonces puede escribir su propio tipo de imagen personalizada (requiere algo de código C). La API que necesita implementar es Tk_CreateImageType, que le permite personalizar cinco aspectos clave de las imágenes (cómo se crean, se instalan en un contexto visualizable, se dibujan, se liberan del contexto y se eliminan). Me han dicho, pero no puedo decirlo por experiencia, es cierto, que esta es una API razonablemente fácil de implementar. Una ventaja de hacer esto es que no necesita tener tanta complejidad como la que existe en el tipo de imagen fotográfica (que incluye todo tipo de elementos exóticos, como el manejo de tipos de visualización raros) y, por lo tanto, puede usar una estructura de datos más eficiente y más rápida. Procesando.

Respondido el 10 de enero de 11 a las 12:01

Al observar sus datos de muestra, parece que lo que está tratando de hacer puede encajar dentro de varias tecnologías web (ya sea una tabla masiva con colores de fondo o renderizado desde cero con el código HTML <canvas> etiqueta).

Para Perl, puede optar por una de las muchas técnicas de desarrollo web del lado del servidor, o puede usar algo como XUL :: Gui que es un módulo que escribí que básicamente usa Firefox (u otros navegadores compatibles) como motor de renderizado de interfaz gráfica de usuario para Perl.

A continuación, se muestra un breve ejemplo que muestra cómo utilizar <canvas> elemento (en este caso para dibujar un triángulo de Sierpinski, de los ejemplos del módulo):

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
            }
        }
    })
);

Respondido el 11 de enero de 11 a las 01:01

No no no. No es para web. Es una herramienta para programadores de C, puede ser como xvcg (que es una aplicación X fea) - osgx

Los datos no son una tabla, solo un montón de líneas largas de 1 píxel de altura. cada línea tiene algunos puntos marcados. Hay 23000 de líneas en un caso típico. - osgx

también hay una etiqueta Tk, que no es para web - osgx

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.