Bio-Graphics

 view release on metacpan or  search on metacpan

lib/Bio/Graphics/Glyph/image.pm  view on Meta::CPAN

When working with photographic images, you may wish to have
Bio::Graphics::Panel create 24-bit (truecolor) images in order to
avoid running out of colors. The symptom of this is that images appear
posterized. To turn on truecolor images, pass the -truecolor option to
Bio::Graphics::Panel.
END
}
sub my_options {
    {
    image => [
	'string',
	undef,
	'Specify the image path or URL to use for the feature.',
	'If no image option is specified, then the glyph will look',
	'inside the feature itself for an image path or URL in a tag named "image"',
	],
    image_prefix => [
	    'string',
	    undef,
	    'A string to prepend to each image path.',
	    'You may use this to prepend a directory path or a partial URL.'],
    vertical_spacing => [
	    'integer',
	    20,
	    'Vertical distance from the box that shows the physical span of the',
	    'feature to the top of the picture, in pixels.'],
    glyph_delegate => [
	'string',
	'generic',
	'The glyph to use for the part of the glyph that shows the physical',
	'span of features.']
    }
}

sub demo_feature {
    my $self = shift;
    my $ex_image = 
	'http://www.catch-fly.com/sites/awhittington/_files/Image/Drosophila-melanogaster.jpg';
    return Bio::Graphics::Feature->new(-start=>1,
				       -end=>500,
				       -name=>$ex_image,
				       -attributes => {
					   image=>$ex_image,
				       },
	);
}

sub new {
  my $self  = shift->SUPER::new(@_);
  $self->{image} = $self->get_image();
  return $self;
}

sub get_image {
  my $self    = shift;
  my ($format,$image)   = eval { $self->image_data };
  unless ($image) {
    warn $@ if $@;
    return;
  }
  my $gd      =   $format eq 'image/png'  ? GD::Image->newFromPngData($image,1)
                : $format eq 'image/jpeg' ? GD::Image->newFromJpegData($image,1)
		: $format eq 'image/gif'  ? GD::Image->newFromGifData($image)
		: $format eq 'image/gd'   ? GD::Image->newFromGdData($image)
		: $format eq 'image/gd2'  ? GD::Image->newFromGd2Data($image)
		: $self->throw("This module cannot handle images of type $format");
  return $gd;
}

sub _guess_format {
  my $self = shift;
  my $path = shift;
  return 'image/png'   if $path =~ /\.png$/i;
  return 'image/jpeg'  if $path =~ /\.jpe?g$/i;
  return 'image/gif'   if $path =~ /\.gif(87)?$/i;
  return 'image/gd'    if $path =~ /\.gd$/i;
  return 'image/gd2'   if $path =~ /\.gd2$/i;
  my ($extension) = $path =~ /\.(\w+)$/;  #cop-out
  return $extension;
}

sub image_path {
  my $self = shift;
  my $feature  = $self->feature  or $self->throw("no feature!");
  my $dirname  = $self->image_dir;
  my $basename = $self->option('image');

  # can't get it from callback, so try looking for an 'image' attribute
  if (!$basename && $feature->can('has_tag') && $feature->has_tag('image')) {
    ($basename)  = $feature->get_tag_values('image');
  }

  return unless $basename;
  return $basename             if $basename =~ m!^\w+:/!;  # looks like a URL
  return $basename             if $basename =~ m!^/!;      # looks like an abs path
  return "$dirname/$basename";
}

sub image_data {
  my $self = shift;
  my $path = $self->image_path or return;

  if ($path =~ m!^\w+:/!) { # looks like a URL
    require LWP::UserAgent;
    my $ua = LWP::UserAgent->new(env_proxy => 1);
    my $response = $ua->get($path);
    if ($response->is_success) {
      return ($response->content_type,$response->content);
    } else {
      $self->throw($response->status_line);
    }


  } else {
    my $content_type = $self->_guess_format($path);
    open F,$path or $self->throw("Can't open $path: $!");
    binmode F;
    my $data;
    $data .= $_ while read(F,$_,1024);
    close F;
    return ($content_type,$data);



( run in 1.010 second using v1.01-cache-2.11-cpan-39bf76dae61 )