#!/local/bin/perl5.8.5 # # Add a digital matte to an image # # File: add_matte # # Author: Nem W Schlecht # Copyright © 2003 NDSU Libraries # # Creation Date: Jun 10, 2003 # Last Modification: Jun 13, 2003 # # Jun 13, 2003 # - Version 1.0 completed # use Gimp qw(:auto __ N_); use Gimp::Fu; use Gimp::Util; use strict; register "add_matte", # fill in name "Add a matte border w/ signature", # a small description "Add a matte border w/ signature", # a help text "Nem Schlecht", # Your name "Nem Schlecht (c)", # Your copyright "2003-06-10", # Date N_"/Filters/Render/Add Matte", # menu path "RGB*", # Image types [ [PF_TOGGLE, "merge_layers", "Merge Layers", 1], [PF_TOGGLE, "dual_matte", "Dual matte", 1], [PF_RADIO, "light_source", "Light Source", 0, [Top => 0, Left => 1, Right => 2, Bottom => 3]], [PF_FLOAT, "inner_matte_size_perc","Inner Matte Size (%)", 4], [PF_RADIO, "inner_fill_type", "Inner Fill Type", 0, [Color => 0, Pattern => 1, Gradient => 2]], [PF_COLOR, "inner_matte_color", "Inner Matte Color", [0,0,0]], [PF_PATTERN,"inner_matte_pattern", "Inner Matte Pattern", 'Granite #1'], [PF_GRADIENT,"inner_matte_gradient","Inner Matte Gradient", 'Default'], [PF_FLOAT, "gradient_repeat", "Gradient Repeat", 1], [PF_RADIO, "gradient_direction", "Gradient Direction", 0, ['UL->BR' => 0, 'UR->BL' => 2, 'L->R' => 4, 'U->B' => 6]], [PF_TOGGLE, "gradient_direction_rev", "Reverse Gradient Direction", 0], [PF_INT, "inner_cut_size", "Inner Cut Size", 5], [PF_COLOR, "inner_cut_color", "Inner Cut color", [220,220,200,1]], [PF_RADIO, "outer_fill_type", "Outer Fill Type", 0, [Color => 0, Pattern => 1, Gradient => 2]], [PF_COLOR, "outer_matte_color", "Outer Matte Color", [255,255,245]], [PF_PATTERN,"outer_matte_pattern", "Outer Matte Pattern", 'Marble #1'], [PF_GRADIENT,"outer_matte_gradient","Outer Matte Gradient", 'Default'], [PF_FLOAT, "gradient_repeat", "Gradient Repeat", 1], [PF_RADIO, "gradient_direction", "Gradient Direction", 0, ['UL->BR' => 0, 'UR->BL' => 2, 'L->R' => 4, 'U->B' => 6]], [PF_TOGGLE, "gradient_direction_rev", "Reverse Gradient Direction", 0], [PF_INT, "outer_cut_size", "Outer Cut Size", 5], [PF_COLOR, "outer_cut_color", "Outer Cut color", [220,220,200,1]], [PF_TOGGLE, "add_signature", "Add Signature", 1], [PF_BRUSH, "signature_brush", "Signature Brush", 'Property of XCF!'], [PF_COLOR, "brush_color", "Brush Color", [0,0,0]], [PF_TOGGLE, "add_title", "Add Title", 1], [PF_STRING, "title_text", "Title text", ''], [PF_FONT, "title_font", "Font", 'helvetica Medium 24'], [PF_COLOR, "title_color", "Title Color", [0,0,0]], [PF_RADIO, "title_location", "Title Location", 0, ['Top' => 0, 'Bottom' => 1]], [PF_RADIO, "title_align", "Title Alignment", 1, ['Left', => 0, 'Center' => 1, 'Right' => 3]], ], \&matteborder; sub matteborder { my ($img, $layer, $merge, $dual, $direction, $isize, $iftype, $icolor, $ipat, $igrad, $igcnt, $igdir, $igdrev, $icsize, $iccolor, $oftype, $ocolor, $opat, $ograd, $ogcnt, $ogdir, $ogdrev, $ocsize, $occolor, $addsig, $brush, $bcolor, $addtit, $tittext, $titfont, $titcol, $titloc, $titalign ) = @_; # fix isize $isize = $isize / 100; # check for reverse gradient direction if ($igdrev == 1) { ++$igdir; } if ($ogdrev == 1) { ++$ogdir; } my $cutdel = 35; my $ow = gimp_image_width($img); my $oh = gimp_image_height($img); my $ims = int(($ow > $oh ? $oh : $ow) * $isize); gimp_undo_push_group_start($img); if ($dual == 1) { my $nl; if ($icsize > 0) { # print "adding inner cut\n"; $nl = addborder($img, $layer, $icsize, $icsize, $iccolor, 0, 0, 0, $cutdel, $direction, $merge == 1 ? "Matte" : "Inner Matte Cut"); } if ($iftype == 1) { $icolor = $ipat; } elsif ($iftype == 2) { $icolor = $igrad; } # print "adding inner matte\n"; $nl = addborder($img, $layer, $ims, $ims, $icolor, $iftype, $igcnt, $igdir, 0, 0, "Inner Matte"); if ($icsize > 0) { gimp_image_merge_down($img, $nl, EXPAND_AS_NECESSARY) if ($merge == 1); } } my $nl; # # Add outer cut if ($ocsize > 0) { # print "adding outer cut\n"; $nl = addborder($img, $layer, $ocsize, $ocsize, $occolor, 0, 0, 0, $cutdel, $direction, "Outer Matte Cut"); gimp_image_merge_down($img, $nl, EXPAND_AS_NECESSARY) if ($merge == 1); } if ($oftype == 1) { $ocolor = $opat; } elsif ($oftype == 2) { $ocolor = $ograd; } # # Create title layer my($tw, $th); if ($addtit == 1) { my($ascent, $descent); my $fsize = (split / /,$titfont)[-1]; ($tw, $th, $ascent, $descent) = gimp_text_get_extents_fontname($tittext || "Title", $fsize, POINTS, $titfont); } if ($addsig == 1 || $addtit == 1) { my ($bn, $bo, $bs, $bpm, $bw, $bh, $bl, $bmd) = gimp_brushes_get_brush_data($brush); my $nbw; my $nbh; if ($bw < $bh) { $nbw = $bw+15; $nbh = $bh/2; $nbh = $th+15 if ($th > $bh); } else { $nbw = $bw/2; $nbh = $bh+15; } $nbh = $th+15 if ($th > $bh); # print "adding outer matte\n"; $nl = addborder($img, $layer, $nbw, $nbh, $ocolor, $oftype, $ogcnt, $ogdir, 0, 0, "Outer Matte"); gimp_image_merge_down($img, $nl, EXPAND_AS_NECESSARY) if ($merge == 1); $nl = addsign($img, $layer, $brush, $bcolor, $nbw, $nbh); gimp_image_merge_down($img, $nl, EXPAND_AS_NECESSARY) if ($merge == 1); } else { my $ims = (($ow > $oh ? $oh : $ow) * ($isize))*3; # print "adding outer matte\n"; $nl = addborder($img, $layer, $ims, $ims, $ocolor, $oftype, $ogcnt, $ogdir, 0, 0, "Outer Matte"); gimp_image_merge_down($img, $nl, EXPAND_AS_NECESSARY) if ($merge == 1); } if ($addtit == 1) { my $nw = gimp_image_width($img); my $nh = gimp_image_height($img); my $fsize = (split / /,$titfont)[-1]; my $ofg = gimp_palette_get_foreground(); gimp_palette_set_foreground($titcol); my $tl = $img->gimp_text_fontname(-1, # layer 0, # x coord 0, # y coord $tittext || "Title", # text string 0, # border 1, # antialias $fsize, # font size POINTS, # PNTS/PIX $titfont); # font name ($tw,$th) = ($tl->width, $tl->height); my $tx; my $ty; if ($titloc == 0) { # top $ty = 8; } elsif ($titloc == 1) { # bottom $ty = (($nh - 8) - $th); } elsif ($titloc == 2) { # left } elsif ($titloc == 3) { # right } if ($titalign == 0) { # left $tx = 8; } elsif ($titalign == 1) { # center $tx = ($nw/2) - ($tw/2); } elsif ($titalign == 2) { # right $tx = (($nw - 8) - $tw); } $tl->gimp_layer_resize($tw, $th, 0, 0); $tl->gimp_layer_set_offsets($tx, $ty); # gimp_image_merge_down($img, $ntl, EXPAND_AS_NECESSARY) if ($merge == 1); } gimp_undo_push_group_end($img); gimp_displays_flush(); return(); } sub addsign { my ($img, $layer, $brush, $bcolor, $nbw, $nbh) = @_; my $w = gimp_image_width($img); my $h = gimp_image_height($img); my $nl = gimp_layer_new($img, $w, $h, RGBA_IMAGE, "Signature", 100, NORMAL_MODE); gimp_drawable_fill($nl, TRANSPARENT_FILL); my ($cbn, $cbw, $cbh, $cbs) = gimp_brushes_get_brush(); my $ofg = gimp_palette_get_foreground(); my ($bn, $bo, $bs, $bpm, $bw, $bh, $bl, $bmd) = gimp_brushes_get_brush_data($brush); gimp_brushes_set_brush($brush); gimp_palette_set_foreground($bcolor); gimp_paintbrush($nl, 0, 1, [($w - ($bw/2) - ($bw*.1)), ($h - ($bh/2) - ($bh*.1))], 0, 0); gimp_brushes_set_brush($cbn); gimp_palette_set_foreground($ofg); $nl->gimp_image_add_layer(-1); return $nl; } sub addborder { my ($img, $layer, $xsize, $ysize, $color, $ftype, $gcnt, $gdir, $delta, $direction, $name) = @_; my $owidth = gimp_image_width($img); my $oheight = gimp_image_height($img); # print "width: $owidth\n"; # print "height: $oheight\n"; my $obgpat; if ($ftype == 0) { $obgpat = gimp_palette_get_background(); } elsif ($ftype == 1) { my $j; ($obgpat,$j,$j) = gimp_patterns_get_pattern(); gimp_patterns_set_pattern($color); } elsif ($ftype == 2) { $obgpat = gimp_gradients_get_active(); gimp_gradients_set_active($color); } my($delta1,$delta2,$delta3,$delta4); if ($direction == 0) { # top $delta1 = (0-$delta); # top $delta2 = (0-($delta/2)); # left $delta3 = ($delta/2); # right $delta4 = $delta; # bottom } elsif ($direction == 1) { # left $delta1 = (0-($delta/2)); # top $delta2 = (0-$delta); # left $delta3 = $delta; # right $delta4 = ($delta/2); # bottom } elsif ($direction == 2) { # right $delta1 = ($delta/2); # top $delta2 = $delta; # left $delta3 = (0-$delta); # right $delta4 = (0-($delta/2)); # bottom } elsif ($direction == 3) { # bottom $delta1 = $delta; # top $delta2 = ($delta/2); # left $delta3 = (0-($delta/2)); # right $delta4 = (0-$delta); # bottom } my $width = ($owidth + (2*$xsize)); my $height = ($oheight + (2*$ysize)); gimp_image_resize($img, $width, $height, $xsize, $ysize); my $nl = gimp_layer_new($img, $width, $height, RGBA_IMAGE, "$name", 100, NORMAL_MODE); gimp_drawable_fill($nl, TRANSPARENT_FILL); # top border gimp_free_select($img, 10, [0,0, $xsize, $ysize, ($width-$xsize), $ysize, $width, 0, 0,0], CHANNEL_OP_REPLACE, 0, 0, 0); do_cur_fill($nl, $ftype, $color, $delta1, $gcnt, $gdir); # left border gimp_free_select($img, 10, [0,0, $xsize, $ysize, $xsize, ($height-$ysize), 0, $height, 0,0], CHANNEL_OP_REPLACE, 0, 0, 0); do_cur_fill($nl, $ftype, $color, $delta2, $gcnt, $gdir); # right border gimp_free_select($img, 10, [$width,0, ($width-$xsize), $ysize, ($width-$xsize), ($height-$ysize), $width, $height, $width,0], CHANNEL_OP_REPLACE, 0, 0, 0); do_cur_fill($nl, $ftype, $color, $delta3, $gcnt, $gdir); # bottom border gimp_free_select($img, 10, [0, $height, $xsize, ($height-$ysize), ($width-$xsize), ($height-$ysize), $width, $height, 0, $height], CHANNEL_OP_REPLACE, 0, 0, 0); do_cur_fill($nl, $ftype, $color, $delta4, $gcnt, $gdir); # # Resets gimp_selection_none($img); if ($ftype == 0) { gimp_palette_set_background($obgpat); } elsif ($ftype == 1) { gimp_patterns_set_pattern($obgpat); } elsif ($ftype == 2) { $obgpat = gimp_gradients_set_active($obgpat); } $nl->gimp_image_add_layer(-1); return $nl; } sub do_cur_fill { my $nl = shift; my $ftype = shift; my $color = shift; my $delta = shift; my $gcnt = shift; my $gdir = shift; if ($ftype == 0) { my $ncol = adj_color($color, $delta); gimp_palette_set_background($ncol); gimp_edit_fill($nl, BACKGROUND_FILL); } elsif ($ftype == 1) { gimp_bucket_fill($nl, 2, 0, 100, 0, 0, 0, 0); } elsif ($ftype == 2) { my $ow = $nl->gimp_drawable_width(); my $oh = $nl->gimp_drawable_height(); my $gw = sprintf "%.3f", $ow * (1/$gcnt); my $gh = sprintf "%.3f", $oh * (1/$gcnt); my @coords; if ($gdir == 0) { @coords = (0,0,$gw,$gh); # UL->BR } elsif ($gdir == 1) { @coords = ($ow,$oh,($ow-$gw),($oh-$gh)); # BR->UL } elsif ($gdir == 2) { @coords = ($ow,0,($ow-$gw),$gh); # UR->BL } elsif ($gdir == 3) { @coords = (0,$oh,$gw,($oh-$gh)); # BL->UR } elsif ($gdir == 4) { @coords = (0,0,$gw,0); # L->R } elsif ($gdir == 5) { @coords = ($ow,0,($ow-$gw),0); # R->L } elsif ($gdir == 6) { @coords = (0,0,0,$gh); # U->B } elsif ($gdir == 7) { @coords = (0,$oh,0,($oh-$gh)); # B->U } $nl->gimp_blend( CUSTOM_MODE, # blend mode NORMAL_MODE, # paint mode GRADIENT_LINEAR, # type 100, # opacity 0, # offset REPEAT_TRIANGULAR, # repeat type 0, # reverse 0, # supersample 0, # max_depth for super 0, # super thresh. 0, # dithering @coords, ); } } sub adj_color { my $cref = shift; my $delta = shift; $delta = $delta/255; my(@nc); for (@$cref) { my $cc = $_; $cc += $delta; $cc = 0 if ($cc < 0); $cc = 1 if ($cc > 1); push(@nc, $cc); } $nc[3]=1; return \@nc; } exit main();