SkimでPDFを、見開き2ページ、書籍モードで表示させた状態で、見開きごと2ページ分の画像をJPEG画像で書き出すAppleScriptです。
macOS 12.3 beta 5、Skim v1.6.8で動作を確認してあります。macOS 12に合わせてPDFKitを直接useコマンドで使用指定しています。
▲SkimでPDFをオープンした状態で実行。見開き2ページ、書籍モードを設定している状態
▲macOS標準搭載のスクリプトメニューから呼び出すことを前提に作ってあります
▲見開き2ページのうち、右ページを選択しているか、左ページを選択しているかの状態を検出して処理
AppleScript名:Skimで現在表示中のページ(見開き2ページ、書籍モード)をJPEG画像で書き出す |
— Created 2022-03-02 by Takaaki Naganoya — 2022 Piyomaru Software use AppleScript version "2.7" use scripting additions use framework "Foundation" use framework "Quartz" use framework "PDFKit" use framework "AppKit" property |NSURL| : a reference to current application’s |NSURL| property NSString : a reference to current application’s NSString property NSImage : a reference to current application’s NSImage property NSScreen : a reference to current application’s NSScreen property NSNumber : a reference to current application’s NSNumber property NSZeroPoint : a reference to current application’s NSZeroPoint property PDFDocument : a reference to current application’s PDFDocument property NSJPEGFileType : a reference to current application’s NSJPEGFileType property NSCompositeCopy : a reference to current application’s NSCompositeCopy property NSGraphicsContext : a reference to current application’s NSGraphicsContext property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep property NSNumberFormatter : a reference to current application’s NSNumberFormatter property NSImageInterpolationHigh : a reference to current application’s NSImageInterpolationHigh tell application "Skim" set docCount to count every document if docCount = 0 then return tell front document set curViewSets to view settings set curMode to display mode of curViewSets if curMode is not in {two up, two up continuous} then display dialog "2ページ見開きモードでないため、処理を終了します。" with title "error" with icon 0 return end if set bMode to displays as book of curViewSets if bMode = false then display dialog "「書籍モード」でないため、処理を終了します。" with title "error" with icon 0 return end if set curInd to index of current page set docFile to file of it end tell end tell –PDFのファイルパスから実際のPDFを求める set aPOSIX to POSIX path of docFile set aURL to (|NSURL|’s fileURLWithPath:aPOSIX) set aPDFdoc to PDFDocument’s alloc()’s initWithURL:aURL –PDFのページ数を求める set pCount to aPDFdoc’s pageCount() –ページ数 if curInd = pCount then display dialog "このページはPDFの最終ページなので、見開き表示になっていない可能性があります。" with title "エラー" return end if if curInd = 1 then display dialog "このページはPDFの最初のページなので、見開き表示になっていない可能性があります。" with title "エラー" return end if –見開き中の選択ページが奇数(右ページ)だった場合の対処 if chkOddNum(curInd) = true then set curInd to curInd – 1 –Detect Retina Environment set compFactor to 1.0 –1.0 — 0.0 = max jpeg compression, 1.0 = none set retinaF to NSScreen’s mainScreen()’s backingScaleFactor() if retinaF = 1.0 then set aScale to 2.0 –Non Retina Env else set aScale to 1.0 –Retina Env end if –Pick Up a PDF page as an image (Left Side Page) set thisPageL to (aPDFdoc’s pageAtIndex:(curInd – 1)) set imgL to (NSImage’s alloc()’s initWithData:(thisPageL’s dataRepresentation())) set pageL to renderPDFPageToNSImage(imgL, (curInd – 1), aScale) of me –Pick Up a PDF page as an image (Right Side Page) set thisPageR to (aPDFdoc’s pageAtIndex:(curInd – 0)) set imgR to (NSImage’s alloc()’s initWithData:(thisPageR’s dataRepresentation())) set pageR to renderPDFPageToNSImage(imgR, (curInd – 0), aScale) of me –Calc 2 pages’ width and others set origWidth to (pageR’s |size|()’s width) set newWidth to origWidth * 2 set newHeight to pageR’s |size|()’s height –Make 2 pages’ blank image set aSize to current application’s NSMakeSize(newWidth, newHeight) set newImage to NSImage’s alloc()’s initWithSize:aSize –Compositte each Left and Right page image overlayNSImageByLeftTopOrigin(newImage, pageL, {0, 0}) of me overlayNSImageByLeftTopOrigin(newImage, pageR, {origWidth, 0}) of me –Save Image as JPEG set theData to newImage’s TIFFRepresentation() set newRep to (NSBitmapImageRep’s imageRepWithData:theData) set targData to (newRep’s representationUsingType:(NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor, NSImageProgressive:false}) set zText to retZeroPaddingText((curInd + 1), 4) of me set outPath to addString_beforeExtensionIn_addingExtension_("_" & zText, aPOSIX, "jpg") (targData’s writeToFile:outPath atomically:true) –書き出し on renderPDFPageToNSImage(anImage, aPageNum, aScale) set pointSize to anImage’s |size|() set newSize to current application’s NSMakeSize((pointSize’s width) * aScale, (pointSize’s height) * aScale) set newImage to (NSImage’s alloc()’s initWithSize:newSize) newImage’s lockFocus() (anImage’s setSize:newSize) (NSGraphicsContext’s currentContext()’s setImageInterpolation:(NSImageInterpolationHigh)) (anImage’s drawAtPoint:(NSZeroPoint) fromRect:(current application’s CGRectMake(0, 0, newSize’s width, newSize’s height)) operation:(NSCompositeCopy) fraction:2.0) newImage’s unlockFocus() return newImage end renderPDFPageToNSImage –ファイルパス(POSIX path)に対して、文字列(枝番)を追加。任意の拡張子を追加 on addString:extraString beforeExtensionIn:aPath addingExtension:aExt set pathString to 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, aLen) set tText to ("0000000000" & aNum as text) set tCount to length of tText set resText to text (tCount – aLen + 1) thru tCount of tText return resText end retZeroPaddingText –2つのNSImageを重ね合わせ合成してNSImageで返す(x,yで配置座標を指定) –newImageを参照渡し on overlayNSImageByLeftTopOrigin(newImage, composeImage, aTargPos as list) set backSize to newImage’s |size|() set bHeight to (height of backSize) set overlaySize to composeImage’s |size|() copy aTargPos to {x1, tempy1} set x2 to (width of overlaySize) set y2 to (height of overlaySize) set y1 to bHeight – y2 + tempy1 newImage’s lockFocus() set bRect to {{x1, y1}, {x2, y2}} –macOS 10.13 or later set newImageRect to {{0, 0}, (newImage’s |size|)} newImage’s drawInRect:newImageRect composeImage’s drawInRect:bRect newImage’s unlockFocus() end overlayNSImageByLeftTopOrigin on retUUIDfilePath(aPath, aExt) set aUUIDstr to (NSUUID’s UUID()’s UUIDString()) as string set aPath to ((NSString’s stringWithString:aPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:aExt return aPath end retUUIDfilePath –NSImageを指定パスにPNG形式で保存 on saveNSImageAtPathAsPNG(anImage, outPath) set imageRep to anImage’s TIFFRepresentation() set aRawimg to NSBitmapImageRep’s imageRepWithData:imageRep set pathString to NSString’s stringWithString:outPath set newPath to pathString’s stringByExpandingTildeInPath() set myNewImageData to (aRawimg’s representationUsingType:(NSPNGFileType) |properties|:(missing value)) set aRes to (myNewImageData’s writeToFile:newPath atomically:true) as boolean return aRes –true/false end saveNSImageAtPathAsPNG –奇数かどうかチェック on chkOddNum(aNum) set a to aNum mod 2 if a = 1 then return true else return false end if end chkOddNum –偶数かどうかチェック on chkEvenNum(aNum) set a to aNum mod 2 if a = 0 then return true else return false end if end chkEvenNum |
More from my site
(Visited 67 times, 1 visits today)