Copy link to clipboard
Copied
Do any of You know how to determine the number of pages of a pdf-file (selected with the openDialog for example)?
Somehow I fail to grasp how to achieve that any way short of actually opening/rasterizing all pages without prior knowledge of the actual number.
I would like to use that information to determine the number of elements for a contact-sheet-like procedure beforehand.
MultiPageImporter2.0.jsx, which is an Indesign-Script by Scott Zanelli, obviously does it, but so far I’ve failed to successfully utilize his functions.
Anyway, have a nice weekend
pfaffenbichler
Ok now this works....
Install X's script amending CSx version
Then run this script amending the pdf location and CS version... (NB: will not work with CS2. CS,CS3 and CS4 should be ok)
/////////////////////////////////////////////////////////////
var pdffile = File("~/Desktop/56 pages.pdf").fsName;
////////////////////////////////////////////////////////////
var file = new File("/Applications/Adobe Photoshop CS3/Presets/Scripts/macexec.app/contents/macexec");
var pdfcnt = File("~/pdfcnt");
if(pdfcnt.exi
...Copy link to clipboard
Copied
Sorry can't be done in Photoshop. There is a routine somewhere that you can get the number of pages but it is Mac only. Mike Hale came up with a brilliant idea for processing all pages, that was to use scriptlistener to open each page in turn, if that page didn't open that was the end of the pdf.
Copy link to clipboard
Copied
Thanks.
But opening is inconvenient in this case as I would prefer to place
the pages rather than open them.
But it probably shouldn’t make a lot of difference … maybe I’ll just
have to change that part.
I work on a Mac by the way, so maybe I can find the routine You
mentioned somewhere.
Copy link to clipboard
Copied
I have never tried it but I think this is the code....
tell application "Finder"
set theItems to choose file
do shell script "/usr/bin/mdls -name kMDItemNumberOfPages " & quoted form of POSIX path of result & " | /usr/bin/grep -o '[0-9]\\+$'"
return result as integer
Copy link to clipboard
Copied
Thanks again!
But I didn’t get that You meant it’s in AppleScript … I generally
avoid that Scripting language.
Copy link to clipboard
Copied
You might be able to convert it to a system() command if on CS4. I don't understand applescript at all. If not on CS4 you could create a shell script and call that with file.execute()
Copy link to clipboard
Copied
choose file returns a file path (as scripting alias of an HFS path)
The shell "mdls" is Mac Tiger onwards part of Spotlight
The "kMDItemNumberOfPages " is a key that Spotlight can read in the files Meta Data
The "quoted form of POSIX path of result" is converting the Finder file path alias to a POSIX slash delimited path wrapped in 'single quotes' for use with the shell in case the path has space characters in it. (quoted form is safer)
The piped GREP is just getting the numbers from the returned Meta Data key
There is a space character at the end of "/usr/bin/mdls -name kMDItemNumberOfPages " string and also at beginning of " | /usr/bin/grep -o '[0-9]\\+$'" these are important in the concatenating of the string for the shell to interpret
So a shell should look something like this:
/usr/bin/mdls -name kMDItemNumberOfPages '~/Desktop/Some Folder/Some File.pdf' | /usr/bin/grep -o '[0-9]\\+$'
Sorry I have no idea how you get the result of a shell back to JavaScript but may be someone else does now that I've explained the AppleScript part?
Copy link to clipboard
Copied
Nice Mark, I can see two ways of doing it.
If using CS4 there is the system(); command this could be used with that string re-directing the output to a file. Then check if file exists and read the contents.
The second way for other versions of Photoshop.
First create a shell script that will set the file permissions of a set filename
Write out all the details to a new shell script this again needs to re-direct the output to a file
execute the script to set permissions
execute the new shell script
check if output file exists then read contents.
Copy link to clipboard
Copied
Paul you have been more than helpful with me as of late, glad to be of some use. Should you need it here is the info on Spotlight from a shell point of view. I've included 2 samples just so you can see what it gets. The mdfind with onlyin is very useful and fast.
MDLS(1) BSD General Commands Manual MDLS(1)
NAME
mdls -- lists the metadata attributes for the specified file
SYNOPSIS
mdls [-name attributeName] [-raw [-nullMarker markerString]] file ...
DESCRIPTION
The mdls command prints the values of all the metadata attributes associ-
ated with the files provided as an argument.
The following options are available:
-name Print only the matching metadata attribute value. Can be
used multiple times.
-raw Print raw attribute data in the order that was requested.
Fields will be separated with a ASCII NUL character, suit-
able for piping to xargs(1) -0.
-nullMarker Sets a marker string to be used when a requested attribute
is null. Only used in -raw mode. Default is "(null)".
SEE ALSO
mdfind(1), mdutil(1) xargs(1)
Mac OS X June 3, 2004 Mac OS X
mdfind(1) BSD General Commands Manual mdfind(1)
NAME
mdfind -- finds files matching a given query
SYNOPSIS
mdfind [-live] [-count] [-onlyin directory] query
DESCRIPTION
The mdfind command consults the central metadata store and returns a list
of files that match the given metadata query. The query can be a string
or a query expression.
The following options are available:
-0 Prints an ASCII NUL character after each result path. This
is useful when used in conjunction with xargs -0.
-live Causes the mdfind command to provide live-updates to the num-
ber of files matching the query. When an update causes the
query results to change the number of matches is updated.
The find can be cancelled by typing ctrl-C.
-count Causes the mdfind command to output the total number of
matches, instead of the path to the matching items.
-onlyin dir
Limit the scope of the search to the directory specified.
-literal Force the provided query string to be taken as a literal
query string, without interpretation.
-interpret Force the provided query string to be interpreted as if the
user had typed the string into the Spotlight menu. For exam-
ple, the string "search" would produce the following query
string:
(* = search* cdw || kMDItemTextContent = search* cdw)
EXAMPLES
The following examples are shown as given to the shell.
This returns all files with any metadata attribute value matching the
string "image":
mdfind image
This returns all files that contain "MyFavoriteAuthor" in the kMDItemAu-
thor metadata attribute:
mdfind "kMDItemAuthor == '*MyFavoriteAuthor*'"
This returns all files with any metadata attribute value matching the
string "skateboard". The find continues to run after gathering the ini-
tial results, providing a count of the number of files that match the
query.
:
mdutil(1) BSD General Commands Manual mdutil(1)
NAME
mdutil -- manage the metadata stores used by Spotlight
SYNOPSIS
mdutil [-pEsav] [-i on | off] volume ...
DESCRIPTION
The mdutil command is useful for managing the metadata stores for mounted
volumes.
The following options are available:
-p Spotlight caches indexes of some network devices locally. This
option requests that a local caches be flushed to the appropriate
network device.
-E This flag will cause each local store for the volumes indicated to be
erased. The stores will be rebuilt if appropriate.
-i on | off
Sets the indexing status for the provided volumes to on or off. Note
that indexing may be delayed due to low disk space or other condi-
tions.
-s Display the indexing status of the listed volumes.
-a Apply command to all volumes.
-v Print verbose information when available.
SEE ALSO
mdfind(1), mdimport(1), mds(8), mdimport(1)
Mac OS X September 1, 2005 Mac OS X
*************************************************
This is a Photoshop image Meta Data
*************************************************
"kMDItemBitsPerSample = 32
kMDItemColorSpace = \"RGB\"
kMDItemContentCreationDate = 2009-04-16 22:39:20 +0100
kMDItemContentModificationDate = 2009-04-16 22:39:24 +0100
kMDItemContentType = \"public.tiff\"
kMDItemContentTypeTree = (
\"public.tiff\",
\"public.image\",
\"public.data\",
\"public.item\",
\"public.content\"
)
kMDItemCreator = \"Adobe Photoshop CS2 Macintosh\"
kMDItemDisplayName = \"1212345678901234567890 copy 2.tif\"
kMDItemFinderComment = \"XYZ&Larsen&Phillip&Mark\"
kMDItemFSContentChangeDate = 2009-04-16 22:39:24 +0100
kMDItemFSCreationDate = 2009-04-16 22:39:20 +0100
kMDItemFSCreatorCode = \"8BIM\"
kMDItemFSFinderFlags = 1024
kMDItemFSHasCustomIcon = 1
kMDItemFSInvisible = 0
kMDItemFSIsExtensionHidden = 0
kMDItemFSIsStationery = 0
kMDItemFSLabel = 0
kMDItemFSName = \"1212345678901234567890 copy 2.tif\"
kMDItemFSNodeCount = 0
kMDItemFSOwnerGroupID = 20
kMDItemFSOwnerUserID = 501
kMDItemFSSize = 104697
kMDItemFSTypeCode = \"TIFF\"
kMDItemHasAlphaChannel = 0
kMDItemKind = \"Adobe Photoshop TIFF file\"
kMDItemLastUsedDate = 2009-04-25 12:23:09 +0100
kMDItemOrientation = 0
kMDItemPixelHeight = 200
kMDItemPixelWidth = 200
kMDItemProfileName = \"sRGB IEC61966-2.1\"
kMDItemResolutionHeightDPI = 72
kMDItemResolutionWidthDPI = 72
kMDItemUsedDates = (
2009-04-16 00:00:00 +0100,
2009-04-25 00:00:00 +0100
)"
*************************************************
This is a PDF image Meta Data
*************************************************
"kMDItemContentCreationDate = 2009-04-11 17:59:08 +0100
kMDItemContentModificationDate = 2009-04-11 17:59:08 +0100
kMDItemContentType = \"com.adobe.pdf\"
kMDItemContentTypeTree = (
\"com.adobe.pdf\",
\"public.data\",
\"public.item\",
\"public.composite-content\",
\"public.content\"
)
kMDItemCreator = \"FrameMaker 5.5.2L11a\"
kMDItemDisplayName = \"CoreGuideJS14.pdf\"
kMDItemEncodingApplications = (
\"Acrobat Distiller 3.01 for Windows\"
)
kMDItemFSContentChangeDate = 2009-04-11 17:59:08 +0100
kMDItemFSCreationDate = 2009-04-11 17:59:08 +0100
kMDItemFSCreatorCode = \"\"
kMDItemFSFinderFlags = 0
kMDItemFSHasCustomIcon = 0
kMDItemFSInvisible = 0
kMDItemFSIsExtensionHidden = 0
kMDItemFSIsStationery = 0
kMDItemFSLabel = 0
kMDItemFSName = \"CoreGuideJS14.pdf\"
kMDItemFSNodeCount = 0
kMDItemFSOwnerGroupID = 20
kMDItemFSOwnerUserID = 501
kMDItemFSSize = 1892967
kMDItemFSTypeCode = \"\"
kMDItemKind = \"Adobe PDF document\"
kMDItemLastUsedDate = 2009-04-25 12:25:22 +0100
kMDItemNumberOfPages = 174
kMDItemPageHeight = 648
kMDItemPageWidth = 540
kMDItemSecurityMethod = \"None\"
kMDItemTitle = \"Untitled Document\"
kMDItemUsedDates = (
2009-04-11 00:00:00 +0100,
2009-04-12 00:00:00 +0100,
2009-04-24 00:00:00 +0100,
2009-04-25 00:00:00 +0100
)
kMDItemVersion = \"1.2\"
kMDItemWhereFroms = (
\"http://devedge-temp.mozilla.org/library/manuals/2000/javascript/1.4/guide/CoreGuideJS14.pdf\"
)"
Copy link to clipboard
Copied
Thanks for that Mark. I have been playing to see what can be done, it isn't as simple as what I thought! when using file.execute() on a shell script I found that it did not execute it, it only opened the document in TextEdit! By the way this is using Photoshop CS3 and the OS is Leopard.
Not to be beat I have written a small c program that reads a file and executes a system() command with the text in the file and that works. So without creating your own system command it looks like it's only possible the get the pdf page count using Photoshop CS4 as that has the system command.
Copy link to clipboard
Copied
If you would like to try the code, here it is..
pdfcount.c
----------------------------------------------
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(){
FILE *fp;
unsigned char string[301];
char en[150];
strcpy(en,getenv("HOME"));
chdir(en);
strcat(en,"/pdfinfo");
fp = fopen(en, "r");
if(fp==NULL){
printf("Can not open file!!!\n");
return 1;
}
fgets(string,300,fp);
fclose(fp);
system(string);
}
------------------------------------------------
pdfcount.jsx
----------------------------------------------------
var pdffile = File("~/Desktop/56 pages.pdf").fsName;
var pdfinfo = File("~/pdfinfo");
var pdfcnt = File("~/pdfcnt");
var pdfcount = File("~/cprogs/pdfcount");
if(pdfcnt.exists) pdfcnt.remove();
if(pdfinfo.exists) pdfinfo.remove();
pdfinfo.open("w");
pdfinfo.write("/usr/bin/mdls -name kMDItemNumberOfPages ");
pdfinfo.write("\""+pdffile+"\"| /usr/bin/grep -o [0-9]\\\\+$ > pdfcnt 2>/dev/null");
pdfinfo.close();
pdfcount.execute();
var test = false;
while(test){
if(pdfcnt.exist) test=true;
$.sleep(50);
}
for(var t =0;t<20;t++){
if(pdfcnt.length >0) break;
$.sleep(50);
}
pdfcnt.open("r");
var count = parseInt(pdfcnt.readln());
pdfcnt.close();
alert("Number of pages in "+ pdffile+" = "+ count);
--------------------------------------------------------------------------------
Copy link to clipboard
Copied
Thanks!
But quite frankly You lost me …
I found a thread in the Indesign-Forum that concerns the same matter,
but so far I have not been successfull in using the Scripts by Peter
Kahrel or Jezz either, which use open("r") and readln()-commands.
In case You want to see how they approached the problem:
http://forums.adobe.com/message/1112698#1112698
Copy link to clipboard
Copied
My background is in image-editing, so I actually couldn’t follow some
of the stuff here; but some of the Indesign-Scripts I mentioned
earlier seem to provide a workable function for Photoshop, too, at
least in CS4.
It seems to utilize some of the same functions You used in Your last
Script, Paul:
#target photoshop
thePageNumber = getPDFPageCount ( File.openDialog("select image/s to
put on the inside cover"))
alert (thePageNumber);
// by jezz, based on something by xbytor i guess;
function getPDFPageCount(f) {
f.open ('r');
var gotCount = false;
while (! gotCount) {
next_line = f.readln();
if ( f.eof ) {alert("Aborting the script\nWe've got to the end of the
file without finding a page count");
f.close();
exit();
}
if (next_line.indexOf ("/N ") > 0 && next_line.slice(0, 9) != "<</
Length" && next_line.slice(0, 9) != "[/Separat") {
var p = next_line.match (/\/N (\d+)\/T/)[1];
gotCount = true;
}
else if (next_line.indexOf ("/Pages") > 0 ) {
alert (next_line);
var p = parseInt(next_line.substring(next_line.indexOf("/Pages") +6),
10)
gotCount = true;
}
}
f.close ();
return Number(p);
};
Though possibly it will not get the correct number of pages for some
types of pdfs.
Copy link to clipboard
Copied
Please disregard my last post, at current I once again don’t seem to be able to get any meaningful results with the posted Script.
Copy link to clipboard
Copied
Mark, yes I even did a chmod 777 on the file and it still opens in TextEdit, so what I presume unless someone can say otherwise, the only way to run a system command/applescript is by using the system command.
(Tested using Mac OS X 10.5.6 )
So this is what I have so far..
Photoshop CS and CS3 need an external program so that a command can be issued via it.
Photoshop CS4 has the system command so no problem.
Photoshop CS2 the file.execute() does not work at all on the Mac (only checked on Leopard) file.execute() works fine on a PC.
Christoph, what version of Photoshop are you using so that we can work out the best method.
Copy link to clipboard
Copied
Use this script to create an executable shell script package for use in JS in Photoshop. You just need to run this once to set it up.
At runtime, do an open('e') on the 'macexec' file and write whatever shell commands you want to run.
File("/Applications/Adobe Photoshop CS4/Presets/Scripts/macexec.app").execute() will run those commands.
This effectively gets around the inability to set the 'execute' bit on shell scripts.
#!/bin/bash
#
# createMacExec.sh
#
# $Id: createMacExec.sh,v 1.1 2008/10/03 20:59:58 anonymous Exp $
#
# This is the Mac exec installation script.
# This creates the necessary files and folders needed to execute shell scripts
# under OSX.
#
# Installation instructions:
#
# To install the OSX shell script support, open a terminal window and change to
# the parent directory, possibly Presets/Scripts
#
# Run this script:
# % ./createMacExec.sh
#
# Specify the desired parent directory here
# Exec defaults to using this path
IDIR="/Applications/Adobe Photoshop CS4/Presets/Scripts"
if [ ! -e "$IDIR" ]; then
echo Bad directory specified ${IDIR}
exit 1
fi
cd "$IDIR"
mkdir -p macexec.app
mkdir -p macexec.app/Contents
rm -f macexec.app/Contents/macexec
touch macexec.app/Contents/macexec
chmod 755 macexec.app/Contents/macexec
echo macexec successfully installed
# EOT
Copy link to clipboard
Copied
That's fantastic X, now how on earth do you get a new line????
all I seem to get is ctrl/m I've tried using write instead of writeln, tried \r , \n, \0a and \0d with no luck please tell me the secret.
Copy link to clipboard
Copied
Got it.
file.encoding = 'BINARY';
Now things are working!
Copy link to clipboard
Copied
I typically set File.encoding to 'BINARY', File.lineFeed property to 'unix', and always use '\n'. They way I know exactly what's getting written to the file.
Copy link to clipboard
Copied
Ok now this works....
Install X's script amending CSx version
Then run this script amending the pdf location and CS version... (NB: will not work with CS2. CS,CS3 and CS4 should be ok)
/////////////////////////////////////////////////////////////
var pdffile = File("~/Desktop/56 pages.pdf").fsName;
////////////////////////////////////////////////////////////
var file = new File("/Applications/Adobe Photoshop CS3/Presets/Scripts/macexec.app/contents/macexec");
var pdfcnt = File("~/pdfcnt");
if(pdfcnt.exists) pdfcnt.remove();
if(file.exists) {
file.open("e");
file.encoding= 'BINARY';
file.write("/usr/bin/mdls -name kMDItemNumberOfPages ");
file.write("\""+pdffile+"\"| /usr/bin/grep -o [0-9]\\\\+$ > pdfcnt \n");
// The following line closes all Terminal windows.
file.writeln("/usr/bin/osascript -e 'tell application \"Terminal\" to quit'");
file.close();
}
file.execute();
var test = false;
while(test){
if(pdfcnt.exist) test=true;
$.sleep(50);
}
for(var t =0;t<20;t++){
if(pdfcnt.length >0) break;
$.sleep(50);
}
pdfcnt.open("r");
var count = parseInt(pdfcnt.readln());
pdfcnt.close();
alert("Number of pages in "+ pdffile+" = "+ count);
Copy link to clipboard
Copied
Well … well, all of this seems to be set several floors above my head, but it works.
The Terminal-closing-dialog pops up though, any idea what could I have done wrong there?
Thanks, all of You contributors!
Copy link to clipboard
Copied
Yes I was having the same problem here Christoph, I have now found a fix, this should be a lot cleaner now.
/////////////////////////////////////////////////////////////
var pdffile = File("~/Desktop/56 pages.pdf").fsName;
////////////////////////////////////////////////////////////
var file = new File("/Applications/Adobe Photoshop CS3/Presets/Scripts/macexec.app/contents/macexec");
var pdfcnt = File("~/pdfcnt");
if(pdfcnt.exists) pdfcnt.remove();
if(file.exists) {
file.open("e");
file.encoding= 'BINARY';
file.write("/usr/bin/mdls -name kMDItemNumberOfPages ");
file.write("\""+pdffile+"\"| /usr/bin/grep -o [0-9]\\\\+$ > pdfcnt \n");
file.writeln("/usr/bin/osascript -e 'tell application \"Terminal\"' -e 'close front window' -e 'end tell'");
file.close();
}
file.execute();
for(var t =0;t<100;t++){
if(pdfcnt.length >0) break;
$.sleep(30);
}
pdfcnt.open("r");
var count = parseInt(pdfcnt.readln());
pdfcnt.close();
alert("Number of pages in "+ pdffile+" = "+ count);
Copy link to clipboard
Copied
file.writeln("/usr/bin/osascript -e 'tell application \"Terminal\"' -e 'close front window' -e 'end tell'");
I get a 'Do you want to close this window?' prompt for the terminal
window with this code. I've never been able to automatically close the
terminal window without a prompt.
-X
Copy link to clipboard
Copied
Mine is closing clean without prompts X. I wonder if you have your terminal preferences set to close on exit?
Copy link to clipboard
Copied
I got it working by setting my Terminal preferences to use these settings. The important thing for me was adding osascript, loging, and bash to the list at the bottom right.
The shutdown popup gave me a nice list of process names to add.
Also, this is OS X 10.5.6.