Archive for the 'PDFPage' Category

2016/09/20 連番JPEGファイルを読み込んで連結したPDFを作成(新規作成)

連番JPEG画像を番号順にソートして、順次連結したPDFを新規作成するAppleScriptです。

jpeg_catfiles.jpg

このような連番画像を連結して任意のファイル名のPDFに合成します。出来上がるPDFは、元のJPEGファイルの圧縮度に応じて大きくなります。

新規作成よりも、すでに存在しているPDFにJPEGファイルを連結するほうが実用的だと思います。

AppleScript名:連番JPEGファイルを読み込んで連結したPDFを作成(新規作成)
– Created 2016-09-20 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “QuartzCore”
use framework “Quartz”
use framework “AppKit”

set aExt to “.jpg”
set aFol to choose folder
set fList to getFilePathList(aFol, aExt) of me
set f2List to my sort1DList:fList ascOrder:true –sort by ascending

set newFile to POSIX path of (choose file name with prompt “新規PDFファイルの名称を選択”)
set newFilePath to current application’s NSString’s stringWithString:newFile

–Make Blank PDF
set aPDFdoc to current application’s PDFDocument’s alloc()’s init()

set pageNum to 0

repeat with i in f2List
  set j to contents of i
  
set aURL to (current application’s |NSURL|’s fileURLWithPath:j)
  
set bImg to (current application’s NSImage’s alloc()’s initWithContentsOfURL:aURL)
  (
aPDFdoc’s insertPage:(current application’s PDFPage’s alloc()’s initWithImage:bImg) atIndex:pageNum)
  
set pageNum to pageNum + 1
end repeat

aPDFdoc’s writeToFile:newFilePath

–ASOCで指定フォルダのファイルパス一覧取得(拡張子指定つき)
on getFilePathList(aFol, aExt)
  set aPath to current application’s NSString’s stringWithString:(POSIX path of aFol)
  
set aFM to current application’s NSFileManager’s defaultManager()
  
set nameList to (aFM’s contentsOfDirectoryAtPath:aPath |error|:(missing value)) as list
  
set anArray to current application’s NSMutableArray’s alloc()’s init()
  
  
repeat with i in nameList
    set j to i as text
    
if (j ends with aExt) and (j does not start with “.”) then –exclude invisible files
      set newPath to (aPath’s stringByAppendingString:j)
      (
anArray’s addObject:newPath)
    end if
  end repeat
  
  
return anArray as list
end getFilePathList

–1D List(文字)をsort / ascOrderがtrueだと昇順ソート、falseだと降順ソート
on sort1DList:theList ascOrder:aBool
  set aDdesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:“self” ascending:aBool selector:“localizedCaseInsensitiveCompare:”
  
set theArray to current application’s NSArray’s arrayWithArray:theList
  
return (theArray’s sortedArrayUsingDescriptors:{aDdesc}) as list
end sort1DList:ascOrder:

★Click Here to Open This Script 

2016/07/27 PDFをページごとに分解してJPEGで保存する v2

PDFをページごとに分解してJPEG画像で保存するAppleScriptのアップデート版です。

実際に連番画像に変換して、ePub書類に変換させてみたらページの順序が狂ってしまいました。連番を振るときにゼロパディングしなかったためだとすぐにわかったので、ゼロパディングの処理を追加したものです。

ただし、実際にはこれだと解像度が不足しており、2倍の解像度で出力するように改良して実戦投入(Retina Display環境に配慮しつつ)しました。

AppleScript名:ASOCでPDFをページごとに分解してJPEGで保存する v2
– Created 2014-12-26 by Takaaki Naganoya
– Modified 2015-09-26 by Takaaki Naganoya
– Modified 2015-10-01 by Takaaki Naganoya
– Modified 2016-07-27 by Takaaki Naganoya–save each PDF page as jpeg
– Modified 2016-07-27 by Takaaki Naganoya–added zero padding function
– 2016 Piyomaru Software
# http://piyocast.com/as/archives/4176

use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “QuartzCore”
use framework “AppKit”

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “ページごとに分解するPDFを指定してください”)
set aPOSIX to POSIX path of aHFSPath
set aURL to (current application’s |NSURL|’s fileURLWithPath:aPOSIX)

set aPOSIXpath to POSIX path of aHFSPath —書き出し先パスをPOSIX pathで用意しておく(あとで加工)

set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:aURL
set pCount to aPDFdoc’s pageCount()

set compFactor to 1.0 – 0.0 = max jpeg compression, 1.0 = none

–PDFをページごとに分割してJPEGでファイル書き出し
repeat with i from 0 to (pCount - 1)
  set thisPage to (aPDFdoc’s pageAtIndex:(i))
  
set thisDoc to (current application’s NSImage’s alloc()’s initWithData:(thisPage’s dataRepresentation()))
  
if thisDoc = missing value then error “Error in getting imagerep from PDF in page:” & (i as string)
  
  
set theData to thisDoc’s TIFFRepresentation()
  
set newRep to (current application’s NSBitmapImageRep’s imageRepWithData:theData)
  
set targData to (newRep’s representationUsingType:(current application’s NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor, NSImageProgressive:false})
  
set zText to retZeroPaddingText((i + 1), 4) of me
  
set outPath to addString_beforeExtensionIn_addingExtension_(“_” & zText, aPOSIXpath, “jpg”)
  
  (
targData’s writeToFile:outPath atomically:true) –書き出し
end repeat

–ファイルパス(POSIX path)に対して、文字列(枝番)を追加。任意の拡張子を追加
on addString:extraString beforeExtensionIn:aPath addingExtension:aExt
  set pathString to current application’s NSString’s stringWithString:aPath
  
set theExtension to pathString’s pathExtension()
  
set thePathNoExt to pathString’s stringByDeletingPathExtension()
  
  
set newPath to (thePathNoExt’s stringByAppendingString:extraString)’s stringByAppendingPathExtension:aExt
  
return newPath as string
end addString:beforeExtensionIn:addingExtension:

on retZeroPaddingText(aNum as integer, aDigitNum as integer)
  if aNum > (((10 ^ aDigitNum) as integer) - 1) then return “” –Range Check
  
set aFormatter to current application’s NSNumberFormatter’s alloc()’s init()
  
aFormatter’s setUsesGroupingSeparator:false
  
aFormatter’s setAllowsFloats:false
  
aFormatter’s setMaximumIntegerDigits:aDigitNum
  
aFormatter’s setMinimumIntegerDigits:aDigitNum
  
aFormatter’s setPaddingCharacter:“0″
  
set aStr to aFormatter’s stringFromNumber:(current application’s NSNumber’s numberWithFloat:aNum)
  
return aStr as string
end retZeroPaddingText

★Click Here to Open This Script 

2016/07/27 PDFをページごとに分解してJPEGで保存する

指定したPDFをページごとに分解してJPEG画像として保存するAppleScriptです。

書籍のPDFからePubを作ろうとして、さまざまなツールを試して撃沈。日本語のフォントが通らなかったり、オリジナルからかけ離れたレイアウトになったりと散々でした。

ePub版を作るのにそれほど労力を割きたくなかったので、「画像からePub作ろう」と割り切り、PDFをページごとにJPEGに分解することにしました。これを手作業で行っていたのでは日が暮れます。

splittedjpegs.png

そこで、本AppleScriptを作成。ありものを組み合わせたぐらいの作業で完成。さくっとPDFをページごとのJPEG画像に分解できました。

AppleScript名:ASOCでPDFをページごとに分解してJPEGで保存する
– Created 2014-12-26 by Takaaki Naganoya
– Modified 2015-09-26 by Takaaki Naganoya
– Modified 2015-10-01 by Takaaki Naganoya
– Modified 2016-07-27 by Takaaki Naganoya–save each PDF page as jpeg
– 2016 Piyomaru Software
# http://piyocast.com/as/archives/4174

use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “QuartzCore”
use framework “AppKit”

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “ページごとに分解するPDFを指定してください”)
set aPOSIX to POSIX path of aHFSPath
set aURL to (current application’s |NSURL|’s fileURLWithPath:aPOSIX)

set aPOSIXpath to POSIX path of aHFSPath —書き出し先パスをPOSIX pathで用意しておく(あとで加工)

set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:aURL
set pCount to aPDFdoc’s pageCount()

set compFactor to 1.0 – 0.0 = max jpeg compression, 1.0 = none

–PDFをページごとに分割してJPEGでファイル書き出し
repeat with i from 0 to (pCount - 1)
  set thisPage to (aPDFdoc’s pageAtIndex:(i))
  
set thisDoc to (current application’s NSImage’s alloc()’s initWithData:(thisPage’s dataRepresentation()))
  
if thisDoc = missing value then error “Error in getting imagerep from PDF in page:” & (i as string)
  
  
set theData to thisDoc’s TIFFRepresentation()
  
set newRep to (current application’s NSBitmapImageRep’s imageRepWithData:theData)
  
set targData to (newRep’s representationUsingType:(current application’s NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor, NSImageProgressive:false})
  
  
set outPath to addString_beforeExtensionIn_addingExtension_(“_” & (i + 1) as string, aPOSIXpath, “jpg”)
  
  (
targData’s writeToFile:outPath atomically:true) –書き出し
end repeat

–ファイルパス(POSIX path)に対して、文字列(枝番)を追加。任意の拡張子を追加
on addString:extraString beforeExtensionIn:aPath addingExtension:aExt
  set pathString to current application’s NSString’s stringWithString:aPath
  
set theExtension to pathString’s pathExtension()
  
set thePathNoExt to pathString’s stringByDeletingPathExtension()
  
  
set newPath to (thePathNoExt’s stringByAppendingString:extraString)’s stringByAppendingPathExtension:aExt
  
return newPath as string
end addString:beforeExtensionIn:addingExtension:

★Click Here to Open This Script 

2016/07/18 PDFの指定ページを削除

指定PDF中の指定ページを削除するAppleScriptです。

CocoaのAPIをひととおり調べて、PDFのページ削除を行うメソッドなどが存在していないことがよくわかりました。

存在しない=できない、ということではないのでAppleScriptで組んでみました。動作確認した範囲ではちゃんと機能しています。

pdfremove.png

削除機能を削除機能として考えただけでは実現できませんが、これを「新規PDFへのページコピー」と考えれば不可能ではありません。つまり、削除を「新規PDFにコピーしない」ことと定義し直してみました。

 /卦PDFに指定ページ以外のページをコピー
 ▲リジナルのPDFを削除
 新規PDFをオリジナルのPDF名で保存

と処理すれば、指定ページを削除したのと同じことです。

このルーチンを用いて、「複数ファイルのPDFを連結、末尾が空白ページだったら削除しつつ連結」という動作を行うAppleScriptを簡単に書くことができました。

ただ、この処理方法がSandbox環境で(Xcode上で作成するCocoa-AppleScript Applet内で)許可されるものなのかは、試してみないといけないでしょう。

AppleScript名:PDFの指定ページを削除
– Modified 2016-07-18 by Takaaki Naganoya
–Original By Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “Quartz”
use framework “QuartzCore”

set inFile to (choose file of type {“pdf”} with prompt “Choose your PDF files:”)
set targPage to 2
set maxPage to pdfPageCount(inFile) of me
if 0 < targPage and targPage maxPage then
  –Skip
else
  display dialog “Page Number Range Error”
  
return
end if

removeSpecificPageInPDF(inFile, targPage) of me

on removeSpecificPageInPDF(inFile, targPageNum)
  – make URL of the first PDF
  
set inNSURL to current application’s |NSURL|’s fileURLWithPath:(POSIX path of inFile)
  
set theDoc to current application’s PDFDocument’s alloc()’s initWithURL:inNSURL
  
  set oldDocCount to ((theDoc’s pageCount()) - 1)
  
  –Make Blank PDF (deleted PDF)
  
set newPDFdoc to current application’s PDFDocument’s alloc()’s init()
  
  set newDocCount to 0
  
  repeat with i from 0 to oldDocCount
    if i is equal to (targPageNum - 1) then
      log {“skip page at:”, i}
    else
      log {i}
      
set thePDFPage to (theDoc’s pageAtIndex:i) – zero-based indexes
      (
newPDFdoc’s insertPage:thePDFPage atIndex:newDocCount)
      
set newDocCount to newDocCount + 1
    end if
  end repeat
  
  –元ファイルを削除して問題がなければ、指定ページを削除したPDFを同名で新規保存
  
set aRes to deleteFile(inFile) of me
  
if aRes = true then
    set aRes to (newPDFdoc’s writeToURL:inNSURL)
  end if
  
  return aRes
  
end removeSpecificPageInPDF

–指定PDFのページ数をかぞえる
on pdfPageCount(aFile)
  set aFile to POSIX path of aFile
  
set theURL to current application’s |NSURL|’s fileURLWithPath:aFile
  
set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:theURL
  
set aRes to aPDFdoc’s pageCount()
  
return aRes as integer
end pdfPageCount

–指定ファイルの削除
on deleteFile(aFile)
  set aPath to POSIX path of aFile
  
set filePath to current application’s NSString’s stringWithString:aPath
  
set fileManager to current application’s NSFileManager’s defaultManager()
  
set aRes to fileManager’s removeItemAtPath:filePath |error|:(reference)
  
–>  {true, missing value}
  
–>  {false, (NSError) Error}
  
copy aRes to {aFlag, aReason}
  
return aFlag
end deleteFile

★Click Here to Open This Script 

2016/04/19 Multi Page Tiffを読み込んで、PDFに変換する

Multipage Tiffを読み込んで、PDFに書き出すAppleScriptです。

意外とサンプルもなく、さまざまなObjective-Cのサンプルの断片をかき集めて、ようやくできました。着手してから1年ぐらい放置してあったぐらいです。

Multipage Tiffのサンプルをここから入手し、試行錯誤してようやく変換できました。

multipage1.png

大昔から存在しているものの、ずーーっとマイナーな存在だったMultipage Tiffなので、こんなもん書いて有用性がどーのとかいうことは一切ないわけですが、1年間放置しておいた未解決の問題を解決できてスッキリしました。

AppleScript名:multi page tiffを読み込んで、PDFにする
– Created 2015-01-01 by Takaaki Naganoya
– Modified 2016-04-18 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “QuartzCore”
use framework “Quartz”
use framework “AppKit”

set a to choose file of type {“public.tiff”} with prompt “Select Multi-page tiff file” –tiff

–Make Output Path
set b to POSIX path of a
set bb to changeExtensionInPath(“pdf”, b) –OutPath

–Read Multi-Page TIFF
set aURL to current application’s |NSURL|’s fileURLWithPath:b
set aImage to current application’s NSImage’s alloc()’s initWithContentsOfURL:aURL
set aRawimg to aImage’s TIFFRepresentation()
set eachTiffPages to (current application’s NSBitmapImageRep’s imageRepsWithData:aRawimg) as list

–Make Blank PDF
set aPDFdoc to current application’s PDFDocument’s alloc()’s init()

set pageNum to 0

repeat with curPage in eachTiffPages
  set thisImage to contents of curPage
  
set aImg to (current application’s NSImage’s alloc()’s initWithSize:(thisImage’s |size|()))
  (
aImg’s addRepresentation:thisImage)
  (
aPDFdoc’s insertPage:(current application’s PDFPage’s alloc()’s initWithImage:aImg) atIndex:pageNum)
  
set pageNum to pageNum + 1
end repeat

aPDFdoc’s writeToFile:bb

–ファイルパス(POSIX path)に対して、拡張子のみ付け替える
on changeExtensionInPath(extStr as string, aPath as string)
  set pathString to current application’s NSString’s stringWithString:aPath
  
set theExtension to pathString’s pathExtension()
  
set thePathNoExt to pathString’s stringByDeletingPathExtension()
  
set newPath to thePathNoExt’s stringByAppendingPathExtension:extStr
  
return newPath as string
end changeExtensionInPath

★Click Here to Open This Script 

2015/10/20 PDFの各種情報を取得する

Cocoaの機能を用いて、PDFの各種情報を取得するAppleScriptです。

PDFのParse自体はAppleScriptだけでは行えませんが、こうした情報の取得や、PDFの暗号化/復号化ぐらいであればAppleScriptだけで(他のアプリケーションを併用せずに)実行可能です。

AppleScript名:ASOCでPDFの各種情報を取得する
– Created 2015-10-20 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.5″
use scripting additions
use framework “Foundation”
use framework “QuartzCore”

set aPath to POSIX path of (choose file of type {“com.adobe.pdf”} with prompt “Select PDF”)
set aURL to current application’s |NSURL|’s fileURLWithPath:aPath
set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:aURL

set pCount to aPDFdoc’s pageCount() –ページ数
–>  1

set aMajorVersion to aPDFdoc’s majorVersion() –バージョン(メジャーバージョン)
–> 1

set aMinorVersion to aPDFdoc’s minorVersion() –バージョン(マイナーバージョン)
–> 3

set aRoot to aPDFdoc’s outlineRoot()
–>  missing value

set anAttr to (aPDFdoc’s documentAttributes()) as record
–> (NSDictionary) {Creator:”Pages”, Producer:”Mac OS X 10.11.1 Quartz PDFContext”, ModDate:(NSDate) 2015-10-20 07:45:55 +0000, Title:”testPDF”, CreationDate:(NSDate) 2015-10-20 07:45:55 +0000}

set aCreator to anAttr’s Creator()
–>  ”Pages”

set aProducer to anAttr’s Producer()
–>  ”Mac OS X 10.11.1 Quartz PDFContext”

set aTitle to anAttr’s Title()
–>  ”testPDF”

set aCreationDate to anAttr’s CreationDate() –PDF作成年月日
–>  date “2015年10月20日火曜日 16:45:55″

set aModDate to anAttr’s ModDate() –PDF変更年月日
–>  date “2015年10月20日火曜日 16:45:55″

set anEncF to aPDFdoc’s isEncrypted() –暗号化されている(パスワードが設定されている)か?
–>  false

set anLockF to aPDFdoc’s isLocked() –ロックされているか?
–>  false

set aCopyF to aPDFdoc’s allowsCopying() –テキストのコピーを許可されているか?
–>  true

set aPrintF to aPDFdoc’s allowsPrinting() –印刷を許可されているか?
–>  true

–PDFのサイズを取得する(単位:Point)
set aPage to aPDFdoc’s pageAtIndex:0
set aBounds to aPage’s boundsForBox:(current application’s kPDFDisplayBoxMediaBox)
set aSize to |size| of aBounds
–>  {width:595.28, height:841.89}

★Click Here to Open This Script 

2015/10/18 PDFメディアサイズの取得(単位:Point)

選択したPDF書類のページのサイズをPointで取得するAppleScriptです。

ページの取得方式にいろいろあるので、ひととおり調べてみたところ(実験には、Shane Stanleyの「Everyday AppleScriptObjC」を使用)・・・すべて同じ結果が返ってきました。それぞれどのように取得しているか、調べておきたいところです(図になっていないものか)。

OS X 10.11上で確認および10.11の機能(Enumのbridge)を使っていますが、OS X 10.10上では「current application’s kPDFDisplayBoxMediaBox」などと書いてあるものを0(数値)に書き換えれば動きます。

AppleScript名:PDFメディアサイズの取得(単位:Point)
– Created 2015-10-18 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.5″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “QuartzCore”

–PDFを選択
set aFile to choose file of type {“com.adobe.pdf”}

set aFile to POSIX path of aFile
set theURL to current application’s |NSURL|’s fileURLWithPath:aFile
set aPDFdoc to current application’s PDFDocument’s alloc()’s initWithURL:theURL
set aPage to aPDFdoc’s pageAtIndex:0

–PDFのサイズを取得する(単位:Point)
set aBounds to aPage’s boundsForBox:(current application’s kPDFDisplayBoxMediaBox) –0
set aSize to |size| of aBounds
–>  {width:612.0, height:792.0}

set aBounds to aPage’s boundsForBox:(current application’s kPDFDisplayBoxCropBox) –1
set aSize to |size| of aBounds
–>  {width:612.0, height:792.0}

set aBounds to aPage’s boundsForBox:(current application’s kPDFDisplayBoxBleedBox) –2
set aSize to |size| of aBounds
–>  {width:612.0, height:792.0}

set aBounds to aPage’s boundsForBox:(current application’s kPDFDisplayBoxTrimBox) –3
set aSize to |size| of aBounds
–>  {width:612.0, height:792.0}

set aBounds to aPage’s boundsForBox:(current application’s kPDFDisplayBoxArtBox) –4
set aSize to |size| of aBounds
–>  {width:612.0, height:792.0}

★Click Here to Open This Script 

2014/12/27 PDFをページごとに分解する

指定したPDFファイルをページごとに分解して保存するAppleScriptです。

非常によくあるScript(PDFpenやSkimなどを使って分割)ですが、他のアプリを必要としません。

MacBook Pro Retina 2012(Core i7 2.66GHz)で277ページのPDFをページごとに分解するのに12秒でした。

AppleScript名:PDFをページごとに分解する
– Created 2014-12-26 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”
use framework “QuartzCore”

property PDFDocument : class “PDFDocument”

set aHFSPath to (choose file of type {“com.adobe.pdf”} with prompt “ページごとに分解するPDFを指定してください”) as string
set aURL to (current application’s SMSFord’s URLFrom:aHFSPath)

set aPOSIXpath to POSIX path of aHFSPath —書き出し先パスをPOSIX pathで用意しておく(あとで加工)

set aPDFdoc to PDFDocument’s alloc()’s initWithURL:aURL
set pCount to aPDFdoc’s pageCount()

–PDFをページごとに分割してファイル書き出し
repeat with i from 0 to (pCount - 1)
  
  
set thisPage to (aPDFdoc’s pageAtIndex:(i))
  
set thisDoc to (PDFDocument’s alloc()’s initWithData:(thisPage’s dataRepresentation()))
  
set outPath to addString_beforeExtensionIn_(“_” & (i + 1) as string, aPOSIXpath)
  
  (
thisDoc’s writeToFile:outPath) –書き出し
  
end repeat

–ファイルパス(POSIX path)に対して、文字列(枝番)を追加。拡張子はそのまま
on addString:extraString beforeExtensionIn:aPath
  set pathString to current application’s NSString’s stringWithString:aPath
  
set theExtension to pathString’s pathExtension()
  
set thePathNoExt to pathString’s stringByDeletingPathExtension()
  
  
set newPath to (thePathNoExt’s stringByAppendingString:extraString)’s stringByAppendingPathExtension:theExtension
  
return newPath as string
end addString:beforeExtensionIn:

★Click Here to Open This Script 

2014/11/08 ASObjCExtras.frameworkのつかいかた〜HFS pathとURLの変換

ASObjCExtras.frameworkでファイルパス(alias)をURLに変換する機能を利用してみました。

Cocoaの機能を利用するにあたって、aliasをそのまま渡せずURLとかPOSIX pathに変換する必要が多々あり、とくにalias→URLの変換はちょっと面倒(Finderを利用したり、いろいろやってますが)なので任せられるとありがたいです。

URLからHFS pathへの変換も行えます(コメントアウトしている行がそれです)。

AppleScript名:ASObjCExtrasのじっけん_aliasとURLの変換
use AppleScript version "2.4"
use framework "Foundation"
use framework "ASObjCExtras"
use framework "QuartzCore"
use scripting additions

property PDFDocument : class "PDFDocument"

set aHFSPath to (choose file of type {"com.adobe.pdf"} with prompt "ページ数をかぞえるPDFを指定してください") as string
set aURL to (current application’s SMSFord’s URLFrom:aHFSPath)

set aPDFdoc to PDFDocument’s alloc()’s initWithURL:aURL
set aRes to aPDFdoc’s pageCount()

–set aPath to (current application’s SMSFord’s fileFromURL:aURL) as string–URLからHFS pathに変換

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2013/12/16 OS X 10.9で指定PDFのページ数をかぞえる(AppleScriptObjC版)

OS X 10.9, Mavericks上で指定のPDFのページ数をかぞえるAppleScriptのAppleScriptObjC版(要Xcode)です。

PDFのページ数をかぞえる処理は、ひじょーに重要で応用範囲が広いものなので、先日あわてて即興で1本書きました(迅速に対応できないとまずい案件があったので)。mdlsコマンドで間接的にPDFのページ数を取得するというものでしたが、常識的な範囲内ではとくに問題なく動きました。

ただ……あれやこれやと「常識的な範囲内」についての条件説明が必要なため、まっとうな方法(AppleScriptObjCでCocoaを叩く)=「直接機能にアクセスして情報を取得」する方法で作っておく必要がありました。

そこで、仕事の合間を見て試作品を作成。ウィンドウのボタンをクリックすると、PDF選択ダイアログが表示されるため、PDFを選択するとページ数をダイアログで返します。

pdfc1.png

pdfc2.png

AppleScriptObjCファイル名:AppDelegate.applescript

– AppDelegate.applescript
– countPDFtest

– Created by Takaaki Naganoya on 2013/12/12.
– Copyright (c) 2013年 Takaaki Naganoya. All rights reserved.


script AppDelegate
  property parent : class “NSObject”
  
  property nsurl : class “NSURL”
  
property PDFDocument : class “PDFDocument”
  
  
  on applicationWillFinishLaunching:aNotification
    
  end applicationWillFinishLaunching:
  
  
  on applicationShouldTerminate:sender
    return current application’s NSTerminateNow
  end applicationShouldTerminate:
  
  
  on clicked:sender
    
    tell current application
      set aFile to choose file of type {“com.adobe.pdf”}
    end tell
    
    set aRes to pdfPageCount_(aFile as string)
    
    tell current application
      display dialog aRes as string
    end tell
    
  end clicked:
  
  
  
  –指定PDFのページ数をかぞえる(10.9対応。普通にPDFpageから取得)
  
–パラメータ:PDFファイルのHFS path(string)
  
–返り値:PDFファイルのページ数(整数値)
  
on pdfPageCount:aFile
    
    tell application “Finder”
      set aFileURL to (URL of file aFile)
    end tell
    
    set aFileURL to aFileURL as Unicode text
    
set theURL to nsurl’s URLWithString:aFileURL
    
    set aPDFdoc to PDFDocument’s alloc()’s initWithURL:theURL
    
set aRes to aPDFdoc’s pageCount()
    
    return aRes as integer
    
  end pdfPageCount:
  
  
  
  –指定PDFのページ数をかぞえる(10.9対応。普通にPDFpageから取得)
  
–パラメータ:PDFファイルのPOSIX path(quoteされていない)
  
–返り値:PDFファイルのページ数(整数値)
  
on pdfCountPOSIXpath:aPDFPosixPath
    
    set aFile to (aPDFPosixPath as POSIX file) –POSIX pathからPOSIX fileにcast
    
    tell application “Finder”
      set aFileURL to (URL of (aFile as alias)) –aliasからでないとURLが取得できない
    end tell
    
    set aFileURL to aFileURL as Unicode text
    
set theURL to nsurl’s URLWithString:aFileURL
    
    set aPDFdoc to PDFDocument’s alloc()’s initWithURL:theURL
    
set aRes to aPDFdoc’s pageCount()
    
    return aRes as integer
    
  end pdfCountPOSIXpath:
  
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2013/04/16 AppleScriptObjCでPDFViewを使ってPDFをプレビュー(4)

AppleScriptObjCでPDFをプレビューするテストプログラムをその後進展させたものです。

ようやく、現在表示中のPDFの選択中のページのインデックス番号(0からはじまる通し番号)を取得できるようになりました。

→ Xcodeプロジェクトのダウンロード

PDF Kit Programming Guideの「PDF Kit Tasks」を参照し、そのとおりにAppleScriptObjCで書いても動かず、延々とデバッグを行い…………………………「document」を「|document|」と修正したところ、何の問題もなく動作しました。

このあたりは、Xcode上でチェックしたり対策してくれないと、なかなか気付きません。

AppleScriptObjC Explorer2を外部からAppleScriptでコントロールして、自動でチェックするようにしたほうがよいかもしれません(XcodeのAppleScript用語辞書の実装はあいかわらずタコなままなので、Xcodeをこづき回しても得るものが少ない。また、AppleScriptの構文色分けを反映しなくなったのは納得できません)。

本サンプルは、選択したPDFをPhotoshopでレンダリングして画像にするための「プレビュー」を目的としており、対象ファイル、対象ページ、レンダリング解像度などを取得してPhotoshopでレンダリングするフローの中で使用する部品として想定しています。実際にはこの部品は(間に合わなかったので)使用せず、もっと簡易な仕様の部品を使いましたが……次回はこの部品の改良版を投入したいところです。

pdf1.png

pdf2.png

AppleScriptObjCファイル名:AppDelegate.applescript

– AppDelegate.applescript
– pdftest2

– Created by Takaaki Naganoya on 2013/04/16.
– Copyright (c) 2012年 Takaaki Naganoya. All rights reserved.


script AppDelegate
  property parent : class “NSObject”
  
property nsurl : class “NSURL”
  
property PDFDocument : class “PDFDocument”
  
  
  property pdfPreviewWin : missing value
  
property pdfView : missing value
  
property pdfThumb : missing value
  
  property pdfPageText : missing value
  
  
  
  on applicationWillFinishLaunching_(aNotification)
    
    pdfView’s setAllowsDragging_(false)
    
pdfView’s setDelegate_(me)
    
    
    pdfThumb’s setMaximumNumberOfColumns_(2)
    
pdfThumb’s setAllowsMultipleSelection_(false)
    
    –書類が変更になった(オープンされた場合)Notificationの処理先ハンドラを登録
    
set noter1 to current application’s NSNotificationCenter’s defaultCenter()
    
noter1’s addObserver_selector_name_object_(me, “pdfChange:”, current application’s PDFViewDocumentChangedNotification, pdfView)
    
    –ページが変更になったNotificationの処理先ハンドラを登録
    
noter1’s addObserver_selector_name_object_(me, “pdfPageChange:”, current application’s PDFViewPageChangedNotification, pdfView)
    
    
    
    –ファイルを選択
    
set aFile to choose file of type “com.adobe.pdf”
    
set aFileString to aFile as Unicode text
    
dispPDFWithHFSpath_(aFileString)
    
    
  end applicationWillFinishLaunching_
  
  
  
  –プレビューウィンドウをセンタリング(見た目以外にとくに意味なし)
  
on applicationDidFinishLaunching_(aNotification)
    
    pdfPreviewWin’s |center|()
    
  end applicationDidFinishLaunching_
  
  
  
  –HFSパスの文字列を渡すとPDFViewに表示する
  
on dispPDFWithHFSpath_(aFileString)
    
    set aFileString to aFileString as Unicode text
    
    tell application “Finder”
      set aFileURL to (URL of file aFileString)
    end tell
    
    set aFileURL to aFileURL as Unicode text
    
set theURL to nsurl’s URLWithString_(aFileURL)
    
    set aPDFdoc to PDFDocument’s alloc()’s initWithURL_(theURL) –allocわすれてた、、、
    
pdfView’s setDocument_(aPDFdoc)
    
  end dispPDFWithHFSpath_
  
  
  on applicationShouldTerminate_(sender)
    return current application’s NSTerminateNow
  end applicationShouldTerminate_
  
  
  –表示ページが変更になった場合にnotificationでこちらを呼び出している
  
on pdfPageChange_(notification)
    
    dispPDFPageNumber()
    
  end pdfPageChange_
  
  
  –ファイルの新規オープン、および表示ページが変更になった場合にnotificationでこちらを呼び出している
  
on pdfChange_(notification)
    
    dispPDFPageNumber()
    
  end pdfChange_
  
  
  –PDFページ数を表示する
  
on dispPDFPageNumber()
    
    set curDoc to pdfView’s |document| –ここが問題の箇所!!!
    
set curPage to pdfView’s currentPage
    
set curPageNumber to curDoc’s indexForPage_(curPage)
    
    pdfPageText’s setStringValue_((curPageNumber + 1) as string)
    
  end dispPDFPageNumber
  
  
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2013/02/09 AppleScriptObjCでPDFViewを使ってPDFをプレビュー(3)

AppleScriptObjCでPDFをプレビューするテストプログラムをその後進展させたものです。

1作目で、PDFのプレビューができるようになり
2作目で、表示中のPDFの選択中のページ(label)が取得できるようになり
この3作目では、PDFに設定されているリンクのクリックを無視するようになりました。

結局、PDFViewのオンラインマニュアルを端から端まで探しても、リンクの無効化などの機能は存在していないようだったので、上位クラスであるNSViewのオンラインマニュアルを探してみました。すると、

nsview1.png

のように、hitTest:でnill(false)を返せばViewへのクリックを無視できることがわかったので、以下のようにPDFViewを継承したクラスを宣言し、Interface Builder上でPDFViewのクラスをこの「clicThPDFView」に変更してみました。

→ Xcodeプロジェクトのダウンロード

AppleScriptObjCファイル名:clickThroughPDFView.applescript
script clicThPDFView
  
  property parent : class “PDFView”
  
  on hitTest_(aPoint)
    
    return false
    
  end hitTest_
  
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

pdfv1.png

すると……

pdfv2.png

このような、目次から各章へのリンクが張られまくっているPDFをオープンして、PDFViewで目次をクリックしても……

pdfv3.png

リンク先には飛ばなくなりました!!! PDFViewへのマウスクリックを無効化することで、PDF内のリンクが反応することを防げるようになったわけです。

ただし、以前心配していたとおり、ページ数の取得にPage(0からはじまるページ数)ではなくlabelを取得しているために、目次ページなどPDFドキュメント制作時にアラビア数字ではないページ数が割り振られている箇所では、そのようなページ数が表示されることが判明。

PDF上のリンクが反応しないようにはできたものの、ページ数の取得については依然として問題を抱えていることがわかりました。PDFのプレビューとページ数設定のUser Interfaceとして利用するためにはあと一歩の改良が必要といったところです。

2013/02/06 AppleScriptObjCでPDFViewを使ってPDFをプレビュー(2)

AppleScriptObjCでPDFをプレビューするテストプログラムをその後進展させたものです。

本コードについては、PDFのファイルを選択した後で、プレビューしつつ対象ページを選ばせて他のアプリケーション(たぶんPhotoshop)に渡してレンダリングさせる……という目論見があったものの、プレビュー対象のページの取得方法が分らずに、時間がなかったのでその時には実戦投入することをあきらめました。

そして、時間のあるときに調べてみて、選択・プレビュー中のページをなんとか取得する方法にたどり着いたので、修正してみました。

pdfprev1.png

–> “Page 0; label = 1\n media (0.0, 0.0) [612.0, 792.0]\n crop (0.0, 0.0) [612.0, 792.0]\n rot 0\n ‘A Adobe\U00ae RGB (1998) Color Imag…’\n”

pdfprev2.png

–> “Page 1; label = 2\n media (0.0, 0.0) [612.0, 792.0]\n crop (0.0, 0.0) [612.0, 792.0]\n rot 0\n ‘A Adobe RGB (1998) Color Image…’\n”

まだ、実用上は問題があります。PDFViewに表示されたPDF上のリンクが生きており、PDF書類内のリンクや外部のWebサイトに張られたリンクが反応してしまうからです。これらをDisableにしてはじめて、プレビュー/処理対象ページ選択用のUIとして使えるのですが…………。

AppleScriptObjCファイル名:AppDelegate.applescript

– AppDelegate.applescript
– pdftest2

– Created by Takaaki Naganoya on 2012/10/23.
– Copyright (c) 2012年 Takaaki Naganoya. All rights reserved.


script AppDelegate
  property parent : class “NSObject”
  
property nsurl : class “NSURL”
  
property PDFDocument : class “PDFDocument”
  
  
  property pdfPreviewWin : missing value
  
property pdfView : missing value
  
property pdfThumb : missing value
  
  property pdfPageText : missing value
  
  
  
  on applicationWillFinishLaunching_(aNotification)
    
    pdfView’s setAllowsDragging_(false)
    
pdfView’s setDelegate_(me)
    
    
    pdfThumb’s setMaximumNumberOfColumns_(2)
    
pdfThumb’s setAllowsMultipleSelection_(false)
    
    –書類が変更になった(オープンされた場合)
    
set noter1 to current application’s NSNotificationCenter’s defaultCenter()
    
noter1’s addObserver_selector_name_object_(me, “pdfChange:”, current application’s PDFViewDocumentChangedNotification, missing value)
    
    –ページが変更になった
    
set noter2 to current application’s NSNotificationCenter’s defaultCenter()
    
noter2’s addObserver_selector_name_object_(me, “pdfChange:”, current application’s PDFViewPageChangedNotification, missing value)
    
    
    –ファイルを選択
    
set aFile to choose file of type “com.adobe.pdf”
    
set aFileString to aFile as Unicode text
    
dispPDFWithHFSpath_(aFileString)
    
    
  end applicationWillFinishLaunching_
  
  
  
  –プレビューウィンドウをセンタリング(見た目以外にとくに意味なし)
  
on applicationDidFinishLaunching_(aNotification)
    
    pdfPreviewWin’s |center|()
    
  end applicationDidFinishLaunching_
  
  
  
  –HFSパスの文字列を渡すとPDFViewに表示する
  
on dispPDFWithHFSpath_(aFileString)
    
    set aFileString to aFileString as Unicode text
    
    tell application “Finder”
      set aFileURL to (URL of file aFileString)
    end tell
    
    set aFileURL to aFileURL as Unicode text
    
set theURL to nsurl’s URLWithString_(aFileURL)
    
    set aPDFdoc to PDFDocument’s alloc()’s initWithURL_(theURL) –allocわすれてた、、、
    
pdfView’s setDocument_(aPDFdoc)
    
  end dispPDFWithHFSpath_
  
  
  on applicationShouldTerminate_(sender)
    return current application’s NSTerminateNow
  end applicationShouldTerminate_
  
  (*
–PDF内のURLなどのリンクをクリックした場合の動作??? これを無視させたかったのだが、、、、
on PDFViewOpenPDF_forRemoteGoToAction_(sender)

return false

end PDFViewOpenPDF_forRemoteGoToAction_
*)

  
  –ファイルの新規オープン、および表示ページが変更になった場合にnotificationでこちらを呼び出している
  
–ここで、選択中のページのノンブルを取得したい(まだできていない)
  
on pdfChange_(sender)
    set curPage to pdfView’s currentPage
    
–set curPageNum to curPage’s indexForPage
    
    set curPage2 to pdfThumb’s selectedPages
    
    set anItem to first item of curPage2
    
    log {anItem}
    
–> “Page 0; label = 1\n media (0.0, 0.0) [612.0, 792.0]\n crop (0.0, 0.0) [612.0, 792.0]\n rot 0\n ‘A Adobe\U00ae RGB (1998) Color Imag…’\n”
    
    set bItem to label of anItem –本当はPage(0からはじまるIndex)を取得したかったのだが、できなかった。なんでだろうねぇ
    
    pdfPageText’s setStringValue_(bItem as string)
    
  end pdfChange_
  
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2012/12/27 AppleScriptObjCでPDFViewを使ってPDFをプレビュー

PDFのファイルを選択して、Photoshopで画像フォーマット変換を行うため、対象ページ数と解像度を指定しなければなりませんでした。そこで、PDF内の各ページのプレビューを行うウィンドウを表示すべく、AppleScriptObjCでPDFプレビュー用の試作品を作ってみました。

pdfview.png

とりあえず、指定したPDFのファイルをプレビューできています。本来なら、これで十分なはずですが……PDFビューで表示しているPDF内のリンクなどをDisableにできていないので、表示中の内容をクリックすると別のページに飛べてしまったりします。

あとは、現在表示中のページ数を取得できるとよいのですが……まだ構造を調べながらいろいろつっついている状態なので、まだできていません。さらに、パスワードが設定されていた場合への対処なども手を打っておく必要があるでしょう。

→ Xcodeプロジェクトのダウンロード

AppleScriptObjCファイル名:AppDelegate.applescript

– AppDelegate.applescript
– pdftest2

– Created by Takaaki Naganoya on 2012/10/23.
– Copyright (c) 2012年 Takaaki Naganoya. All rights reserved.


script AppDelegate
  property parent : class “NSObject”
  
property nsurl : class “NSURL”
  
property PDFDocument : class “PDFDocument”
  
  
  property pdfPreviewWin : missing value
  
property pdfView : missing value
  
property pdfThumb : missing value
  
  property pdfPageText : missing value
  
  
  
  on applicationWillFinishLaunching_(aNotification)
    
    pdfView’s setAllowsDragging_(true)
    
pdfView’s setDelegate_(me)
    
    
    pdfThumb’s setMaximumNumberOfColumns_(2)
    
    
    –書類が変更になった(オープンされた場合)
    
set noter1 to current application’s NSNotificationCenter’s defaultCenter()
    
noter1’s addObserver_selector_name_object_(me, “pdfChange:”, current application’s PDFViewDocumentChangedNotification, missing value)
    
    –ページが変更になった
    
set noter2 to current application’s NSNotificationCenter’s defaultCenter()
    
noter2’s addObserver_selector_name_object_(me, “pdfChange:”, current application’s PDFViewPageChangedNotification, missing value)
    
    
    –ファイルを選択
    
set aFile to choose file of type “com.adobe.pdf”
    
set aFileString to aFile as Unicode text
    
dispPDFWithHFSpath_(aFileString)
    
    
  end applicationWillFinishLaunching_
  
  
  
  –プレビューウィンドウをセンタリング(見た目以外にとくに意味なし)
  
on applicationDidFinishLaunching_(aNotification)
    
    pdfPreviewWin’s |center|()
    
  end applicationDidFinishLaunching_
  
  
  
  –HFSパスの文字列を渡すとPDFViewに表示する
  
on dispPDFWithHFSpath_(aFileString)
    
    set aFileString to aFileString as Unicode text
    
    tell application “Finder”
      set aFileURL to (URL of file aFileString)
    end tell
    
    set aFileURL to aFileURL as Unicode text
    
set theURL to nsurl’s URLWithString_(aFileURL)
    
    set aPDFdoc to PDFDocument’s alloc()’s initWithURL_(theURL) –allocわすれてた、、、
    
pdfView’s setDocument_(aPDFdoc)
    
  end dispPDFWithHFSpath_
  
  
  on applicationShouldTerminate_(sender)
    return current application’s NSTerminateNow
  end applicationShouldTerminate_
  
  
  –ファイルの新規オープン、および表示ページが変更になった場合にnotificationでこちらを呼び出している
  
–ここで、選択中のページのノンブルを取得したい(まだできていない)
  
on pdfChange_(sender)
    set curPage to pdfView’s currentPage
    
–set curPageNum to curPage’s indexForPage
    
    log curPage
  end pdfChange_
  
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に