GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
Gimp::PixelRgn(3) User Contributed Perl Documentation Gimp::PixelRgn(3)

Gimp::PixelRgn - Operate on raw pixels in powerful, efficient way.

  use Gimp;
  use PDL; # to do sensible things with the pixels
  my $i = Gimp::Image->new(10,10,RGB);
  my $l = $i->layer_new(10,10,RGBA_IMAGE,"new layer",100,VALUE_MODE);
  $i->insert_layer($l,0,0);
  my $gd = $l->get;
  my $region = $gd->pixel_rgn(0,0,10,10,0,0);
  my $piddle = $region->get_pixel($x,$y);
  print $piddle."\n"; # stringified piddle is readable

Perl interface to GIMP's low-level pixel-access functions. In Gimp-Perl (mirroring how GIMP does it), to access these functions you must get a "Gimp::GimpDrawable" from a "Gimp::Drawable". You can then get either a "Gimp::Tile" or "Gimp::PixelRgn" object, and work with that. Since the tile interface is very low-level, it is not further documented here. The "Gimp::PixelRgn" methods take and return PDL objects to handle the data, with a few exceptions.

It is vital to note that while GIMP uses the "GimpRGB" format (each colour a floating point number from 0 to 1.0) to pass colours around as parameters, the pixel functions all work on bytes, integers with values from 0 to 255. Depending on the type of layer/image colour mode (e.g. RGB vs indexed), the meaning of the integers' values may also vary.

In GIMP, drawables (also known as PARAM_DRAWABLE or Gimp::Drawable) are things you can draw on: layers or channels. While in GIMP most functions named "gimp_drawable_something" operate on "drawable_ID"s, some functions (notably the ones operating on raw pixel data!) need a "GimpDrawable" instead. In Gimp-Perl, this distinction is made explicit in that every function that operates on a "GimpDrawable" is no longer called "gimp_drawable_something" but "gimp_gdrawable_something".

Every drawable has a corresponding "GimpDrawable", you can get it with the "gimp_drawable_get" function:

  my $gdrawable = $drawable->get;

When the $gdrawable is destroyed, it is automatically flushed & detached, so you don't need to do this yourself. Do not call this method more than once; each time it is called, GIMP makes a new internal list of tiles, which will cause mayhem if done more than once.

GIMP's "PixelRgn"s are rectangular parts of a drawable. You can access single pixels, rows, columns and rectangles within these regions.

To create a pixel region, you first get a GimpDrawable structure as above. Then you can create a "Gimp::PixelRgn" structure:

  $region = $gdrawable->pixel_rgn(0,0,50,30,0,0); # read-only
  $region = $gdrawable->pixel_rgn(0,0,50,30,1,1); # read-write
  $region = $gdrawable->pixel_rgn(0,0,50,30,1,0); # means undo won't work!

The last two parameters are respectively "dirty" and "shadow". Be warned that if you set "shadow" to be true, the "shadow" tile(s) start out as all-zero. If you only set some, e.g. with "set_pixel", then once you have called "$drawable->merge_shadow($undo)", nearly all the drawable's contents will be zeros.

The main "use case" for this functionality is to have a read-only "source" region, and a writable "destination" region:

  $gdrawable = $drawable->get;
  $src = $gdrawable->pixel_rgn(0,0,50,30,0,0); # read-only
  $dst = $gdrawable->pixel_rgn(0,0,50,30,1,1); # read-write
  my ($x,$y,$w,$h)=($dst->x,$dst->y,$dst->w,$dst->h);
  my $pdl = $src->get_rect($x,$y,$w,$h);
  $pdl += 7; # trivial operation
  $dst->set_rect($pdl, $x, $y);
  $drawable->merge_shadow(1);

However, it is possible to use dirty=1, shadow=0; see the "setpixel" example below. The GIMP API document says that it "could prevent the Undo-System from working as expected".

The following functions return pixel data in PDL objects:

  $piddle = $region->get_pixel(45,60); # return the pixel at (45|60)
  $piddle = $region->get_row(45,60,10); # return ten horizontal pixels
  $piddle = $region->get_col(45,60,10); # same but vertically
  $piddle = $region->get_rect(45,60,10,12); # a 10x12 rectangle

And the corresponding set-functions:

  $region->set_pixel($piddle,45,60);    # set pixel at (45|60)
  $region->set_row($piddle,45,60);      # set a row
  $region->set_col($piddle,45,60);      # set a column
  $region->set_rect($piddle,45,60);     # set a whole rectangle

Please note that (unlike the C functions they call), the size arguments (width and/or height) are omitted; they are calculated from the piddle.

The dimensions of the piddle are, for a rectangle (due to how GIMP stores the data):

  ($bytesperpixel, $width, $height) = $r->get_rect($l->bounds)->dims;

For a row or column:

  ($bytesperpixel, $width) = $r->get_row(0, 0, $width)->dims;
  ($bytesperpixel, $height) = $r->get_col(0, 0, $height)->dims;

Functions demonstrating getting and setting the colour of a pixel on an RGB layer:

  use PDL;
  sub setpixel {
    my ($i, $l, $x, $y, $colour) = @_;
    my @bounds = $l->bounds;
    my $region = $l->get->pixel_rgn(@bounds,1,0); # warning! see above
    my $piddle = pdl [ @{$colour}[0..2] ]; # remove any alpha
    $piddle *= 255; # so it's bytes, not floats
    $region->set_pixel($piddle, $x, $y);
    $l->update(@bounds);
  }

  sub getpixel {
    my ($i, $l, $x, $y) = @_;
    my $region = $l->get->pixel_rgn($l->bounds,0,0);
    my $piddle = $region->get_pixel($x,$y);
    return unpdl $piddle;
  }

GIMP uses "tiles" as a way of breaking drawables into smaller chunks. This allows a potentially very large image to be process in manageable pieces. To use this, GIMP (and therefore Gimp-Perl) provides an "iterator" functionality to process each part of the image. This is best explained with a simple working example:

  sub iterate {
    my ($i, $l, $inc) = @_;
    my @bounds = $l->bounds;
    {
      # in block so $src/$dst go out of scope before merge
      my $src = Gimp::PixelRgn->new($l,@bounds,0,0);
      my $dst = Gimp::PixelRgn->new($l,@bounds,1,1);
      my $iter = Gimp->pixel_rgns_register($dst);
      do {
        my ($x,$y,$w,$h)=($dst->x,$dst->y,$dst->w,$dst->h);
        my $pdl = $src->get_rect($x,$y,$w,$h);
        $pdl += $inc;
        $dst->data($pdl);
      } while (Gimp->pixel_rgns_process($iter));
    }
    $l->merge_shadow(1);
    $l->update(@bounds);
  }

The key points are:

Iterator registration and processing
Done respectively with "$iter = Gimp->pixel_rgns_register($dst)" and "do { ... } while (Gimp->pixel_rgns_process($iter))".
Block scope
The source and destination "Gimp::PixelRgn"s are in a block so their lexical variables go out of scope at the end, and therefore the objects get destroyed, and they get flushed and detached.
Merge shadow tiles
Once the operation is complete and the shadow tiles have all been set with the right data, "$drawable->merge_shadow($undo)" is called. $undo is a boolean telling GIMP "whether to add an undo step for the operation".
data method only valid for iterators
The "$region->data" method is only valid for use within an iterator.

These functions take/return not PDL objects, but Perl scalars:

  gimp_gdrawable_get_tile2
  gimp_pixel_rgn_get_col2
  gimp_pixel_rgn_get_rect2
  gimp_pixel_rgn_set_rect2
  gimp_pixel_rgn_get_row2

Ed J, based on "Gimp::Pixel.pod" by Marc Lehmann <pcg@goof.com>

perl(1), Gimp(1), PDL.

These GIMP API docs are also relevant:

<http://developer.gimp.org/api/2.0/libgimp/libgimp-gimppixelrgn.html> <http://developer.gimp.org/api/2.0/libgimp/libgimp-gimpdrawable.html>

2019-04-11 perl v5.32.1

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.