Old Dogs

The eyeI’ve been developing software since the days of the Apple II. Back then everyone who used a microcomputer had to know something about how software worked. Most people just wanted to use VisiCalc or play games on those early machines but a few of us were fascinated by the technology. I can tell you the exact day I became a programmer. It was Thanksgiving Day 1979. After a marathon twenty hour session learning MS BASIC I could code. It was such a rush.

From that early day I started writing code for money and continued to do so until a couple of years ago. Suddenly after I turned sixty it was like someone turned off the light. Software developers are young and I was not young. Over the years I had opportunities to become a manager but the code always spoke to me. So I became an ex software developer.

Now after some time has passed it seems that code still speaks to me. In fact I have begun to recapture some of the excitement that I felt in the early days. I no longer have endless meetings, pressing deadlines or code reviews. Now I get to write code to make the machine personal again. My projects are small and completely non-commercial. Most run on my desktop machine but I dabble a bit with mobile Android stuff.

A few months ago I put together an application to generate PDF calendar sets and web ready images. My idea was to be able to take a finished full sized photograph and generate several sizes of images for publishing online along with two different calendars types in encrypted PDF format. This has worked extremely well. I can now generate all the image content for a post on phototrice.com in a few seconds with no hand work.

My old habits have also served me well in that I continue to write reusable object code. This has come in handy for my latest project creating photo mosaic images. This project highlights the differences between makers of things and consumers of things. It would be simple and faster to pay a few bucks to buy some photo mosaic software. It would be simple and boring that is. It is better for me to build the software and learn something new.

To that end I am finishing up the first phase of the project which consists of discovering images, cataloging and producing graphic tiles. There are lots of ways to accomplish this task. I decided to leverage my existing code from the calendar project to automate Photoshop to do the imaging work and use a Sqlite database to manage the cataloging. Works like a charm.

I’m really looking forward to the next phase which is actually creating the mosaic images. I will be writing code using the .Net framework rather than automating Photoshop to accomplish this. It is the interesting part for me. I have done quite a bit of document imaging work over the years but not much actual graphics programming. It should be fun. So in a few weeks you may see some really bad photo mosaic images here on phototrice.com.

Scripting a Calendar Generator

A couple of weeks ago I wrote a post about my Photoshop automation project for generating single page photo calendars. Phototrice includes a new calendar every week as part of our regular Friday Photo feature. Actually two calendars are produced every week with North America and international weekday formats. Creating two calendars a week is not all that labor intensive but creating two calendars fifty two times a year is something worth automating. The coding on the calendar generator was completed about a week ago. I used it to generate last week’s Friday Photo calendars without a hitch.

This project was put together using Visual Studio 2015 and VB.Net. As mentioned in the last post, external automation provides many more options for integrating functionality that cannot or should not be scripted to run directly in Photoshop. Of course this approach limits me to running under Windows but that is what I use anyway. Future projects will likely be coded in JavaScript or ExtendScript to make them platform independent.

The application GUI is quite simple. I can enter all necessary information and kick off the generator which is about all that is required. A SQLite database is used to store various kinds of information for the generator. Right now configuration and logging data are the primary items stored. Eventually it will contain all information and images required to create any previous calendar. This will be useful for my yearly compilation of calendar images in book form.

Calendar Generator GUI
Calendar Generator GUI

The application lends itself quite easily to other uses where templates and dynamic data are combined to produce finished documents. Right now I’m working on a series of custom postcard templates which will also use the generator. Table driven configuration allows for great flexibility in layout and template selection. Coding was done using normal object oriented techniques. This allows me to extend or repurpose functionality as necessary.

Calendar generator configuration table
Calendar generator configuration table

This is the first time I have created code to script or automate Photoshop. I have learned some very useful things about how Photoshop operates by analyzing the API model. That information gives me insight into how to accomplish various tasks with or without scripting. The experience of writing code for Photoshop has been good overall. The documentation is accurate and detailed which is not always the case many application API’s. I expect to build other useful scripts in the months ahead. Hopefully I can make scripts available on Phototrice at some point. Anyway that is my goal.

Photoshop Scripting and Automation

The eyeOne of the nice features of many Adobe applications is the ability to automate repetitive or highly detailed sequences of tasks. The simple solution of using actions is more than enough for most purposes but sometimes you need more flexibility. That is where scripting can be useful. The obvious choice for running scripts within an Adobe application is ExtendScript or javascript. VBScript is also supported in Photoshop but it is probably not the best choice all around.

Simple External Automation

There is another option for using Photoshop functionality that I will be talking about here. If you are running Windows you can automate Photoshop and some other Adobe applications with OLE automation objects. This opens up possibilities for using Photoshop functionality within applications using general purpose programming languages such as C# or VB.Net. Ole Automation only makes sense if you have a need to combine Photoshop capabilities and other functionality that is not easily available within Photoshop. For instance, if you plan to use SQL Server or SQLlite along with image processing then building scripts that run entirely within Photoshop is probably not the best option. The application I describe is a standalone Windows desktop app built using Visual Studio 2015, VB.Net and SQLite.

Here is a small code snippet from my PSAuto class to give you a sense of how OLE automation might be done in VB.Net. The code uses Photoshop references that were added to the working project. These references must be added to allow Photoshop functionality to be accessed within Dot Net. This is just one possible approach that could be used for automation.

Imports Photoshop

    Public Structure pDocInfo
        Public _title As String
        Public _author As String
        Public _authPos As String
        Public _capt As String
        Public _captionWrtr As String
        Public _keywords As String
        Public _copyrighted As PsCopyrightedType
        Public _copyrightNotice As String
        Public _ownerURL As String
    End Structure

	Private Function doCreatPsApp() As Application
		If _psApp Is Nothing Then
			_psApp = New Application()
			_psApp.DisplayDialogs = PsDialogModes.psDisplayNoDialogs
		End If
		Return _psApp
	End Function

	Private Function doOpenPSDoc(ByVal path As String) As Document
		Dim psdoc As Document = Nothing

		Try
			Dim psapp As Application = doCreatPsApp()
			psdoc = psapp.Open(path)
		Catch ex As Exception
			Throw
		End Try

		Return psdoc
	End Function

    Public Function PopulateDocInfo(ByVal doc As Document, ByVal dinfo As pDocInfo) As Document
        doc.Info.Title = dinfo._title
        doc.Info.Author = dinfo._author
        doc.Info.AuthorPosition = dinfo._authPos
        doc.Info.Caption = dinfo._capt
        doc.Info.CaptionWriter = dinfo._captionWrtr
        doc.Info.Keywords = dinfo._keywords
        doc.Info.Copyrighted = dinfo._copyrighted
        doc.Info.CopyrightNotice = dinfo._copyrightNotice
        doc.Info.OwnerUrl = dinfo._ownerURL
        Return doc
    End Function
Building Calendars

Over the past few months I have been publishing calendar downloads on my blog with a new featured photograph every week. I release two versions of each calendar with North America or international week formatting. The difference being that one has weekdays starting on Sunday and the other Monday. Each calendar includes a 5×7 high resolution image at 300ppi in horizontal or vertical orientation. My approach to creating calendars is to use .psd files of static calendar content as templates. New images and text are then added and secure PDF documents are generated.

Here is the process for publishing the calendars and blog post images:

  • Select the featured image for the week
  • Add file and copyright information to the source image file
  • Export a version of the image having a horizontal dimension of 600 pixels or less for publishing online in the blog post
  • Create a 5×7 300ppi version of the image in horizontal or vertical format for the weekly calendars
  • Open Photoshop and load the appropriate North America and international calendar templates
  • Insert the photo into each template as a layer
    • Position the photo in the template
    • Edit image title text
    • Position the image title text relative to the image
  • Publish the completed calendars as secure PDF documents
  • Move finished documents to output folders
  • Write a blog post to discuss the image
Advantages of Automation

The steps outlined above are repetitive and tedious work. Just the kind of thing the computer should handle for a user. The entire workflow for creating PDF calendars and blog post images can be automated with a little work. The process can also easily be driven by information stored in a database using something like SQLite. The database can store everything including calendar templates, original source images, logo images, copyright information, titles, text data, calendar layout configurations, processing logs, etc. The user need only select a source image and enter some text fields. The application handles all aspects of document creation and information storage autonomously. The whole process takes a few seconds at most. Using a data driven approach also allows previous documents to be regenerated on demand.

My application is around 80% complete as of now. The prototype app can select and size images, add standard and image specific file/copyright information, load appropriate calendar templates, modify text content and add images as layers to the calendar templates. All information is stored in a local SQLite database. The app can use either an existing instance of Photoshop or start a new instance as necessary for processing.

Broader Uses for Scripting

My ultimate goal is to be able to automate any adobe application that supports scripting capability using ExtendScript or Javascript. That allows development of cross application and cross platform functionality. Depending upon the need there are also many possibilities for combining internal and external scripting. For instance Python comes to mind as a compliment to Javascript. Also combining scripting and actions seems interesting.

Of course application scripting is not something everyone will need or want to do. It is good to know the capability exists just in case you ever need it. For me it is a way to combine my passions for photography and code.