home *** CD-ROM | disk | FTP | other *** search
/ PC Extra 07 & 08 / pca1507.iso / Software / psp8 / Data1.cab / EXIFCaptioning.PspScript < prev    next >
Encoding:
Text File  |  2003-04-22  |  9.5 KB  |  217 lines

  1. from JascApp import *
  2. import string
  3. import JascUtils
  4.  
  5. def ScriptProperties():
  6.     return {
  7.         'Author': 'Joe Fromm',
  8.         'Copyright': 'Copyright (C) 2002-2003, Jasc Software Inc., All Rights Reserved. Permission to create derivate works of this script is granted provided this copyright notice is included',
  9.         'Description': 'Put EXIF camera and exposure information at the bottom of the image.',
  10.         'Host': 'Paint Shop Pro 8',
  11.         'Host Version': '8.00'
  12.         }
  13.  
  14.         
  15. def Do(Environment):
  16.     ''' This script extracts data from the active document to place a caption at the lower right corner
  17.         of the image.  The caption contains the camera make/model number, aperture and exposure time.
  18.         This does require that the image contain this information to being with - if no EXIF data is
  19.         found it puts up a message box and returns.
  20.  
  21.         The text is placed at the bottom right corner of the image.  To make it easier to read, the area
  22.         around the text is filled with a dark gray.
  23.  
  24.         To isolate the caption and backdrop from the rest of the image, a layer group is created.
  25.         Following execution of the script, three additional layers will be created, placed above the
  26.         layer that was active when the script was run:
  27.         EXIF Caption - the group layer
  28.           EXIF Text - this is a vector layer containing the text we created
  29.           Caption Background - this is a raster layer that is filled with grey around the text
  30.     '''
  31.     if JascUtils.RequireADoc( Environment ) == App.Constants.Boolean.false:
  32.         return
  33.  
  34.     
  35.     # first extract the EXIF data - if we can't find any just return without changing the image
  36.     ImageInfo = App.Do( Environment, 'ReturnImageInfo' )
  37.     if ImageInfo['ExifMake'] == '' or ImageInfo['ExifModel'] == '' or \
  38.        ImageInfo['ExifFNumber' ] == '' or ImageInfo['ExifExposureTime'] == '':
  39.         App.Do(Environment,  'MsgBox', {
  40.                 'Buttons': App.Constants.MsgButtons.OK, 
  41.                 'Icon': App.Constants.MsgIcons.Stop, 
  42.                 'Text': 'No EXIF data found on the current image.', 
  43.                 })
  44.         return
  45.  
  46.  
  47.     # save any existing selection
  48.     SelSaver = JascUtils.SaveSelection( Environment, App.TargetDocument )
  49.     
  50.     # assemble the camera string by concatenating the camera make and model.  Some camera
  51.     # manufacturers have the barbaric practice of CAPITALIZING everything in their make and model
  52.     # strings, so convert it to initial caps only for a more civilized appearance
  53.     CaptionTextCamera = unicode(string.capwords( ImageInfo['ExifMake'] + ' ' + ImageInfo[ 'ExifModel' ] ))
  54.     
  55.     # now assemble exposure information by using the aperture and exposure
  56.     Aperture = float(ImageInfo['ExifFNumber'])
  57.     CaptionTextExposure = u'f/%g aperture, %s exposure' % (Aperture, ImageInfo['ExifExposureTime'].strip())
  58.  
  59.     # first we create a raster layer at 50% opacity as a backdrop for the caption    
  60.     # for now the raster layer is empty - we'll fill it in later
  61.     # the new layer becomes the active layer
  62.     App.Do( Environment, 'NewRasterLayer', {
  63.             'General': {
  64.                 'Opacity': 50, 
  65.                 'Name': 'Caption Background', 
  66.                 'IsVisible': App.Constants.Boolean.true, 
  67.                 }, 
  68.             'GeneralSettings': {
  69.                 'ExecutionMode': App.Constants.ExecutionMode.Silent, 
  70.                 }
  71.             })
  72.     
  73.     # create a layer group.  This will place the raster layer in the group
  74.     # the group is the active layer on completion
  75.     App.Do( Environment, 'NewLayerGroup', {
  76.             'General': {
  77.                 'Opacity': 100, 
  78.                 'Name': 'EXIF Caption', 
  79.                 }, 
  80.             'GeneralSettings': {
  81.                 'ExecutionMode': App.Constants.ExecutionMode.Silent, 
  82.                 }
  83.             })
  84.  
  85.     # select the raster layer so that the vector layer gets created above it
  86.     App.Do( Environment, 'SelectLayer', {
  87.             'Path': (0,0,[1],App.Constants.Boolean.false), 
  88.             })
  89.     
  90.     # now create a vector layer to put text on - creating the layer will make it active
  91.     App.Do( Environment, 'NewVectorLayer', {
  92.             'General': {
  93.                 'Opacity': 100, 
  94.                 'Name': 'EXIF Text', 
  95.                 }, 
  96.             'GeneralSettings': {
  97.                 'ExecutionMode': App.Constants.ExecutionMode.Silent, 
  98.                 }
  99.             })
  100.  
  101.     # Figure out how big the text should be by examining the overall image size.  We'll do a rough
  102.     # scale based on 1000 pixels.  We won't paint text less than 16 point in any event.
  103.     ImageMaxDimension = max(App.TargetDocument.Width, App.TargetDocument.Height)
  104.     TextScaleFactor = max(0.25, float(ImageMaxDimension) / 1000.0)
  105.     TextSize = int(16.0 * TextScaleFactor)
  106.  
  107.     # now place the text - use right justification at the lower right corner of the image.
  108.     # we are placing 16 pixel text, so to leave some room for leading we place the first
  109.     # line of text 24 pixels up from the bottom, and the second will be only 4 pixels up
  110.     # from the bottom.
  111.     # since we use a black backdrop for the text, make the text color white.
  112.     TextPlacementLine1 = (App.TargetDocument.Width - 4 * TextScaleFactor, App.TargetDocument.Height - (24 * TextScaleFactor))
  113.     App.Do( Environment, 'Text', {
  114.             'CreateAs': App.Constants.CreateAs.Vector, 
  115.             'Segments': [{
  116.                 'Fill': {
  117.                     'Color': (255,255,255), 
  118.                     'Pattern': None, 
  119.                     'Gradient': None, 
  120.                     'Texture': None
  121.                     }, 
  122.                 'Font': 'Arial', 
  123.                 'PointSize': TextSize, 
  124.                 'Start': TextPlacementLine1, 
  125.                 'Stroke': None,
  126.                 'LineStyle': None,
  127.                 'LineWidth':0,
  128.                 'SetText': App.Constants.Justify.Right, 
  129.                 },{
  130.                 'Characters': CaptionTextCamera
  131.                 }], 
  132.             'FinalApply': App.Constants.Boolean.false, 
  133.             'GeneralSettings': {
  134.                 'ExecutionMode': App.Constants.ExecutionMode.Silent, 
  135.                 'AutoActionMode': App.Constants.AutoActionMode.Match
  136.                 }
  137.             })
  138.  
  139.     # place the second line of text
  140.     TextPlacementLine2 = (App.TargetDocument.Width - 4 * TextScaleFactor, App.TargetDocument.Height - (4 * TextScaleFactor) )
  141.     App.Do( Environment, 'Text', {
  142.             'CreateAs': App.Constants.CreateAs.Vector, 
  143.             'Segments': [{
  144.                 'Fill': {
  145.                     'Color': (255,255,255), 
  146.                     'Pattern': None, 
  147.                     'Gradient': None, 
  148.                     'Texture': None,
  149.                     }, 
  150.                 'Font': 'Arial', 
  151.                 'PointSize': TextSize, 
  152.                 'Start': TextPlacementLine2, 
  153.                 'Stroke': None,
  154.                 'LineStyle': None,
  155.                 'LineWidth':0,
  156.                 'SetText': App.Constants.Justify.Right, 
  157.                 },{
  158.                 'Characters': CaptionTextExposure
  159.                 }], 
  160.             'FinalApply': App.Constants.Boolean.false, 
  161.             'GeneralSettings': {
  162.                 'ExecutionMode': App.Constants.ExecutionMode.Silent, 
  163.                 'AutoActionMode': App.Constants.AutoActionMode.Match
  164.                 }
  165.             })
  166.  
  167.     # we have the text down, but we want to put a backdrop behind it so that the text remains
  168.     # visible.  How big do we make the backdrop?  Who knows, so we just ask the vector layer how
  169.     # big it is
  170.     Result = App.Do( Environment, 'ReturnLayerProperties' )
  171.     TextRectangle = Result[ 'LayerRect' ]
  172.     FillStartPoint = ( TextRectangle[0][0] - (4 * TextScaleFactor), TextRectangle[0][1] - (4 * TextScaleFactor) )
  173.     FillEndPoint = ( App.TargetDocument.Width, App.TargetDocument.Height )
  174.     
  175.     # select the raster layer - it is immediately below the vector layer
  176.     App.Do( Environment, 'SelectLayer', {
  177.             'Path': (0,-1,[],App.Constants.Boolean.false), 
  178.             })
  179.  
  180.     # make a selection around the bounding box of the text.  Once we have a selection we'll fill it
  181.     App.Do( Environment, 'Selection', {
  182.             'General': {
  183.                 'Mode': App.Constants.SelectionOperation.Replace, 
  184.                 'Antialias': App.Constants.Boolean.true, 
  185.                 'Feather': 0
  186.                 }, 
  187.             'SelectionShape': App.Constants.SelectionShape.Rectangle, 
  188.             'Start': FillStartPoint, 
  189.             'End': FillEndPoint, 
  190.             'GeneralSettings': {
  191.                 'ExecutionMode': App.Constants.ExecutionMode.Silent
  192.                 }
  193.             })
  194.  
  195.     # now do a flood fill, making sure the point we click on is inside of our selection
  196.     # use a dark grey for the fill so that we can see the text on top of it
  197.     App.Do( Environment, 'Fill', {
  198.             'BlendMode': 0, 
  199.             'MatchMode': 1, 
  200.             'Material': {
  201.                 'Color': (32,32,32), 
  202.                 'Pattern': None, 
  203.                 'Gradient': None, 
  204.                 'Texture': None
  205.                 }, 
  206.             'Opacity': 100, 
  207.             'Point': (FillStartPoint[0] + 1, FillStartPoint[1] + 1), 
  208.             'Tolerance': 20, 
  209.             'GeneralSettings': {
  210.                 'ExecutionMode': App.Constants.ExecutionMode.Silent
  211.                 }
  212.             })
  213.  
  214.     # restore the original selectoin
  215.     SelSaver.RestoreSelection()
  216.     
  217.     # All done!