Image-Base-Magick

 view release on metacpan or  search on metacpan

lib/Image/Base/Magick.pm  view on Meta::CPAN

# Copyright 2010, 2011, 2012, 2017, 2021 Kevin Ryde

# This file is part of Image-Base-Magick.
#
# Image-Base-Magick is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any later
# version.
#
# Image-Base-Magick is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with Image-Base-Magick.  If not, see <http://www.gnu.org/licenses/>.


# file:///usr/share/doc/imagemagick-6-common/html/www/perl-magick.html
# file:///usr/share/doc/imagemagick-6-common/html/www/formats.html

package Image::Base::Magick;
use 5.004;
use strict;
use Carp;
use Fcntl;
use Image::Magick;
use vars '$VERSION', '@ISA';

use Image::Base;
@ISA = ('Image::Base');

$VERSION = 7;

# uncomment this to run the ### lines
# use Smart::Comments '###';


sub new {
  my ($class, %params) = @_;
  ### Image-Base-Magick new(): %params
  my $err;

  # $obj->new(...) means make a copy, with some extra settings
  if (ref $class) {
    my $self = $class;
    $class = ref $self;
    if (! defined $params{'-imagemagick'}) {
      $params{'-imagemagick'} = $self->get('-imagemagick')->Clone;
    }
    # inherit everything else
    %params = (%$self, %params);
    ### copy params: \%params
  }

  if (! defined $params{'-imagemagick'}) {
    # Crib note: passing attributes to new() is the same as a subsequent
    # set() except no error return from new()
    my $m = $params{'-imagemagick'} = Image::Magick->new;

    # must apply -width, -height as "size" before ReadImage()
    if (exists $params{'-width'} || exists $params{'-height'}) {
      my $width = delete $params{'-width'} || 0;
      my $height = delete $params{'-height'} || 0;
      ### Set(size) -width,-height: "${width}x${height}"
      if ($err = $m->Set (size => "${width}x${height}")) {
        croak $err;
      }
    }
    ### ReadImage xc-black ...
    if ($err = $m->ReadImage('xc:black')) {
      croak $err;
    }
  }
  my $self = bless {}, $class;
  $self->set (%params);

  if (defined $params{'-file'}) {
    $self->load;
  }

  ### new made: $self
  return $self;
}

# "size" is the size of the canvas
# "width" and "height" are the size of a ReadImage() file, or something
# file:///usr/share/doc/imagemagick/www/perl-magick.html#get-attribute
#
sub _magic_get_width {
  my ($m, $idx) = @_;
  my $size;
  if (defined ($size = $m->Get('size'))) {
    # ### $size
    # ### split: [ split /x/, $size ]
    # ### return: (split /x/, $size)[$idx||0]
    return (split /x/, $size)[$idx||0];
  } else {
    return 0;
  }
}
sub _magic_get_height {
  my ($m) = @_;
  _magic_get_width ($m, 1);
}
my %attr_to_get_func = (-width  => \&_magic_get_width,
                        -height => \&_magic_get_height,
                       );
my %attr_to_GetSet = (-file        => 'filename',
                      # these not documented yet ...
                      -ncolours    => 'colors',
                      -file_format => 'magick',
                     );
sub _get {
  my ($self, $key) = @_;
  ### Image-Base-Magick _get(): $key

  my $m = $self->{'-imagemagick'};
  if (my $func = $attr_to_get_func{$key}) {

lib/Image/Base/Magick.pm  view on Meta::CPAN

                   ($fill ? 'fill' : 'stroke') => $colour,
                   strokewidth => 0,
                   points => (($x1+$xh).' '.$y1  # top centre

                              # left
                              .' '.$x1.' '.($y1+$yh)

                              .($yeven ? ' '.$x1.' '.($y2-$yh)  : '')

                              # bottom
                              .' '.($x1+$xh).' '.$y2
                              .($xeven ? ' '.($x2-$xh).' '.$y2   : '')

                              # right
                              .($yeven ? ' '.$x2.' '.($y2-$yh)  : '')
                              .' '.$x2.' '.($y1+$yh)

                              .($xeven ? ' '.($x2-$xh).' '.$y1  : '')
                             ))) {
    croak $err;
  }
}

# sub add_colours {
#   my $self = shift;
#   ### add_colours: @_
# 
#   my $m = $self->{'-imagemagick'};
# }

1;
__END__

=for stopwords PNG Magick filename filenames undef Ryde Zlib Zlib's ImageMagick ImageMagick's imagemagick graphicsmagick RGB lossy hotspot XPM

=head1 NAME

Image::Base::Magick -- draw images using Image Magick

=head1 SYNOPSIS

 use Image::Base::Magick;
 my $image = Image::Base::Magick->new (-width => 100,
                                       -height => 100);
 $image->rectangle (0,0, 99,99, 'white');
 $image->xy (20,20, 'black');
 $image->line (50,50, 70,70, '#FF00FF');
 $image->line (50,50, 70,70, '#0000AAAA9999');
 $image->save ('/some/filename.png');

=head1 CLASS HIERARCHY

C<Image::Base::Magick> is a subclass of C<Image::Base>,

    Image::Base
      Image::Base::Magick

=head1 DESCRIPTION

C<Image::Base::Magick> extends C<Image::Base> to create or
update image files using C<Image::Magick>.

The native ImageMagick drawing has hugely more features, but this module is
a way to point C<Image::Base> style code at an ImageMagick canvas and use
the numerous file formats ImageMagick can read and write.

=head2 Colour Names

Colour names are anything recognised by ImageMagick,

    http://imagemagick.org/www/color.html
    file:///usr/share/doc/imagemagick-doc/html/www/color.html

    #RGB    1, 2, 4-digit hex
    #RRGGBB
    #RRRRGGGGBBBB
    names roughly per X11
    colors.xml file

F<colors.xml> is in F</etc/ImageMagick-6/>, or maybe F</etc/ImageMagick/>,
or maybe F</usr/share/ImageMagick-6.6.0/config/>.

=head2 Anti-Aliasing

By default ImageMagick uses "anti-aliasing" to blur the edges of lines and
circles drawn.  This is unlike the other C<Image::Base> modules but
currently it's not changed or overridden in the methods here.  Perhaps that
will change, or perhaps only for canvases created by C<new()> (as opposed to
supplied in a C<-imagemagick> parameter).  You can turn it off explicitly
with

    my $m = $image->get('-imagemagick');
    $m->Set (antialias => 0);

=head2 Graphics Magick

The C<Graphics::Magick> module using the graphicsmagick copy of imagemagick
should work, to the extent it's compatible with imagemagick.  There's
nothing to choose C<Graphics::Magick> as such currently, but a
C<Graphics::Magick> object can be created and passed in as the
C<-imagemagick> target,

    my $m = Graphics::Magick->new (size => '200x100')
    $m->ReadImage('xc:black');
    my $image = Image::Base::Magick-new (-imagemagick => $m);

As of graphicsmagick 1.3.12, there's something bad in its Perl XS interface
causing segfaults attempting to write to a file handle, which is what
C<$image-E<gt>save()> does.  An C<$m-E<gt>Write()> to a file works.

=head1 FUNCTIONS

See L<Image::Base/FUNCTIONS> for the behaviour common to all Image-Base
classes.

=over 4

=item C<$image = Image::Base::Magick-E<gt>new (key=E<gt>value,...)>

Create and return a new image object.  A new image can be started with
C<-width> and C<-height>,

    my $image = Image::Base::Magick->new (-width => 200,
                                          -height => 100);

Or an existing file can be read,

    my $image = Image::Base::Magick->new
                   (-file => '/some/filename.png');

Or an C<Image::Magick> object can be given,

    $image = Image::Base::Magick->new (-imagemagick => $mobj);

=back

=head1 ATTRIBUTES

=over

=item C<-width> (integer)

=item C<-height> (integer)

Setting these changes the size of the image.

In the current code a C<Resize()> is done which means the existing image is
stretched, but don't depend on that.  It might make more sense to crop when
shrinking and pad with black when extending.

=item C<-imagemagick>

The underlying C<Image::Magick> object.

=item C<-file> (string, default C<undef>)

The filename for C<load> or C<save>, or passed to C<new> to load a file.

The filename is used literally, it doesn't have ImageMagick's "%d" scheme
for sets of numbered files.  The code here is only geared towards a single
image in a canvas, and using the filename literally is the same as other
C<Image::Base> modules.

=item C<-file_format> (string or C<undef>)

The file format as a string like "PNG" or "JPEG", or C<undef> if unknown or
never set.

C<load()> sets C<-file_format> to the format read.  Setting C<-file_format>
can change the format for a subsequent C<save()>, or set the format for a
newly created image.

This sets the C<magick> attribute of the ImageMagick object.  The available
formats are per

    http://imagemagick.org/www/formats.html
    file:///usr/share/doc/imagemagick-doc/html/www/formats.html

Some of the choices are pseudo-formats, for example saving as "X" displays a
preview window in X windows, or "PRINT" writes to the printer.

=item C<-quality_percent> (0 to 100 or C<undef>)

The image quality when saving to JPEG and similar lossy formats which
compress by reducing colours and resolution in ways not too noticeable to
the human eye.  100 means full quality, no such reductions.  C<undef> means
the imagemagick C<DefaultImageQuality>, which is 75.

This attribute becomes the C<quality> parameter to
C<$imagemagick-E<gt>Write()>.

=item C<-zlib_compression> (integer 0-9 or -1, default C<undef>)

The amount of data compression to apply when saving.  The value is Zlib
style 0 for no compression up to 9 for maximum effort.  -1 means Zlib's
default, usually 6.  C<undef> or never set means ImageMagick's default,
which is 7.

This attribute becomes the C<quality> parameter to
C<$imagemagick-E<gt>Write()> when saving PNG.

=back

For reference, ImageMagick (as of version 6.7.7) doesn't read or write the
cursor "hotspot" of XPM format, so there's no C<-hotx> and C<-hoty> options.

=head1 SEE ALSO

L<Image::Base>,
L<Image::Magick>

L<Image::Base::GD>,
L<Image::Base::PNGwriter>,
L<Image::Base::Imager>,
L<Image::Base::Gtk2::Gdk::Pixbuf>,
L<Image::Base::Prima::Image>,
L<Image::Xbm>,
L<Image::Xpm>,
L<Image::Pbm>

L<Prima::Image::Magick>

=head1 HOME PAGE

http://user42.tuxfamily.org/image-base-magick/index.html

=head1 LICENSE

Image-Base-Magick is Copyright 2010, 2011, 2012, 2017, 2021 Kevin Ryde

Image-Base-Magick is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

Image-Base-Magick is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
Image-Base-Magick.  If not, see <http://www.gnu.org/licenses/>.

=cut



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