#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''
Copyright: Alexander Hadjiivanov 2010
Licence: GPL
Installation: copy the "batchwork.py" file into your $HOME/.gimp-2.x/plug-ins directory.
On Linux and Mac OSX the file must be executable.
The scripts appear under the <Image>/Tools/Batchwork/ menu entry

Version 1.03
  In Watermark:
    - The text layer is now created directly in the original image, which is faster and saves memory
    - Moved the menu entry to "<Image>/Tools/Batch/Watermark"
    - Added a new type of watermarking which can be used in case the visual impact on the image
      must be minimal

* The bump map technique yields

Version 1.02
  In Watermark:
    - Function names and variable names cleaned up and made consistent
    - Moved the menu entry to "<Image>/Tools/Batch..." in order to bring all scripts under the same hood
    - Added a dropdown option for the file extension
    - Added a special case for "JPG"/"JPEG"
    - The glob is now case-insensitive
  Others:
    - Added a script for batch resizing which is aware of the image orientation

Version 1.01
  - Added an option for choosing the output directory in the Watermark script

Version 1.0
  - Initial release

'''

from gimpfu import *
import os, glob, re
# i18n
import gettext

'''
Batch watermarking with a bump map
Based on the iccii "Texturizer" script (ported from script-fu to python-fu and added a batch mode)
					WARNING
Please double-check whether you have selected the correct output directory. If the
input directory and the output directory are the same, the script will replace the
original files.
'''

locale_directory = gimp.locale_directory
gettext.install( "gimp20-batchwork", locale_directory, unicode=True )

BatchWmBump_help = _("Watermarking of multiple images with a bump map.")
BatchWmBump_description = BatchWmBump_help

def python_fu_batchwm_bump(
  indirectory,
  outdirectory,
  ext,
  angle,
  elevation,
  depth,
  waterlevel,
  ambient,
  fontname,
  copyright):

  if os.path.exists( u''+indirectory ):
    if ext == 0:
      inglobpattern = u''+indirectory + os.sep + '*.' + "[Jj][Pp][Ee][Gg]"
      infilepathnames = glob.glob( inglobpattern )
      inglobpattern = u''+indirectory + os.sep + '*.' + "[Jj][Pp][Gg]"
      infilepathnames.extend(glob.glob( inglobpattern ))
    elif ext==1:
      inglobpattern = u''+indirectory + os.sep + '*.' + "[Gg][Ii][Ff]"
      infilepathnames = glob.glob( inglobpattern )
    elif ext==2:
      inglobpattern = u''+indirectory + os.sep + '*.' + "[Pp][Nn][Gg]"
      infilepathnames = glob.glob( inglobpattern )

    if os.path.exists( u''+outdirectory ):
      if infilepathnames:
	messagebox = pdb.gimp_message_get_handler( )
	pdb.gimp_message_set_handler( 2 ) # send messages in error console
	# Start the process
	for infilepathname in infilepathnames:
	  img = pdb.gimp_file_load( infilepathname, infilepathname )
	  imglayer= img.layers[0]
	  imgwidth = pdb.gimp_image_width(img)
	  imgheight = pdb.gimp_image_height(img)
	# Process the files
	  # Perform some initialisation procedures
	  texture_layer = gimp.Layer(img, _("Texture"), imgwidth,imgheight,RGBA_IMAGE,100,NORMAL_MODE)
	  pdb.gimp_image_undo_disable(img)
	  pdb.gimp_image_add_layer(img,texture_layer, 0)
	  pdb.gimp_drawable_fill(texture_layer, 3)
	  font_size=1

	  # Create the texture layer from the string containing the copyright text
	  textBoxWidth,textBoxHeight,fontAscent,fontDescent = pdb.gimp_text_get_extents_fontname(copyright, font_size, PIXELS, fontname)
	  if imgwidth>imgheight:

	    # Default loop with four textboxes
	    while textBoxWidth < imgwidth/2:
	      font_size=font_size + 1
	      textBoxWidth,textBoxHeight,fontAscent,fontDescent = pdb.gimp_text_get_extents_fontname(copyright, font_size, PIXELS, fontname)

	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,imgheight/3,copyright,0,True,(font_size - 1),PIXELS,fontname)
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,imgwidth/2,imgheight/3,copyright,0,True,(font_size - 1),PIXELS,fontname)
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,5*(imgheight/6),copyright,0,True,(font_size - 1),PIXELS,fontname)
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,imgwidth/2,5*(imgheight/6),copyright,0,True,(font_size - 1),PIXELS,fontname)

	    # Alternative loop for lighter processing - places a single textbox in the middle of the image
	    #while textBoxWidth < imgwidth:
	      #font_size=font_size + 1
	      #textBoxWidth,textBoxHeight,fontAscent,fontDescent = pdb.gimp_text_get_extents_fontname(copyright, font_size, PIXELS, fontname)
	    #texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,imgheight/2,copyright,0,True,(font_size - 1),PIXELS,fontname)

	  else:
	    while textBoxWidth < imgwidth:
	      font_size=font_size + 1
	      textBoxWidth,textBoxHeight,fontAscent,fontDescent = pdb.gimp_text_get_extents_fontname(copyright, font_size, PIXELS, fontname)

	    # Default loop with three textboxes
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,imgheight/6,copyright,0,True,(font_size - 1),PIXELS,fontname)
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,imgheight/2,copyright,0,True,(font_size - 1),PIXELS,fontname)
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,5*(imgheight/6),copyright,0,True,(font_size - 1),PIXELS,fontname)

	    # Alternative loop for lighter processing - places a single textbox in the middle of the image
	    #texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,imgheight/2,copyright,0,True,(font_size - 1),PIXELS,fontname)

	  pdb.gimp_drawable_set_visible(imglayer,False)
	  texture_layer=pdb.gimp_image_merge_visible_layers(img,CLIP_TO_IMAGE)
	  pdb.gimp_drawable_set_visible(imglayer,True)
	  pdb.plug_in_bump_map(img,imglayer,texture_layer,angle,elevation,depth, 0, 0, waterlevel, ambient, True, False, 0)
	  pdb.gimp_image_remove_layer(img,texture_layer)
	  outfilepathname=re.sub(u''+indirectory,u''+outdirectory,infilepathname)
	  pdb.gimp_file_save( img,imglayer,outfilepathname,outfilepathname )
	  pdb.gimp_displays_flush()
	# Give some feedback
	pdb.gimp_message("Watermarking completed successfully!")
	pdb.gimp_message_set_handler( messagebox )
      else:
	pdb.gimp_message( _("There are no files in %s") %(indirectory ) )
    else:
      pdb.gimp_message( _("%s doesn't exist") %(outdirectory) )
  else:
    pdb.gimp_message( _("%s doesn't exist") %(indirectory) )

'''
Batch watermarking with a difference map
Creates a transparent layer with text, which is merged with the original image layer in
the "Soft light" mode. Depending on the opacity of the text layer, the visual impact on
the image is minimal (with the default settings, the watermark is practically
invisible and does not distract the eye even when applied to low-resolution images,
which can not be said for the bump map technique). The copyright text can be extracted
as follows by using the original non-watermarked image as a "key":

0*. Rescale the original ("key") image to the same resolution as the watermarked one
  (skip this step if they are the same size to begin with)
1. Paste the key image as a new layer into the watermarked image
2. Merge down the two layers in the "Difference" mode. What is left is the copyright
  text (plus some noise, depending on the file format)
3. The text is most probably still too faint to read, so boost the levels (Colours/Levels...)
  until the text becomes readable

					WARNING
Please double-check whether you have selected the correct output directory. If the
input directory and the output directory are the same, the script will replace the
original files.
'''

BatchWmDiff_help = _("Watermarking of multiple images with a difference map.")
BatchWmDiff_description = BatchWmDiff_help

def python_fu_batchwm_diff(
  indirectory,
  outdirectory,
  ext,
  opacity,
  fontname,
  copyright):

  if os.path.exists( u''+indirectory ):
    if ext == 0:
      inglobpattern = u''+indirectory + os.sep + '*.' + "[Jj][Pp][Ee][Gg]"
      infilepathnames = glob.glob( inglobpattern )
      inglobpattern = u''+indirectory + os.sep + '*.' + "[Jj][Pp][Gg]"
      infilepathnames.extend(glob.glob( inglobpattern ))
    elif ext==1:
      inglobpattern = u''+indirectory + os.sep + '*.' + "[Gg][Ii][Ff]"
      infilepathnames = glob.glob( inglobpattern )
    elif ext==2:
      inglobpattern = u''+indirectory + os.sep + '*.' + "[Pp][Nn][Gg]"
      infilepathnames = glob.glob( inglobpattern )

    if os.path.exists( u''+outdirectory ):
      if infilepathnames:
	messagebox = pdb.gimp_message_get_handler( )
	pdb.gimp_message_set_handler( 2 ) # send messages in error console
	# Start the process
	for infilepathname in infilepathnames:
	  img = pdb.gimp_file_load( infilepathname, infilepathname )
	  imglayer= img.layers[0]
	  imgwidth = pdb.gimp_image_width(img)
	  imgheight = pdb.gimp_image_height(img)
	# Process the files
	  # Perform some initialisation procedure
	  texture_layer = gimp.Layer(img, _("Texture"), imgwidth,imgheight,RGBA_IMAGE,opacity,SOFTLIGHT_MODE)
	  pdb.gimp_image_undo_disable(img)
	  pdb.gimp_image_add_layer(img,texture_layer, 0)
	  pdb.gimp_drawable_fill(texture_layer, 3)
	  font_size=1

	  # Create the texture layer from the string containing the copyright text
	  textBoxWidth,textBoxHeight,fontAscent,fontDescent = pdb.gimp_text_get_extents_fontname(copyright, font_size, PIXELS, fontname)
	  if imgwidth>imgheight:

	    # Default loop with four textboxes
	    while textBoxWidth < imgwidth/2:
	      font_size=font_size + 1
	      textBoxWidth,textBoxHeight,fontAscent,fontDescent = pdb.gimp_text_get_extents_fontname(copyright, font_size, PIXELS, fontname)

	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,imgheight/3,copyright,0,True,(font_size - 1),PIXELS,fontname)
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,imgwidth/2,imgheight/3,copyright,0,True,(font_size - 1),PIXELS,fontname)
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,5*(imgheight/6),copyright,0,True,(font_size - 1),PIXELS,fontname)
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,imgwidth/2,5*(imgheight/6),copyright,0,True,(font_size - 1),PIXELS,fontname)

	    # Alternative loop for lighter processing - places a single textbox in the middle of the image
	    #while textBoxWidth < imgwidth:
	      #font_size=font_size + 1
	      #textBoxWidth,textBoxHeight,fontAscent,fontDescent = pdb.gimp_text_get_extents_fontname(copyright, font_size, PIXELS, fontname)
	    #texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,imgheight/2,copyright,0,True,(font_size - 1),PIXELS,fontname)

	  else:
	    while textBoxWidth < imgwidth:
	      font_size=font_size + 1
	      textBoxWidth,textBoxHeight,fontAscent,fontDescent = pdb.gimp_text_get_extents_fontname(copyright, font_size, PIXELS, fontname)

	    # Default loop with three textboxes
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,imgheight/6,copyright,0,True,(font_size - 1),PIXELS,fontname)
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,imgheight/2,copyright,0,True,(font_size - 1),PIXELS,fontname)
	    texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,5*(imgheight/6),copyright,0,True,(font_size - 1),PIXELS,fontname)

	    # Alternative loop for lighter processing - places a single textbox in the middle of the image
	    #texture_layer=pdb.gimp_text_fontname( img,texture_layer,0,imgheight/2,copyright,0,True,(font_size - 1),PIXELS,fontname)

	  texture_layer=pdb.gimp_image_flatten(img)

	  outfilepathname=re.sub(u''+indirectory,u''+outdirectory,infilepathname)
	  pdb.gimp_file_save( img,texture_layer,outfilepathname,outfilepathname )
	  pdb.gimp_displays_flush()
	# Give some feedback
	pdb.gimp_message("Watermarking completed successfully!")
	pdb.gimp_message_set_handler( messagebox )
      else:
	pdb.gimp_message( _("There are no files in %s") %(indirectory ) )
    else:
      pdb.gimp_message( _("%s doesn't exist") %(outdirectory) )
  else:
    pdb.gimp_message( _("%s doesn't exist") %(indirectory) )


'''
Batch resizing of images. Automatically detects whether the orientation is landscape
or portrait and resizes the image accordingly. The only input is the new value for the
"long side" of the images, which can be either the width of the height. This ensures,
for example, that the resulting images will fit into a square <div></div> element with
a side equal to the new "long side".
'''

BatchResize_help = _("Watermarking of multiple images.")
BatchResize_description = BatchResize_help

def python_fu_batch_resize(
  indirectory,
  outdirectory,
  ext,
  new_long_side,
  interpolation):

    if os.path.exists( u''+indirectory ):
      if ext == 0:
	inglobpattern = u''+indirectory + os.sep + '*.' + "[Jj][Pp][Ee][Gg]"
	infilepathnames = glob.glob( inglobpattern )
	inglobpattern = u''+indirectory + os.sep + '*.' + "[Jj][Pp][Gg]"
	infilepathnames.extend(glob.glob( inglobpattern ))
      elif ext==1:
	inglobpattern = u''+indirectory + os.sep + '*.' + "[Gg][Ii][Ff]"
	infilepathnames = glob.glob( inglobpattern )
      elif ext==2:
	inglobpattern = u''+indirectory + os.sep + '*.' + "[Pp][Nn][Gg]"
	infilepathnames = glob.glob( inglobpattern )

      if os.path.exists( u''+outdirectory ):
	if infilepathnames:
	  messagebox = pdb.gimp_message_get_handler( )
	  pdb.gimp_message_set_handler( 2 )
	  # Start the process
	  for infilepathname in infilepathnames:

	    img = pdb.gimp_file_load( infilepathname, infilepathname )
	    imglayer= img.layers[0]

	    # Process the files
	    imgwidth = pdb.gimp_image_width(img)
	    imgheight = pdb.gimp_image_height(img)
	    if imgwidth>imgheight:
	      aspect_ratio=float(imgwidth)/float(imgheight)
	      pdb.gimp_image_scale_full(img,new_long_side,int(round(new_long_side/aspect_ratio)),interpolation)
	    else:
	      aspect_ratio=float(imgheight)/float(imgwidth)
	      pdb.gimp_image_scale_full(img,int(round(new_long_side/aspect_ratio)),new_long_side,interpolation)

	    outfilepathname=re.sub(u''+indirectory,u''+outdirectory,infilepathname)

	    pdb.gimp_file_save( img,imglayer,outfilepathname,outfilepathname )
	    pdb.gimp_displays_flush()

	  # Give some feedback
	  pdb.gimp_message("Resizing completed successfully!")
	  pdb.gimp_message_set_handler( messagebox )
	else:
	  pdb.gimp_message( _("There are no files in %s") %(indirectory ) )
      else:
	pdb.gimp_message( _("%s doesn't exist") %(outdirectory) )
    else:
      pdb.gimp_message( _("%s doesn't exist") %(indirectory) )


# Register all plugins

register(
   "python-fu-batchwm-bump",
   BatchWmBump_description,
   BatchWmBump_help,
   "Alexander Hadjiivanov",
   "GPL License",
   "2010",
   _("Bump map"),
   "",
   [
      (PF_DIRNAME, "indirectory", _("Input Directory"), os.getcwd() ),
      (PF_DIRNAME, "outdirectory", _("Output Directory"), os.getcwd() ),
      (PF_OPTION, "ext", _("Extension"), 0, ["JPEG", "GIF", "PNG"]),
      (PF_SPINNER, "angle", _("Angle"), 135, (0,360,1)),
      (PF_SPINNER, "elevation", _("Elevation"), 40, (0.5,90,0.5)),
      (PF_SPINNER, "depth", _("Depth"), 5, (1,65,1)),
      (PF_SPINNER, "waterlevel", _("Waterlevel"), 30, (0,255,1)),
      (PF_SPINNER, "ambient", _("Ambient"), 5, (0,255,1)),
      (PF_FONT, "fontname", _("Font"), "Sans"),
      (PF_STRING, "copyright", _("Copyright info"), "© your_copyright_info"),
   ],
   [],
   python_fu_batchwm_bump,
   menu="<Image>/Tools/Batchwork/Watermark...",
   domain=( "gimp20-batchwork", locale_directory)
   )

register(
   "python-fu-batchwm-diff",
   BatchWmDiff_description,
   BatchWmDiff_help,
   "Alexander Hadjiivanov",
   "GPL License",
   "2010",
   _("Difference map"),
   "",
   [
      (PF_DIRNAME, "indirectory", _("Input Directory"), os.getcwd() ),
      (PF_DIRNAME, "outdirectory", _("Output Directory"), os.getcwd() ),
      (PF_OPTION, "ext", _("Extension"), 0, ["JPEG", "GIF", "PNG"]),
      (PF_SPINNER, "opacity", _("Opacity"), 5, (0,100,0.1)),
      (PF_FONT, "fontname", _("Font"), "Sans"),
      (PF_STRING, "copyright", _("Copyright info"), "© your_copyright_info"),
   ],
   [],
   python_fu_batchwm_diff,
   menu="<Image>/Tools/Batchwork/Watermark...",
   domain=( "gimp20-batchwork", locale_directory)
   )

register(
   "python-fu-batch-resize",
   BatchResize_description,
   BatchResize_help,
   "Alexander Hadjiivanov",
   "GPL License",
   "2010",
   _("Resize"),
   "",
   [
      (PF_DIRNAME, "indirectory", _("Input Directory"), os.getcwd() ),
      (PF_DIRNAME, "outdirectory", _("Output Directory"), os.getcwd() ),
      (PF_OPTION, "ext", _("Extension"), 0, ["JPEG", "GIF", "PNG"]),
      (PF_SPINNER, "new_long_side", _("New long side (px):"), 640, (10, 3000, 1)),
      (PF_OPTION, "interpolation", _("Interpolation"), 3, ["None", "Linear", "Cubic", "Lanczos"]),
   ],
   [],
   python_fu_batch_resize,
   menu="<Image>/Tools/Batchwork",
   domain=( "gimp20-batchwork", locale_directory)
   )


main()

