Tuesday, April 16, 2013

Photoshop Scripting with Javascript

Photoshop has a couple of kinds of automation, and today I learned about scripting it with Javascript. You can also record actions into macros in the Actions toolbox/window; though these are somewhat limited, they can be assigned a hotkey from a short range of the function keys (F2, F3, etc.)

Here's the script I threw together from examples and experimenting. Its purpose is to visibly watermark a folder of images with one image. It prompts you to choose a folder of images that you want to modify, then an output folder, then the watermark image you want pasted onto the images from the folder. At each image, the script prompts you to specify which corner of the image you want the watermark on.

 /*   
 Description:  
 This script pastes one image to the chosen corner of each image in a folder.  
 */  
 // enable double clicking from the   
 // Macintosh Finder or the Windows Explorer  
 #target photoshop  
 ////////////////////////////////////  
 /// Options and Variables  
 ///  
 ////////////////////////////////////  
   
 //margin is the number of pixels you want to space the edge of the watermark  
 //from the edge of the image  
 var marginX = 5;   
 var marginY = 5;  
   
 //save a copy of the modified images to a jpeg file   
 var fileSaveOptions = new JPEGSaveOptions();  
 fileSaveOptions.embedColorProfile = true;  
 fileSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;  
 fileSaveOptions.matte = MatteType.NONE;  
 fileSaveOptions.quality = 10;  
   
 // Close the file without saving  
 var documentCloseOptions = SaveOptions.DONOTSAVECHANGES;  
                  
 // Make Photoshop the frontmost application  
 // in case we double clicked the file  
 app.bringToFront();  
   
 /////////////////////////  
 // SETUP  
 /////////////////////////  
   
 // A list of file extensions to skip, keep them lower case  
 gFilesToSkip = Array( "db", "xmp", "xcf", "thm", "txt", "doc", "md0", "tb0", "adobebridgedb", "adobebridgedbt", "bc", "bct" );  
   
 /////////////////////////  
 // MAIN  
 /////////////////////////  
   
 // Pops open a dialog for the user to  
 // choose the folder of documents to process  
 var inputFolder = Folder.selectDialog("Select a folder of documents to process");  
   
 // Pops open a dialog for the user to  
 // set the output folder  
 var outputFolder = Folder.selectDialog("Select a folder for the output files");  
   
 //choose the file to watermark with  
 var logoFile = File.openDialog ("Select the logo file", "*.png", false);  
 var logo = open(logoFile);  
 //select all of the watermark  
 logo.selection.selectAll();  
 //copy the watermark to the clipboard  
 logo.selection.copy();  
   
 // Open Folder of Images  
 OpenFolder();  
 /////////////////////////  
 // FUNCTIONS  
 /////////////////////////  
   
 // Given the a Folder of files, open them  
 function OpenFolder() {  
      var filesOpened = 0;  
      var fileList = inputFolder.getFiles();  
      for ( var i = 0; i < fileList.length; i++ ) {  
           // Make sure all the files in the folder are compatible with PS  
           if ( fileList[i] instanceof File && ! fileList[i].hidden && ! IsFileOneOfThese( fileList[i], gFilesToSkip )) {  
                var photo = open( fileList[i] );  
                filesOpened++;  
                  
                //add a new layer for the watermark  
                var pasteLayer = photo.artLayers.add();  
                //paste the watermark into the new layer  
                photo.paste();  
                //ask the user which corner the watermark should be in  
                var corner = prompt("Top Left = 1, Top Right = 2, \r\nBottom Left = 3, Bottom Right = 4, \r\n Quit = 5","1","Which corner?");  
                if(corner == 1)  
                     topLeft(pasteLayer);  
                else if(corner == 2)  
                     topRight(pasteLayer);  
                else if(corner == 3)  
                     bottomLeft(pasteLayer);  
                else if(corner == 4)  
                     bottomRight(pasteLayer);  
                else if(corner == 5)  
                     break; //stop the program  
   
                //Save a copy of the file  
                app.activeDocument.saveAs(outputFolder, fileSaveOptions, true, Extension.LOWERCASE);  
                //Close the modified file  
                app.activeDocument.close(documentCloseOptions);  
           }  
      }  
 }  
   
 // given a file name and a list of extensions  
 // determine if this file is in the list of extensions  
 function IsFileOneOfThese( inFileName, inArrayOfFileExtensions ) {  
      var lastDot = inFileName.toString().lastIndexOf( "." );  
      if ( lastDot == -1 ) {  
           return false;  
      }  
      var strLength = inFileName.toString().length;  
      var extension = inFileName.toString().substr( lastDot + 1, strLength - lastDot );  
      extension = extension.toLowerCase();  
      for (var i = 0; i < inArrayOfFileExtensions.length; i++ ) {  
           if ( extension == inArrayOfFileExtensions[i] ) {  
                return true;  
           }  
      }  
      return false;  
 }  
 function topLeft( layer ){// layerObject, Number, Number  
      // if can not move layer return  
   if(layer.iisBackgroundLayer||layer.positionLocked) return  
   // get the layer bounds  
   var layerBounds = layer.bounds;  
   // get top left position  
   var layerX = layerBounds[0].value;  
   var layerY = layerBounds[1].value;  
   // the difference between where layer needs to be and is now  
   var deltaX = marginX-layerX;  
   var deltaY = marginY-layerY;  
   // move the layer into position  
   layer.translate (deltaX, deltaY);  
 }  
 function topRight( layer ){  
      // if can not move layer return  
   if(layer.iisBackgroundLayer||layer.positionLocked) return  
   // get the layer bounds  
   var layerBounds = layer.bounds;  
   // get top left position  
   var layerX = layerBounds[0].value;  
   var layerY = layerBounds[1].value;  
   // the difference between where layer needs to be and is now  
   var deltaX = layerX-marginX;  
   var deltaY = marginY-layerY;  
   // move the layer into position  
   layer.translate (deltaX, deltaY);  
 }  
 function bottomRight( layer ){  
      // if can not move layer return  
   if(layer.iisBackgroundLayer||layer.positionLocked) return  
   // get the layer bounds  
   var layerBounds = layer.bounds;  
   // get top left position  
   var layerX = layerBounds[0].value;  
   var layerY = layerBounds[1].value;  
   // the difference between where layer needs to be and is now  
   var deltaX = layerX-marginX;  
   var deltaY = layerY-marginY;  
   // move the layer into position  
   layer.translate (deltaX, deltaY);  
 }  
 function bottomLeft( layer ){  
      // if can not move layer return  
   if(layer.iisBackgroundLayer||layer.positionLocked) return  
   // get the layer bounds  
   var layerBounds = layer.bounds;  
   // get top left position  
   var layerX = layerBounds[0].value;  
   var layerY = layerBounds[1].value;  
   // the difference between where layer needs to be and is now  
   var deltaX = marginX-layerX;  
   var deltaY = layerY-marginY;  
   // move the layer into position  
   layer.translate (deltaX, deltaY);  
 }  

My references and borrowed code:
http://www.tranberry.com/photoshop/photoshop_scripting/PS4GeeksOrlando/IntroScripts/openFolder.jsx
http://forums.adobe.com/message/4287129?tstart=0, reply number 3

Tuesday, April 2, 2013

Windows Domain Controller with Cisco Router DNS

You can install a Windows domain controller without DNS if you have another DNS server, such as a Cisco router with an IOS image that supports the `ip dns primary` configuration command.
Windows domain clients will need SRV records in the DNS in order to authenticate and join the domain. Here is an example of the DNS records you will need for a Windows 2008 R2 server to join a domain (the domain controller is also Win2008R2):
ip host ns.example.com 10.88.33.4  
ip host example.com ns ns.example.com  
ip host dc1.example.com 10.88.33.2  
ip host _ldap._tcp.example.com srv 0 0 389 dc1.example.com  
ip host _ldap._tcp.dc._msdcs.example.com srv 0 0 88 dc1.example.com 
ip host _kdc._tcp.example.com srv 0 0 88 dc1.example.com  
ip host WIN-IRQG06G53P6.example.com 10.88.33.2  
!  
interface GigabitEthernet0/0
 description WAN
 ip address 10.89.28.33 255.255.255.0
 ip nat outside
 ip dns view-group default
interface GigabitEthernet0/1
 description LAN
 ip address 10.88.33.4 255.255.255.0
 ip nat outside
 ip dns view-group default
!
ip dns view default
 logging
 domain name example.com
 domain name-server 10.88.33.4
 dns forwarder 8.8.8.8
 dns forwarder 8.8.4.4
 dns forwarding source-interface GigabitEthernet0/1
ip dns view-list default
 view default 5
!
ip dns server  
ip dns primary example.com soa ns.example.com admin@example.com 21600 900 7776000 86400
!

The line 'ip host WIN-IRQG06G53P6.example.com 10.88.33.2' is there to show that even though I set the dc1's hostname to "dc1" in Windows, this domain controller still responds to domain join requests using this name (and the client could not join the domain until this entry was here). If you have issues finding this, debug DNS on the Cisco router like this:
debug ip dns name-list
debug ip dns view
debug ip dns view-list
terminal monitor

Sunday, March 24, 2013

Resetting a Cisco IOS device

When you need to reset a Cisco IOS device password/configuration, you need it to boot with the config register set to boot without loading the saved configuration. This register is stored in non-volatile memory. You can set this register in ROMMON or in Enable-privilege config mode in IOS.

Normal boot, read config file: 0x2102
boot without reading config file: 0x2142

ROMMON command to set config register to boot without reading the config file:
rommon 1 > confreg 0x2142

IOS command to set config register to boot normally, reading the config file at bootup:
router# conf t
router(config)# config-register 0x2102

Saturday, March 9, 2013

add-apt-repository not installed

apt-get install python-software-properties

Wednesday, March 6, 2013

nVidia display goes black-and-white


Josh1027 from http://answers.microsoft.com/en-us/windows/forum/windows_vista-pictures/my-monitor-just-went-black-and-white/64018efb-0e7a-4df7-94ac-14155e15c575 posted this:

hey smc i had the same problem and finally figured it out! i had updated my nvidia geforce driver when the problem started. alright here's what you do:
1. open ur control panel, switch to classic view
2. then open the NVIDIA control panel
3. then under the display tab on the right, choose adjust desktop color settings
4. then at the bottom of this screen, move the slider of DIGITAL VIBRANCE to 50%
this should fix it if your problem was the same as mine, hope it helps!

Sunday, March 3, 2013

Handy IOS bits

Dynamic DNS: http://nerdy-notes.blogspot.com/2010/07/dyndns-on-cisco-ios.html
Break sequences (case-sensitive!): Ctrl-^, Ctrl-^ then x, Ctrl-], Ctrl-R, Ctrl-C, Ctrl-c
Escape sequence for literal '?': Ctrl-V

Thursday, January 31, 2013

Create VM raw disk mapping

Adapted from http://cyborgworkshop.org/2011/01/08/enabling-raw-sata-access-in-esxi-free/
cd /vmfs/volumes/datastore1/MyVmFolder
vmkfstools -z /vmfs/devices/disks/t10.ATA_____ST32000542AS_____________________________5XW205BS raw_st32000542as.vmdk