Graphics-DZI

 view release on metacpan or  search on metacpan

Build.PL  view on Meta::CPAN

SUBCLASS

my $builder = Module::Build::Custom->new(
    module_name         => 'Graphics::DZI',
    license             => 'perl',
#    version             => $version,
    dist_author         => 'Robert Barta <drrho@cpan.org>',
    dist_version_from   => 'lib/Graphics/DZI.pm',
    build_requires => {
	'Moose'               => '',
	'Image::Magick'       => '',
	'File::Path'          => '',
	'File::Slurp'         => '',
	'File::Basename'      => '',
	'Getopt::Long'        => '',
	'Pod::Usage'          => '',
	'Log::Log4perl'       => '',
	'Image::Magick'       => '',
	'List::MoreUtils'     => '',
        'Test::More'          => '',
	'Test::Exception'     => '',
	'Test::Pod::Coverage' => '',
    },
    script_files       => [ 'script/deepzoom' ],
    add_to_cleanup     => [ 'Graphics-DZI-*' ],
    create_makefile_pl => 'traditional',
);

META.yml  view on Meta::CPAN

  - 'Robert Barta <drrho@cpan.org>'
abstract: DeepZoom Image Pyramid Generation
license: perl
resources:
  license: http://dev.perl.org/licenses/
build_requires:
  File::Basename: ''
  File::Path: ''
  File::Slurp: ''
  Getopt::Long: ''
  Image::Magick: ''
  List::MoreUtils: ''
  Log::Log4perl: ''
  Moose: ''
  Pod::Usage: ''
  Test::Exception: ''
  Test::More: ''
  Test::Pod::Coverage: ''
configure_requires:
  Module::Build: 0.340201
provides:

Makefile.PL  view on Meta::CPAN

use ExtUtils::MakeMaker;
WriteMakefile
(
          'NAME' => 'Graphics::DZI',
          'VERSION_FROM' => 'lib/Graphics/DZI.pm',
          'PREREQ_PM' => {
                           'File::Basename' => '',
                           'File::Path' => '',
                           'File::Slurp' => '',
                           'Getopt::Long' => '',
                           'Image::Magick' => '',
                           'List::MoreUtils' => '',
                           'Log::Log4perl' => '',
                           'Moose' => '',
                           'Pod::Usage' => '',
                           'Test::Exception' => '',
                           'Test::More' => '',
                           'Test::Pod::Coverage' => ''
                         },
          'INSTALLDIRS' => 'site',
          'EXE_FILES' => [

lib/Graphics/DZI.pm  view on Meta::CPAN

=head1 INTERFACE

=head2 Constructor

The constructor accepts the following fields:

=over

=item C<image>

The L<Image::Magick> object which is used as canvas.

(since 0.05)

The image can also be a whole stack (L<Image::Magick> allows you to do that). In that case the
bottom image is regarded as the one with the I<highest> degree of detail, and that is tiled first
(at the higher resolutions). Images up the stack are then taken in turn, until only the top-level
image remains. See C<pop> if you want to influence this policy.

=item C<scale> (integer, default: 1)

Specifies how much the image is stretched in the process.

=item C<overlap> (integer, default: 4)

lib/Graphics/DZI.pm  view on Meta::CPAN


=item C<overlays> (list reference, default: [])

An array of L<Graphics::DZI::Overlay> objects which describe how further images are supposed to be
composed onto the canvas image.

=back

=cut

has 'image'    => (isa => 'Image::Magick', is => 'rw', required => 1);
has 'scale'    => (isa => 'Int',           is => 'ro', default => 1);
has 'overlap'  => (isa => 'Int',           is => 'ro', default => 4);
has 'tilesize' => (isa => 'Int',           is => 'ro', default => 256);
has 'format'   => (isa => 'Str'   ,        is => 'ro', default => 'png');
has 'overlays' => (isa => 'ArrayRef',      is => 'rw', default => sub { [] });

=head2 Methods

=over

lib/Graphics/DZI/A4.pm  view on Meta::CPAN


Do not be fooled by the A4; any format should do.

=back

=cut

use Moose::Util::TypeConstraints qw(enum);
enum 'packing' => qw( exponential linear );

has '+image'    => (isa => 'Image::Magick', required => 0);
has 'A4s'       => (isa => 'ArrayRef',      is => 'ro'    );
has 'W'         => (isa => 'Int'   ,        is => 'rw');
has 'H'         => (isa => 'Int'   ,        is => 'rw');
has 'sqrt'      => (isa => 'Num',           is => 'rw');
has 'pack'      => (isa => 'packing',       is => 'rw', default => 'exponential');

sub BUILD {
    my $self = shift;
    ($self->{W}, $self->{H}) = $self->A4s->[0]->GetAttributes ('width', 'height');     # single A4

lib/Graphics/DZI/A4.pm  view on Meta::CPAN

This iterate honors the fact that we are dealing with a set of documents, not ONE large image.

=cut

sub _list2huge {
    my $sqrt = shift;
    my ($W, $H) = (shift, shift);

    my $dim = sprintf "%dx%d", map { $_ * $sqrt } ($W, $H);
    $log->debug ("building composite document: DIM $dim ($sqrt)");
    use Image::Magick;
    my $huge = Image::Magick->new ($dim);
    $huge->Read ('xc:white');
    $huge->Transparent (color => 'white');

    foreach my $a (0 .. $sqrt*$sqrt - 1) {
	my ($j, $i) = ( int( $a / $sqrt)  , $a % $sqrt );
	$log->debug ("    index $a (x,y) = $i $j");

	$huge->Composite (image => $_[$a],
			  x     => $i * $W,
			 'y'    => $j * $H,

lib/Graphics/DZI/Document.pm  view on Meta::CPAN

BEGIN {
    $log = Log::Log4perl->get_logger ();
}

=head1 NAME

Graphics::DZI::Document - DeepZoom Image Pyramid, Sparse Document Images

=head1 SYNOPSIS

    # prepare a bunch of Image::Magick objects
    @pages = ......;

    # create the overlay itself
    use Graphics::DZI::Document;
    my $o = new Graphics::DZI::Document (pages => \@pages,
					 x => 80000, 'y' => 40000,
					 pack => 'linear',
					 squeeze => 256);

    # use the Graphics::DZI::Files and add this as overlay

lib/Graphics/DZI/Document.pm  view on Meta::CPAN

a parameter C<pack> determines between C<linear> and C<exponential> growth of pages at higher
resolutions. With linear you actually get 1, 4, 9, 16, 25...  documents (so it is actually squared
linear). With exponential you get more aggressively 1, 4, 16, 32, ... pages.

=cut

use Moose::Util::TypeConstraints qw(enum);
enum 'packing' => qw( exponential linear );

has 'pages'     => (isa => 'ArrayRef',       is => 'rw', required => 1);
has '+image'    => (isa => 'Image::Magick',              required => 0);
has 'W'         => (isa => 'Int'   ,        is => 'rw');
has 'H'         => (isa => 'Int'   ,        is => 'rw');
has 'sqrt'      => (isa => 'Num',           is => 'rw');
has 'pack'      => (isa => 'packing',       is => 'rw', default => 'exponential');

sub BUILD {
    my $self = shift;
    ($self->{W}, $self->{H}) = $self->pages->[0]->GetAttributes ('width', 'height');     # single document

    use feature "switch";

lib/Graphics/DZI/Document.pm  view on Meta::CPAN


    $self->{ image } = _list2huge ($self->sqrt, $self->W, $self->H, @{ $self->pages }) ;
}

sub _list2huge {
    my $sqrt = shift;
    my ($W, $H) = (shift, shift);

    my $dim = sprintf "%dx%d", map { $_ * $sqrt } ($W, $H);
    $log->debug ("building composite document: DIM $dim ($sqrt)");
    use Image::Magick;
    my $huge = Image::Magick->new ($dim);
    $huge->Read ('xc:white');
    $huge->Transparent (color => 'white');

    foreach my $a (0 .. $sqrt*$sqrt - 1) {
	last unless $_[$a];
	my ($j, $i) = ( int( $a / $sqrt)  , $a % $sqrt );
	$log->debug ("    index $a (x,y) = $i $j");

	$huge->Composite (image => $_[$a],
			  x     => $i * $W,

lib/Graphics/DZI/Files.pm  view on Meta::CPAN

=head1 INTERFACE

=head2 Constructor

Additional to the parent class L<Graphics::DZI>, the constructor takes the following fields:

=over

=item C<format> (default C<png>):

An image format (C<png>, C<jpg>, ...). Any format L<Image::Magick> understands will do.

=item C<path>: (deprecated from 0.05 onwards, use C<dzi>)

A directory name (including trailing C</>) where the tiles are written to. This has to include the
C<_files> part required by the DZI format.

=item C<prefix>: (deprecated from 0.05 onwards, use C<dzi>)

The string to be prefixed the C<_files/> part in the directory name. Usually the name of the image
to be converted. No slashes.

lib/Graphics/DZI/Overlay.pm  view on Meta::CPAN

=head1 INTERFACE

=head2 Constructor

It expects the following fields:

=over

=item C<image>: (required)

L<Image::Magick> object.

=item C<x>,C<y>: (integers, no default)

Coordinates of the top-left corner of the above image on the canvas 

=item C<squeeze>: (integers, no default)

A factor how much the image should be made smaller, relative to the canvas. I use a power of two to
avoid that the canvas is a bit fuzzy.

=back

=cut

has 'image'   => (isa => 'Image::Magick', is => 'rw', required => 1);
has 'x'       => (isa => 'Int', is => 'rw');
has 'y'       => (isa => 'Int', is => 'rw');
has 'squeeze' => (isa => 'Num', is => 'rw');

=head2 Methods

=over

=item B<halfsize>

lib/Graphics/DZI/Overlay.pm  view on Meta::CPAN

	    $r->[3] - $r->[1],                                                         # height
	    );

	my $oc = $self->{image}->clone;
#	warn "overlay clone "; $oc->Display();
	$oc->Crop (geometry => "${dx}x${dy}+${ox}+${oy}");
#	warn "cropped oc";   $oc->Display();

#	unless ($tile) {                                                               # this just makes sure that we are composing onto SOMETHING
##	    warn "XXXXXXXXX generating substitute tile";
	my $tile = Image::Magick->new ("${tdx}x${tdy}");                               # create an empty one
	$tile->Read ('xc:yellow');                                                 # paint it white (otherwise composite would not work?)
	$tile->Transparent (color => 'yellow');
#	warn "substitute tile "; $tile->Display();
#	}
#	warn "before overlay tile "; $tile->Display();
	$tile->Composite (image => $oc,
			  x     => $r->[0] - $tx,                                      # intersection left/top relative to tile
			  'y'   => $r->[1] - $ty,
			  compose => 'Over',
		);

script/deepzoom  view on Meta::CPAN

that the image can be viewed with DeepZoom image clients (AJAX or MS SilverLight) with varying
resolutions. Bootstrap yourself via L<http://en.wikipedia.org/wiki/Deep_Zoom>.

This program accepts image file names on the command line, and generates these tiles at a file
system location of your choice. It also generates the XML descriptor as file.

=head1 Usage

=head2 Arguments

Arguments are all names of image files. If one of them cannot be read by L<Image::Magick> then the
program will die.

=head2 Options

Following command line switches are understood:

=cut

my %options;

script/deepzoom  view on Meta::CPAN

Log::Log4perl->easy_init($ERROR);
our $log = Log::Log4perl->get_logger ("deepzoom");
$log->level ($loglevel);


use File::Path qw(make_path);
make_path ($path);                                                           # assert path

my @images;
foreach my $arg (@ARGV) {                                                    # slurp in images from the comment line
    use Image::Magick;
    my $image = Image::Magick->new;
    $image->Read ($arg) && $log->logdie ("something is wrong with '$arg'");  # stop right there
    push @images, $image;
}


if ($document) {                                                             # document mode tiles the images
    my $pref;
    if ($prefix) {
	$pref = $prefix;
    } else  {

t/01_dzi.t  view on Meta::CPAN

use constant DONE => 1;

if (DONE) {
    throws_ok {
	my $dzi = new Graphics::DZI (image => 23,
				     overlap  => 4,
				     tilesize => 128,
	    );
    } qr/Validation failed/i, 'invalid image';

    use Image::Magick;
    my $image = Image::Magick->new (size=> "100x50");
    $image->Read('xc:white');
    my $dzi = new Graphics::DZI (image => $image,
				 overlap  => 4,
				 tilesize => 128,
	);

    isa_ok ($dzi, 'Graphics::DZI');

    like ($dzi->descriptor, qr/xml/,         'XML descriptor exists');
    like ($dzi->descriptor, qr/Width='100'/, 'XML descriptor width');
    like ($dzi->descriptor, qr/Height='50'/, 'XML descriptor height');

    is ($dzi->tilesize, 128, 'tilesize echo');
    is ($dzi->overlap,    4, 'overlap echo');
}

if (DONE) {
    use Image::Magick;
    my $image = Image::Magick->new (size=> "100x50");
    $image->Read('xc:white');
    use Graphics::DZI::Files;
    my $dzi = new Graphics::DZI::Files (image => $image,
					prefix => 'xxx',
					path   => '/tmp/',
	);

    isa_ok ($dzi, 'Graphics::DZI::Files');
    is ($dzi->path,    '/tmp/', 'path echo');
}



( run in 1.650 second using v1.01-cache-2.11-cpan-beeb90c9504 )