Gimp

 view release on metacpan or  search on metacpan

examples/iland  view on Meta::CPAN

#!/usr/bin/perl -w

# 11/09/2024
# V1.01

use Gimp;
use Gimp::Fu;
use PDL::LiteF;
use strict;
use warnings;

podregister {
  $image->selection_none if ($image->selection_bounds)[0];
  $drawable->transform_rotate_simple($camerapos, TRUE, 0, 0) if $camerapos >= 0;
  my $width = $drawable->width;
  my $height = $drawable->height;
  #Pixel region of selection
  my $src = Gimp::PixelRgn->new($drawable, 0, 0, $width, $height, 0, 0);
  my $newimage = Gimp::Image->new($width, $height, RGB);
  my $alpha = $drawable->has_alpha;
  my $layer = $newimage->layer_new(
    $width, $height,
    $alpha ? RGBA_IMAGE : RGB_IMAGE,
    "L1", 100, LAYER_MODE_NORMAL_LEGACY
  );
  $newimage->insert_layer($layer, 0, -1);
  my $newdrawable = $newimage->get_active_drawable;
  my $dest = Gimp::PixelRgn->new($newdrawable, 0, 0, $width, $height, 1, 1);
  my $srcdata = $src->get_rect($drawable->bounds);
  my $destdata = $srcdata->zeroes;
  $destdata->slice(3) .= 255 if $alpha;
  my $quant = ($srcdata->slice("($component)")->max / $delta)->floor->sclr;
  goto FINISH if $quant <= 0; # nothing to do
  my $destmv = $destdata->mv(0,-1); # x y rgb
  Gimp::Progress->init("Rendering...");
  my $relord = $width / 255;
  $newdrawable->fill(FILL_FOREGROUND);
  $delta = 1 if $delta < 1;
  for my $x (0..$width-1) {
    my $col = $srcdata->slice("($component),($x)");
    my $exceed_floor = ($col > $floor);
    my $r = $col->where($exceed_floor); # nvals
    my $destx = ($width - $r * $relord + ($x / $elevation))->long; # nvals
    #Apply elevation following the x offset in original picture
    my $remain_s = zeroes(long, 3, $quant, $r->dim(0)); # xyr quant nvals
    my $yslice = $remain_s->slice("(1)") .= $exceed_floor->which->dummy(0); # quant nvals
    my $xslice = $remain_s->slice("(0)") .= $yslice->xvals + $destx->dummy(0); # quant nvals
    my $rslice = $remain_s->slice("(2)") .= $yslice->xlinvals(0,-1) * $quant*$delta + $r->dummy(0); # quant nvals
    $rslice->whereND($xslice >= $width) .= -1;
    my $gt150_ind = whichND($rslice > 150);
    my $btwn_ind = whichND(($rslice <= 150) & ($rslice >= 50));
    my $lt50_ind = whichND(($rslice < 50) & ($rslice > 0));
    $destmv->slice(',,1:2')->indexND(cat(map $_->indexND($gt150_ind), $xslice, $yslice)->mv(-1,0)) .= $rslice->indexND($gt150_ind) if $gt150_ind->nelem;
    $destmv->slice(',,1')->indexND(cat(map $_->indexND($btwn_ind), $xslice, $yslice)->mv(-1,0)) .= $rslice->indexND($btwn_ind) + 55 if $btwn_ind->nelem;
    $destmv->slice(',,2')->indexND(cat(map $_->indexND($lt50_ind), $xslice, $yslice)->mv(-1,0)) .= $rslice->indexND($lt50_ind) + 200 if $lt50_ind->nelem;
    Gimp::Progress->update($x / $width);
  }
  Gimp::Progress->update(1);
FINISH:
  $dest->set_rect($destdata, 0, 0);
#  die "merge_shadow failed for $newdrawable\n" unless
    $newdrawable->merge_shadow(TRUE); # returns false but works and is needed
  $newdrawable->update(0, 0, $width, $height);
  $newdrawable->transform_rotate_simple(ROTATE_90, TRUE, 0, 0);
  $newimage->resize_to_layers;
  eval { Gimp::Display->new($newimage); };
  #Original pic => original state
  if ($camerapos == 2) {
    $camerapos = 0;
  } elsif ($camerapos == 0) {
    $camerapos = 2;
  }
  $drawable->transform_rotate_simple($camerapos, TRUE, 0, 0) if $camerapos >= 0;
  return $newimage;
};

exit main;
__END__

=head1 NAME

intensitylandscape - Generate an intensity based landscape

=head1 SYNOPSIS

<Image>/Filters/Render/_Intensity Landscape

=head1 DESCRIPTION

Generate an alpha landscape based on intensity. The result is an
interpolated view as if you were looking from one side of the original
picture (which is taken as an apical view).

=head1 AUTHOR

Fabian Frederick <fabian.frederick@gmx.fr>

=head1 DATE

20010601



( run in 1.671 second using v1.01-cache-2.11-cpan-d06a3f9ecfd )