PDLA-Rest

 view release on metacpan or  search on metacpan

Libtmp/Image2D/image2d.pd  view on Meta::CPAN

=for ref

return the (dataflown) area of an image described by a polygon

=for usage

  polyfillv($im,$ps,[\%options]);

The default method of determining which points lie inside of the polygon used
is not as strict as the method used in L<pnpoly|pnpoly>. Often, it includes vertices
and edge points. Set the C<Method> option to change this behaviour.

=for option

Method   -  Set the method used to determine which points lie in the polygon.
            => Default - internal PDLA algorithm
            => pnpoly  - use the L<pnpoly|pnpoly> algorithm

=for example

  # increment intensity in area bounded by $poly using the pnpoly algorithm
  $im->polyfillv($poly,{'Method'=>'pnpoly'})++; # legal in perl >= 5.6

  # compute average intensity within area bounded by $poly using the default algorithm
  $av = $im->polyfillv($poly)->avg;

=cut

sub PDLA::polyfillv :lvalue {
	my $opt;
	$opt = pop @_ if ref($_[-1]) eq 'HASH';
	barf('Usage: polyfillv($im,$ps,[\%options])') unless @_==2;

	my ($im,$ps) = @_;
	barf("ps must contain pairwise points.\n") unless $ps->getdim(0) == 2;

	if($opt) {
		use PDLA::Options qw();
		my $parsed = PDLA::Options->new({'Method' => undef});
		$parsed->options($opt);
		return $im->where(PDLA::pnpoly_pp($im, $ps)) if $parsed->current->{'Method'} eq 'pnpoly';
	}

	my $msk = zeroes(long,$im->dims);
	PDLA::polyfill_pp($msk, $ps, 1);
	return $im->where($msk);
}
*polyfillv = \&PDLA::polyfillv;

EOPM

pp_addhdr('#include "rotate.c"'."\n\n");
pp_add_exported('','rotnewsz');
pp_addxs('

void
rotnewsz(m,n,angle)
	int m
	int n
	float angle
	PPCODE:
	int newcols, newrows;

	if (getnewsize(m,n,angle,&newcols,&newrows) != 0)
		croak("wrong angle (should be between -90 and +90)");
	EXTEND(sp,2);
	PUSHs(sv_2mortal(newSVnv(newcols)));
	PUSHs(sv_2mortal(newSVnv(newrows)));
');

pp_def('rot2d',
       HandleBad => 0,
	Pars => 'im(m,n); float angle(); bg(); int aa(); [o] om(p,q)',
	Code => 'int ierr;
		 if ((ierr = rotate($P(im),$P(om),$SIZE(m),$SIZE(n),$SIZE(p),
			$SIZE(q),$angle(),$bg(),$aa())) != 0) {
			if (ierr == -1)
				croak("error during rotate, wrong angle");
			else
				croak("wrong output dims, did you set them?");
		}',
	# ugly workaround since $SIZE(m) and $SIZE(n) are not initialized
	# when the redodimscode is called
	# need to fix this!
	RedoDimsCode => 'int ncols, nrows;
			if ($PDLA(im)->ndims < 2)
				croak("need > 2d piddle");
			if (getnewsize($PDLA(im)->dims[0],$PDLA(im)->dims[1],
				$angle(), &ncols,
				&nrows) != 0)
			   croak("error during rotate, wrong angle");
			/* printf("o: %d, p: %d\n",ncols,nrows); */
			$SIZE(p) = ncols;
			$SIZE(q) = nrows;',
	GenericTypes => ['B'],
	Doc => << 'EOD',

=for ref

rotate an image by given C<angle>

=for example

  # rotate by 10.5 degrees with antialiasing, set missing values to 7
  $rot = $im->rot2d(10.5,7,1);

This function rotates an image through an C<angle> between -90 and + 90
degrees. Uses/doesn't use antialiasing depending on the C<aa> flag.
Pixels outside the rotated image are set to C<bg>.

Code modified from pnmrotate (Copyright Jef Poskanzer) with an algorithm based
on "A Fast Algorithm for General  Raster  Rotation"  by  Alan Paeth,
Graphics Interface '86, pp. 77-81.

Use the C<rotnewsz> function to find out about the dimension of the
newly created image

  ($newcols,$newrows) = rotnewsz $oldn, $oldm, $angle;

L<PDLA::Transform|PDLA::Transform> offers a more general interface to
distortions, including rotation, with various types of sampling; but



( run in 1.092 second using v1.01-cache-2.11-cpan-5511b514fd6 )