<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Weblash.net &#187; C#</title>
	<atom:link href="http://weblash.net/category/development/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblash.net</link>
	<description>Graphic Design &#38; Web Development for Small Businesses</description>
	<lastBuildDate>Mon, 18 Jul 2011 13:03:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Automating PhotoShop Tasks Using PhotoShop APIs.</title>
		<link>http://weblash.net/195/automating-photoshop-tasks-using-photoshop-apis/</link>
		<comments>http://weblash.net/195/automating-photoshop-tasks-using-photoshop-apis/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 07:12:14 +0000</pubDate>
		<dc:creator>WeblashAdmin</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[PhotoShop]]></category>
		<category><![CDATA[PSActions]]></category>

		<guid isPermaLink="false">http://weblash.net/?p=195</guid>
		<description><![CDATA[Melchor Berona of Photo-Essence recently hired me to design his website. One of his feature requests was to enable a fast, easy way to get photos to his galleries online. This sounds simple enough, I thought, and off I went. As for any business, Melchor didn’t want to spend valuable hours replacing images in his [...]]]></description>
			<content:encoded><![CDATA[<p>Melchor Berona of <a href="http://www.photo-ess.com" target="_blank">Photo-Essence</a> recently hired me to design his website. One of his feature requests was to enable a fast, easy way to get photos to his galleries online. This sounds simple enough, I thought, and off I went.</p>
<p>As for any business, Melchor didn’t want to spend valuable hours replacing images in his online photo galleries. He wanted to get the high resolution photos to a usable format and size; then FTP to his site. The process turned out to be this:</p>
<ol>
<li>Get images to 96ppi</li>
<li>Convert images to RGB</li>
<li>Resize landscape or portrait to 600px height</li>
<li>Save file with the correct filename to be used in the destination galleries – old files would be swapped with new files, so the naming on the new images needed to be the same as the images being replaced</li>
<li>Create thumbnail images that are 150x150px</li>
<li>save file with the appropriate naming</li>
<li>FTP the new files (not covered here)</li>
</ol>
<p>So I thought: I’ll just create a droplet – no problem, right? Well, it’s not ideal when you’re resizing both landscape and portraits using the scaling in PhotoShop. This really can’t be automated unless you make two separate droplets, one for landscape and one for portrait.</p>
<p>Then I discovered a folder in the PhotoShop directories (in the Programs directory) that gives a pretty good introduction to automating tasks (and more) using scripting in JavaScript, VBScript, or ActionScript.</p>
<p>OK – now we’re getting somewhere, I thought. However, I wanted to take this a step further. I wanted to make a C# console application using the PhotoShop APIs. I didn’t find much documentation, but I did find a very good tutorial  by John Deurbrouck<em> </em>here: <a title="http://www.pcpix.com/Photoshop/" href="http://www.pcpix.com/Photoshop/">http://www.pcpix.com/Photoshop/</a>.</p>
<p>After I read that I was on my way. For this blog entry, I’d like to walk through my process of developing the application I delivered to my client.</p>
<h2>Step 1 – Do Some Research</h2>
<p>Get information on PhotoShop Scripting here: <a title="http://www.adobe.com/devnet/photoshop/scripting/" href="http://www.adobe.com/devnet/photoshop/scripting/">http://www.adobe.com/devnet/photoshop/scripting/</a></p>
<p>There are some PDFs here that go into detail about scripting for VB, JavaScript, and AppleScript. There’s also information about the ScriptListener.</p>
<h2>Step 2 – turn on the ScriptListener</h2>
<p>The PhotoShop ScriptListener logs every event you do in PhotoShop, from opening a document, modifications, saving, and closing it. So it should only be turned on when you are performing the steps you’ll use for your automation application. From Adobe…</p>
<h3>Installing ScriptListener</h3>
<p>The ScriptListener plug-in is located in the ..\Adobe Photoshop CS4\Scripting\Utilities folder.</p>
<h4>To install the ScriptListener:</h4>
<ol>
<li>Select the file ScriptListener.8li and then choose Edit &gt; Copy.</li>
<li>Paste the file copy to the following location: ..\Adobe Photoshop CS4\Plug-Ins\Automate</li>
<li>Open Photoshop.
<ol>
<li>NOTE: If Photoshop is already open, close it and then start it again. This will allow Photoshop to load<br />
the plug-in.</li>
</ol>
</li>
</ol>
<h4>To uninstall the ScriptListener:</h4>
<ol>
<li>Close Photoshop.</li>
<li>Verify that a copy of the file ScriptListener.8li still exists in the ..\Adobe Photoshop CS4\<br />
Scripting\Utilities folder.</li>
<li>Delete the file ScriptListener.8li from the following location: ..\Adobe Photoshop CS\Plug-Ins\Automate</li>
<li>Delete the log files ScriptingListenerJS.log and ScriptingListenerVB.log from your desktop.
<ol>
<li>NOTE: In Windows, even though you remove the ScriptListener from the Automate folder, it may continue<br />
to record actions. To prevent the ScriptingListenerJS.log file from becoming too large, delete it each<br />
time you finish playing a Photoshop action.</li>
</ol>
</li>
</ol>
<p>So when you’re ready to simulate an automation, go to your Actions, create a new action, and start going through the steps. When you’re finished, you’ll see two files on your desktop:</p>
<blockquote><p>ScriptingListenerJS.log, containing JavaScript code<br />
ScriptingListenerVB.log, containing VBScript code</p></blockquote>
<p>These files contain – you guessed it, the steps you just performed when you created the action.</p>
<p>Now you can see the code that defined the steps in the action. From here you can convert these steps to C# with some help from the documentation by John Deurbrouck<em> </em>here: <a title="http://www.pcpix.com/Photoshop/" href="http://www.pcpix.com/Photoshop/">http://www.pcpix.com/Photoshop/</a>.</p>
<h2>Step 3 – Write your functions</h2>
<p>I created a separate class in my application that contains all the PhotoShop action steps (opening the file, resizing, saving, changing canvas size, etc.). Below is an example:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Resize(<span class="kwrd">int</span> iHeight, <span class="kwrd">string</span> category)
        {
            <span class="rem">//get the original document dimensions</span>
            <span class="kwrd">double</span> dWidth = getdim(<span class="str">"X"</span>);
            <span class="kwrd">double</span> dHeight = getdim(<span class="str">"Y"</span>);
            <span class="rem">//convert datatype of iHeight</span>
            <span class="kwrd">double</span> dNewHeight = Convert.ToDouble(iHeight);

            <span class="kwrd">switch</span> (category)
            {
                <span class="kwrd">case</span> <span class="str">"full"</span>:
                    <span class="kwrd">break</span>;
                <span class="kwrd">case</span> <span class="str">"mid"</span>:
                    <span class="rem">//is the document landscape or portrait?</span>
                    <span class="kwrd">if</span> (dWidth &lt; dHeight)
                    {
                        <span class="rem">//is portrait</span>
                        dNewHeight = 300;
                    }
                    <span class="kwrd">else</span>
                    {
                        dNewHeight = 200;
                    }
                    <span class="kwrd">break</span>;
                <span class="kwrd">case</span> <span class="str">"thumb"</span>:
                    <span class="rem">//is the document landscape or portrait?</span>
                    <span class="kwrd">if</span> (dWidth &lt; dHeight)
                    {
                        <span class="rem">//is portrait</span>
                        dNewHeight = (dHeight * dNewHeight) / dWidth;
                    }
                    <span class="kwrd">break</span>;
            }
            <span class="rem">//run the action</span>
            <span class="rem">//describe the action</span>
            <span class="kwrd">int</span> idImgS = app.CharIDToTypeID(<span class="str">"ImgS"</span>);
            ps.ActionDescriptor desc3 = <span class="kwrd">new</span> ps.ActionDescriptor();
            <span class="rem">//image height</span>
            <span class="kwrd">int</span> idHght = app.CharIDToTypeID(<span class="str">"Hght"</span>);
            <span class="rem">//image resolution</span>
            <span class="kwrd">int</span> idPxl = app.CharIDToTypeID(<span class="str">"#Pxl"</span>);
            <span class="rem">//not sure what the below does</span>
            desc3.PutUnitDouble(idHght, idPxl, dNewHeight);
            <span class="rem">//scale the styles too?</span>
            <span class="kwrd">int</span> idscaleStyles = app.StringIDToTypeID(<span class="str">"scaleStyles"</span>);
            desc3.PutBoolean(idscaleStyles, <span class="kwrd">true</span>);
            <span class="rem">//the canvas?</span>
            <span class="kwrd">int</span> idCnsP = app.CharIDToTypeID(<span class="str">"CnsP"</span>);
            desc3.PutBoolean(idCnsP, <span class="kwrd">true</span>);
            <span class="rem">//not sure what these do</span>
            <span class="kwrd">int</span> idIntr = app.CharIDToTypeID(<span class="str">"Intr"</span>);
            <span class="kwrd">int</span> idIntp = app.CharIDToTypeID(<span class="str">"Intp"</span>);
            <span class="kwrd">int</span> idBcbc = app.CharIDToTypeID(<span class="str">"Bcbc"</span>);
            <span class="rem">//add the properties to prep execution</span>
            desc3.PutEnumerated(idIntr, idIntp, idBcbc);
            <span class="rem">//run execution of action</span>
            app.ExecuteAction(idImgS, desc3, ps.PsDialogModes.psDisplayNoDialogs);
        }</pre>
<p>So I have to admit it’s been quite a while since I wrote the code, and I am sketchy about defining the actions. <a title="http://www.pcpix.com/Photoshop/" href="http://www.pcpix.com/Photoshop/">http://www.pcpix.com/Photoshop/</a> has all the details about just what the code is that defines the action, and lists all of the enum names and values. I have asked John Deurbrouck and pcpix.com if I can distribute the article as a Word doc from my blog. I’ll keep you updated.</p>
<p>If you take on a project like this, you’ll find you’ll need to do some conversions from the code in the ScriptListener file to the C# code for the actions to get prepped properly.</p>
<p>Anyhow, this is a start. Please send me feedback! I’m not an experienced blogger so comments would be helpful.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Share this</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.bloglines.com/sub/http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F" rel="nofollow" title="Add to&nbsp;Bloglines"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/bloglines.png" title="Add to&nbsp;Bloglines" alt="Add to&nbsp;Bloglines" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://buzz.yahoo.com/submit?submitUrl=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F&amp;submitHeadline=Automating+PhotoShop+Tasks+Using+PhotoShop+APIs.&amp;submitSummary=" rel="nofollow" title="Add to&nbsp;Buzz"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/buzz.png" title="Add to&nbsp;Buzz" alt="Add to&nbsp;Buzz" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F&amp;title=Automating+PhotoShop+Tasks+Using+PhotoShop+APIs." rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F&amp;title=Automating+PhotoShop+Tasks+Using+PhotoShop+APIs." rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://FriendSite.com/users/bookmarks/?u=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F&amp;t=Automating+PhotoShop+Tasks+Using+PhotoShop+APIs." rel="nofollow" title="Add to&nbsp;FriendSite"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/friendsite.png" title="Add to&nbsp;FriendSite" alt="Add to&nbsp;FriendSite" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F&amp;title=Automating+PhotoShop+Tasks+Using+PhotoShop+APIs." rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.mister-wong.com/index.php?action=addurl&amp;bm_url=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F&amp;bm_description=Automating+PhotoShop+Tasks+Using+PhotoShop+APIs." rel="nofollow" title="Add to&nbsp;Mister Wong"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/misterwong.png" title="Add to&nbsp;Mister Wong" alt="Add to&nbsp;Mister Wong" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F&amp;title=Automating+PhotoShop+Tasks+Using+PhotoShop+APIs." rel="nofollow" title="Add to&nbsp;reddit"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/reddit.png" title="Add to&nbsp;reddit" alt="Add to&nbsp;reddit" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F&amp;title=Automating+PhotoShop+Tasks+Using+PhotoShop+APIs." rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://tipd.com/submit.php?url=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F" rel="nofollow" title="Add to&nbsp;Tip'd"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/tipd.png" title="Add to&nbsp;Tip'd" alt="Add to&nbsp;Tip'd" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Automating+PhotoShop+Tasks+Using+PhotoShop+APIs.+@+http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fweblash.net%2F195%2Fautomating-photoshop-tasks-using-photoshop-apis%2F&amp;t=Automating+PhotoShop+Tasks+Using+PhotoShop+APIs." rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://weblash.net/wp-content/plugins/social-bookmarks/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://weblash.net/195/automating-photoshop-tasks-using-photoshop-apis/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

