AppleScript名:指定ファイルをFinderで選択表示_OLD Style_as |
— Created 2016-10-31 by Takaaki Naganoya — 2016 Piyomaru Software set aFile to choose file tell application "Finder" activate reveal aFile end tell |
カテゴリー: file
指定ファイルをFinderで選択表示_asoc
AppleScript名:指定ファイルをFinderで選択表示_asoc |
— Created 2016-10-31 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" set aFile to POSIX path of (choose file) set pathStr to current application’s NSString’s stringWithString:aFile set parentPath to pathStr’s stringByDeletingLastPathComponent() set aRes to current application’s NSWorkspace’s sharedWorkspace()’s selectFile:pathStr inFileViewerRootedAtPath:parentPath |
指定ファイルのFinder Tagを取得
AppleScript名:指定ファイルのFinder Tagを取得 |
— Created 2014-12-21 by Takaaki Naganoya — 2014 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set a to choose file set aResList to getFinderTagList(a) of me –> {"ブルー", "レッド"} on getFinderTagList(anAlias) –aliasをNSURLに変換 set aPOSIX to POSIX path of anAlias set aURL to current application’s |NSURL|’s fileURLWithPath:aPOSIX –指定URLから指定の属性(NSURLTagNamesKey)を取得 try set aTargAttr to {current application’s NSURLTagNamesKey} set {attsNSDictionary, theError} to aURL’s resourceValuesForKeys:aTargAttr |error|:(reference) if attsNSDictionary is missing value then error (theError’s localizedDescription() as text) end if –NSURLTagNamesKeyのリストを返す set aList to NSURLTagNamesKey of (attsNSDictionary as list of string or string) return aList as list on error return {} end try end getFinderTagList |
ZipZap frameworkを使ってZipアーカイブ内の情報を取得
AppleScript名:ZipZap frameworkを使ってZipアーカイブ内の情報を取得 |
— Created 2015-10-11 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.5" use scripting additions use framework "Foundation" use framework "ZipZap" –https://github.com/pixelglow/zipzap set aPath to POSIX path of (choose file of type {"public.zip-archive"}) set oldArchive to current application’s ZZArchive’s archiveWithURL:(current application’s |NSURL|’s fileURLWithPath:aPath) |error|:(missing value) –> (ZZArchive) <ZZArchive: 0x7fe59aa932d0> set entryCount to oldArchive’s entries()’s |count|() –> 180 –this zip archive includes 180 file or folders inside set firstArchEntry to oldArchive’s entries()’s firstObject() –> (ZZOldArchiveEntry) <ZZOldArchiveEntry: 0x7fe593fa4dc0> set aList to oldArchive’s entries() as list repeat with i in aList set uSize to i’s uncompressedSize() as real set cSize to i’s compressedSize() as real set comF to i’s compressed() as boolean set encF to i’s encrypted() as boolean set modD to i’s lastModified() as date set chkSum to i’s crc32() as text –The CRC32 code of the entry file: 0 for new entries. set aFileMode to i’s fileMode() as text — The UNIX file mode for the entry: 0 for new or non-UNIX entries. This includes the file type bits. set aFileName to i’s fileName() as text log {aFileName, aFileMode, chkSum, modD, encF, comF, cSize, uSize} –> 21:28:01.817 (* {"ZXingObjC.framework/", "16877d", "0", date "2015年10月10日土曜日 10:07:16", false, false, 0.0, 0.0} *) –> 21:28:01.818 (* {"ZXingObjC.framework/Headers", "41453d", "2.393740531E+9", date "2015年10月10日土曜日 10:07:10", false, false, 24.0, 24.0} *) –> 21:28:01.820 (* {"ZXingObjC.framework/Versions/", "16877d", "0", date "2015年10月10日土曜日 10:07:10", false, false, 0.0, 0.0} *) –> 21:28:01.821 (* {"ZXingObjC.framework/Versions/3.1.0/", "16877d", "0", date "2015年10月10日土曜日 10:07:16", false, false, 0.0, 0.0} *) –> 21:28:01.822 (* {"ZXingObjC.framework/Versions/3.1.0/Headers/", "16877d", "0", date "2015年10月10日土曜日 10:07:16", false, false, 0.0, 0.0} *) –set aData to (i’s newDataWithError:false)–Uncompressed raw data –log aData end repeat |
指定フォルダをtarでまとめる
AppleScript名:指定フォルダをtarでまとめる |
set a to choose folder set b to tarFolder(a) of me –指定フォルダをtarでまとめる on tarFolder(a) set anAlias to a as alias tell application "Finder" set aParent to parent of anAlias set aFolName to name of anAlias end tell set aParent to aParent as alias set preCMD to "cd " & quoted form of POSIX path of aParent set tarCMD to "tar cvf " & quoted form of (aFolName & ".tar") & " " & quoted form of (aFolName & "/") try set aRes to do shell script (preCMD & " && " & tarCMD) on error return false end try tell application "Finder" set tarAlias to ((aParent as string) & aFolName & ".tar") as alias set tarEx to exists of tarAlias end tell if tarEx = true then return tarAlias else return false end if end tarFolder |
指定のtarアーカイブを展開する
AppleScript名:指定のtarアーカイブを展開する |
set a to choose file with prompt ".tarファイルを指定してください" set b to extractTar(a) of me –指定tarアーカイブを展開する on extractTar(a) set anAlias to a as alias tell application "Finder" set aParent to parent of anAlias set aFileName to name of anAlias end tell set aParent to aParent as alias set preCMD to "cd " & quoted form of POSIX path of aParent set tarCMD to "tar xf " & quoted form of (aFileName) try set aRes to do shell script (preCMD & " && " & tarCMD) on error return false end try set newName to text 1 thru -5 of aFileName –展開後の、".tar"を除去した名前 set extractFol to (aParent as string) & newName & ":" try return (extractFol as alias) on error return false end try end extractTar |
テキストのキーワード検索(ファイルから読み込んで検索。複数結果対応)
AppleScript名:テキストの複数検索(ファイルから読み込んで検索) |
— Created 2017-08-09 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" property NSString : a reference to current application’s NSString property NSMutableArray : a reference to current application’s NSMutableArray property NSDate : a reference to current application’s NSDate property NSLiteralSearch : a reference to current application’s NSLiteralSearch set aFile to POSIX path of (choose file) set a1Dat to NSDate’s timeIntervalSinceReferenceDate() set aStr to NSString’s stringWithContentsOfFile:aFile encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value) set aRes to searchWordRanges(aStr, "子供") of me as list –> {{location:1159, length:2}, {location:1242, length:2}, {location:1261, length:2}, ….. set b1Dat to NSDate’s timeIntervalSinceReferenceDate() set c1Dat to b1Dat – a1Dat on searchWordRanges(aTargText as string, aSearchStr as string) set aStr to NSString’s stringWithString:aTargText set bStr to NSString’s stringWithString:aSearchStr set hitArray to NSMutableArray’s alloc()’s init() set cNum to (aStr’s |length|()) as integer set aRange to current application’s NSMakeRange(0, cNum) repeat set detectedRange to aStr’s rangeOfString:bStr options:(NSLiteralSearch) range:aRange if detectedRange’s location is equal to current application’s NSNotFound then exit repeat hitArray’s addObject:detectedRange set aNum to (detectedRange’s location) as integer set bNum to (detectedRange’s |length|) as integer set aRange to current application’s NSMakeRange(aNum + bNum, cNum – (aNum + bNum)) end repeat return hitArray end searchWordRanges |
指定フォルダ以下のすべてのファイルのうち指定UTIに該当するものを取得(spotlightで処理)
AppleScript名:指定フォルダ以下のすべてのファイルを再帰で取得(spotlightで処理).scpt |
use AppleScript version "2.4" use framework "Foundation" use scripting additions use mdLib : script "Metadata Lib" version "1.0.0" –https://www.macosxautomation.com/applescript/apps/Script_Libs.html#Metadata_Lib –set theFolder to choose folder set theFolder to (path to desktop folder) set theFiles to mdLib’s searchFolders:{theFolder} searchString:"kMDItemContentType IN[c] %@" searchArgs:{"com.apple.applescript.script", "com.apple.applescript.script-bundle"} |
指定フォルダ以下のすべてのファイルを再帰で取得 v2
指定フォルダ以下のすべてのファイルを再帰で取得するAppleScriptです。
「指定フォルダ以下のファイルを取得する」やりかたは、Spotlightを使うのがベストです。ベストではあるものの、各ユーザーのHDDなりSSDは「破損している」ケースもあって、Spotligtの検索が効かない場合もあります。
また、マウントしたLAN上のファイルサーバーに対してSpotlightが効くかどうかは実際にやってみないと分かりません。OSが異なる可能性がありますし、同じmacOSであっても効くかどうかは実際に試してみるまではっきりしません(開発時に真っ先に確認するポイントでもあります。ファイルサーバーを相手に処理するつもりかどうかの確認です)。
そこで、地道に再帰処理でファイルを取得すること「も」試してみることになるわけですが、ここでFinderを使うと遅くなります。
OS X 10.6以降の64ビット化されたいわゆる「Cocoa Finder」は処理速度が低下しているため、大量のファイル処理をFinder経由で行うことは「悪手」といえます。数百個ぐらいでけっこうな処理速度の低下がみられます。1,000を超えると露骨に速度が下がります。フィルタ参照で条件をつけて抽出するのも速度低下につながります。さらに複数のフィルタ条件を指定するとアホみたいに遅くなります。Cocoa Finderの性能低下はハンパではありません。
たまに、Classic Mac OSの環境しか知らない人が久しぶりに現代の(64ビット化された)macOS上で昔と同じようにFinderに対して膨大なファイルの処理を行わせて「遅い」と文句を言っているのを見かけますが、Finder経由でのファイル処理が現実的ではないという状況を知らなければそういう感想になってしまうかもしれません。
# Classic MacOS〜macOS 10.6ぐらいまではFinder経由で行っても、極端に時間がかかることはありませんでした。それ以降の環境のお話です。また、macOS 10.7以降でも、数個〜数十程度のすくないファイルを処理する場合には、あまり問題になりません
そこで、NSFileManagerを用いてファイル処理を行うことで、「Spotlightほど速くはないものの、Finderで処理するよりははるかに高速」な処理を行えます。
AppleScript名:指定フォルダ以下のすべてのファイルを再帰で取得 v2 |
— Created 2017-08-04 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" property NSString : a reference to current application’s NSString property NSPredicate : a reference to current application’s NSPredicate property NSFileManager : a reference to current application’s NSFileManager property NSMutableArray : a reference to current application’s NSMutableArray –set aFol to POSIX path of (choose folder) set aFol to POSIX path of (path to desktop folder) –set aList to retFullPathWithinAFolderWithRecursive(aFol) of me set bList to retFullPathWithinAFolderWithRecursiveFilterByExt(aFol, "scpt") of me –set cList to retFilenameWithinAFolderWithRecursiveFilterByExt(aFol, {"scpt", "scptd"}) of me –set dList to retFullPathWithinAFolderWithRecursiveFilterByExtAndFileNameString(aFol, "png", "スクリーン") of me –set eList to retFullPathWithinAFolderWithRecursiveFilterByExtAndFileNameString(aFol, {"scpt", "scptd"}, "並列") of me –指定フォルダ以下のすべてのファイルを再帰で取得 on retFilenamesWithinAFolderWithRecursive(aFol) set anArray to NSMutableArray’s array() set aPath to NSString’s stringWithString:aFol set dirEnum to NSFileManager’s defaultManager()’s enumeratorAtPath:aPath repeat set aName to (dirEnum’s nextObject()) if aName = missing value then exit repeat set aFullPath to aPath’s stringByAppendingPathComponent:aName anArray’s addObject:(aFullPath’s lastPathComponent()’s stringByDeletingPathExtension() as string) end repeat return anArray as list end retFilenamesWithinAFolderWithRecursive –指定フォルダ以下のすべてのファイルを再帰で取得 on retFullPathWithinAFolderWithRecursive(aFol) set anArray to NSMutableArray’s array() set aPath to NSString’s stringWithString:aFol set dirEnum to NSFileManager’s defaultManager()’s enumeratorAtPath:aPath repeat set aName to (dirEnum’s nextObject()) if aName = missing value then exit repeat set aFullPath to aPath’s stringByAppendingPathComponent:aName anArray’s addObject:(aFullPath’s lastPathComponent()’s stringByDeletingPathExtension() as string) end repeat return anArray as list end retFullPathWithinAFolderWithRecursive –指定フォルダ以下のすべてのファイルを再帰で取得(拡張子で絞り込み) on retFilenameWithinAFolderWithRecursiveFilterByExt(aFol, aExt) set anArray to NSMutableArray’s array() set aPath to NSString’s stringWithString:aFol set dirEnum to NSFileManager’s defaultManager()’s enumeratorAtPath:aPath repeat set aName to (dirEnum’s nextObject()) if aName = missing value then exit repeat set aFullPath to aPath’s stringByAppendingPathComponent:aName anArray’s addObject:aFullPath end repeat set thePred to NSPredicate’s predicateWithFormat:"pathExtension == [c]%@" argumentArray:{aExt} set bArray to anArray’s filteredArrayUsingPredicate:thePred return bArray as list end retFilenameWithinAFolderWithRecursiveFilterByExt –指定フォルダ以下のすべてのファイルを再帰で取得(拡張子で絞り込み) on retFullPathWithinAFolderWithRecursiveFilterByExt(aFol, aExt) set anArray to NSMutableArray’s array() set aPath to NSString’s stringWithString:aFol set dirEnum to NSFileManager’s defaultManager()’s enumeratorAtPath:aPath repeat set aName to (dirEnum’s nextObject()) if aName = missing value then exit repeat set aFullPath to aPath’s stringByAppendingPathComponent:aName anArray’s addObject:aFullPath end repeat set thePred to NSPredicate’s predicateWithFormat:"pathExtension == [c]%@" argumentArray:{aExt} set bArray to anArray’s filteredArrayUsingPredicate:thePred return bArray as list end retFullPathWithinAFolderWithRecursiveFilterByExt –指定フォルダ以下のすべてのファイルを再帰で取得(拡張子リストで絞り込み) on retFullPathWithinAFolderWithRecursiveFilterByExtList(aFol, aExtList) set anArray to NSMutableArray’s array() set aPath to NSString’s stringWithString:aFol set dirEnum to NSFileManager’s defaultManager()’s enumeratorAtPath:aPath repeat set aName to (dirEnum’s nextObject()) if aName = missing value then exit repeat set aFullPath to aPath’s stringByAppendingPathComponent:aName anArray’s addObject:aFullPath end repeat set thePred to NSPredicate’s predicateWithFormat:"pathExtension IN [c]%@" argumentArray:{aExtList} set bArray to anArray’s filteredArrayUsingPredicate:thePred return bArray as list end retFullPathWithinAFolderWithRecursiveFilterByExtList –指定フォルダ以下のすべてのファイルを再帰で取得(文字列と拡張子で絞り込み) on retFullPathWithinAFolderWithRecursiveFilterByExtListAndFileNameString(aFol, aExt, aNameString) set anArray to NSMutableArray’s array() set aPath to NSString’s stringWithString:aFol set dirEnum to NSFileManager’s defaultManager()’s enumeratorAtPath:aPath repeat set aName to (dirEnum’s nextObject()) if aName = missing value then exit repeat set aFullPath to aPath’s stringByAppendingPathComponent:aName anArray’s addObject:aFullPath end repeat set thePred to NSPredicate’s predicateWithFormat:"pathExtension == [c]%@ && lastPathComponent CONTAINS %@" argumentArray:{aExt, aNameString} set bArray to anArray’s filteredArrayUsingPredicate:thePred return bArray as list end retFullPathWithinAFolderWithRecursiveFilterByExtListAndFileNameString –指定フォルダ以下のすべてのファイルを再帰で取得(文字列と拡張子リストで絞り込み) on retFullPathWithinAFolderWithRecursiveFilterByExtAndFileNameString(aFol, aExtList, aNameString) set anArray to NSMutableArray’s array() set aPath to NSString’s stringWithString:aFol set dirEnum to NSFileManager’s defaultManager()’s enumeratorAtPath:aPath repeat set aName to (dirEnum’s nextObject()) if aName = missing value then exit repeat set aFullPath to aPath’s stringByAppendingPathComponent:aName anArray’s addObject:aFullPath end repeat set thePred to NSPredicate’s predicateWithFormat:"pathExtension IN [c]%@ && lastPathComponent CONTAINS %@" argumentArray:{aExtList, aNameString} set bArray to anArray’s filteredArrayUsingPredicate:thePred return bArray as list end retFullPathWithinAFolderWithRecursiveFilterByExtAndFileNameString |
PDFをページごとに分解してJPEGで保存する v3
AppleScript名:PDFをページごとに分解してJPEGで保存する v3 |
— 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–Zero padding function, Consider Retina Env — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "Quartz" 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 –1.0 — 0.0 = max jpeg compression, 1.0 = none –Detect Retina Environment set retinaF to current application’s 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 –PDFをページごとに分割してJPEGでファイル書き出し repeat with i from 0 to (pCount – 1) –Pick Up a PDF page as an image 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) –Resize Image set pointSize to thisDoc’s |size|() set newSize to current application’s NSMakeSize((pointSize’s width) * aScale, (pointSize’s height) * aScale) set newImage to (current application’s NSImage’s alloc()’s initWithSize:newSize) newImage’s lockFocus() (thisDoc’s setSize:newSize) (current application’s NSGraphicsContext’s currentContext()’s setImageInterpolation:(current application’s NSImageInterpolationHigh)) (thisDoc’s drawAtPoint:(current application’s NSZeroPoint) fromRect:(current application’s CGRectMake(0, 0, newSize’s width, newSize’s height)) operation:(current application’s NSCompositeCopy) fraction:1.0) newImage’s unlockFocus() –Save Image as JPEG set theData to newImage’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 |
画像の指定エリアを塗りつぶし
▲Before
▲After
AppleScript名:画像の指定エリアを塗りつぶし |
— Created 2017-11-19 by Takaaki Naganoya — Modified 2018-02-14 by Takaaki Naganoya use AppleScript version "2.5" use scripting additions use framework "Foundation" use framework "AppKit" property NSUUID : a reference to current application’s NSUUID property NSColor : a reference to current application’s NSColor 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 NSBezierPath : a reference to current application’s NSBezierPath property NSPNGFileType : a reference to current application’s NSPNGFileType property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep –塗りつぶしエリア(複数) set drawList to {{origin:{x:0, y:0}, |size|:{width:200, height:100}}, {origin:{x:300, y:100}, |size|:{width:50, height:50}}} set imgPath to POSIX path of (choose file of type {"public.image"}) set anImage to NSImage’s alloc()’s initWithContentsOfFile:imgPath set fillColor to (NSColor’s colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:0.9) –塗りつぶし処理呼び出し set resImage to drawImageWithColorFill(anImage, drawList, fillColor) of me set aUUIDstr to (NSUUID’s UUID()’s UUIDString()) as string set aPath to ((NSString’s stringWithString:imgPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:"png" set fRes to saveImageRepAtPathAsPNG(resImage, aPath) of me on drawImageWithColorFill(anImage, drawList, fillColor) set retinaF to (NSScreen’s mainScreen()’s backingScaleFactor()) as real –> 2.0 (Retina) / 1.0 (Non Retina) anImage’s lockFocus() –描画開始 repeat with i in drawList set origX to (x of origin of i) / retinaF set origY to (y of origin of i) / retinaF set sizeX to (width of |size| of i) / retinaF set sizeY to (height of |size| of i) / retinaF set theRect to {{x:origX, y:origY}, {width:sizeX, height:sizeY}} set theNSBezierPath to NSBezierPath’s bezierPath (theNSBezierPath’s appendBezierPathWithRect:theRect) fillColor’s |set|() –色設定 theNSBezierPath’s fill() –ぬりつぶし end repeat anImage’s unlockFocus() –描画ここまで return anImage –returns NSImage end drawImageWithColorFill –画像を指定パスにPNG形式で保存 on saveImageRepAtPathAsPNG(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)) return (myNewImageData’s writeToFile:newPath atomically:true) as boolean end saveImageRepAtPathAsPNG |
表示中のCotEditor書類の「前」のファイルを縦書きでオープン v2
CotEditorでオープン中の書類の「前」のファイルを縦書きでオープンするAppleScriptです。
CotEditorでオープン中の書類のパスを取得して、同一フォルダ内にあるファイル名一覧からオープン中の書類の「前」に該当する書類をオープンします。
ファイルオープン後にCotEditorのメニューをGUI Scriptingで強制的に操作して縦書きに設定します。
CotEditor v3.3.2のメニューにバグがあって、横書きのメニュー項目にも縦書きのメニュー項目にも「縦書き」と書いてあり、メニュー項目を名称で指定するとうまく動きません。そこだけItem No.で指定しています。このメニュー項目の不具合については、近い将来のアップデートで修正される見込みです。
▲CotEditor内蔵のScript Menuから実行するとGUI Scriptingの実行が制限されて縦書きにならない
▲OS側のScript Menuから実行すると問題なく実行できる
AppleScript名:表示中のCotEditor書類の「前」のファイルを縦書きでオープン v2 |
— Created 2017-12-15 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use bPlus : script "BridgePlus" property |NSURL| : a reference to current application’s |NSURL| property NSArray : a reference to current application’s NSArray property NSString : a reference to current application’s NSString property SMSForder : a reference to current application’s SMSForder property NSPredicate : a reference to current application’s NSPredicate property NSFileManager : a reference to current application’s NSFileManager property NSMutableArray : a reference to current application’s NSMutableArray property NSSortDescriptor : a reference to current application’s NSSortDescriptor property NSURLIsPackageKey : a reference to current application’s NSURLIsPackageKey property NSURLIsDirectoryKey : a reference to current application’s NSURLIsDirectoryKey property NSDirectoryEnumerationSkipsHiddenFiles : a reference to current application’s NSDirectoryEnumerationSkipsHiddenFiles property NSDirectoryEnumerationSkipsPackageDescendants : a reference to current application’s NSDirectoryEnumerationSkipsPackageDescendants property NSDirectoryEnumerationSkipsSubdirectoryDescendants : a reference to current application’s NSDirectoryEnumerationSkipsSubdirectoryDescendants load framework tell application "CotEditor" set dCount to count every document if dCount = 0 then return tell front document set curPath to path end tell tell window 1 set aBounds to bounds end tell end tell set aPath to NSString’s stringWithString:curPath set fileName to (aPath’s lastPathComponent()) –ファイル名 set pathExtension to aPath’s pathExtension() as string set parentFol to (aPath’s stringByDeletingLastPathComponent()) as string —親フォルダ –同じフォルダから同じ拡張子のファイルのファイル名を取得 set fList to my getFilesByIncludedStringInName:(pathExtension) fromDirectory:(parentFol) exceptPackages:(true) –昇順ソート set aArray to NSArray’s arrayWithArray:fList set desc1 to NSSortDescriptor’s sortDescriptorWithKey:"self" ascending:true selector:"localizedCaseInsensitiveCompare:" set bArray to aArray’s sortedArrayUsingDescriptors:{desc1} –ファイル名検索 –set aIndex to bArray’s indexOfObjectIdenticalTo:fileName set aIndex to (SMSForder’s indexesOfItem:fileName inArray:bArray inverting:false) as list if aIndex = {} then display notification "Error: File Not Found" return end if set bIndex to (contents of first item of aIndex) + 1 – 1 –0 based to 1 based conversion & previous one set aLen to length of (bArray as list) if bIndex > aLen then display notification "Error: Out of bounds" return end if set newFile to contents of item bIndex of (bArray as list) set newPath to parentFol & "/" & newFile tell application "CotEditor" set oldDoc to front document open (POSIX file newPath) as alias tell window 1 set bounds to aBounds end tell close oldDoc without saving end tell makeWinVertical() of me –縦書き表示 –指定フォルダ内の指定文字列を含むファイル名のファイルをPOSIX pathのlistで抽出する on getFilesByIncludedStringInName:(fileNameStr as string) fromDirectory:(sourceFolder) exceptPackages:(packageF as boolean) set fileManager to NSFileManager’s defaultManager() set aURL to |NSURL|’s fileURLWithPath:sourceFolder set theOptions to ((NSDirectoryEnumerationSkipsPackageDescendants) as integer) + ((NSDirectoryEnumerationSkipsHiddenFiles) as integer) + ((NSDirectoryEnumerationSkipsSubdirectoryDescendants) as integer) set directoryContents to fileManager’s contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:theOptions |error|:(missing value) set findPredicates to NSPredicate’s predicateWithFormat_("lastPathComponent CONTAINS %@", fileNameStr) set foundItemList to directoryContents’s filteredArrayUsingPredicate:findPredicates –Remove Folders From found URL Array set anArray to NSMutableArray’s alloc()’s init() repeat with i in foundItemList set j to contents of i set {theResult, isDirectory} to (j’s getResourceValue:(reference) forKey:(NSURLIsDirectoryKey) |error|:(missing value)) –Collect files if (isDirectory as boolean = false) then (anArray’s addObject:j) else if (packageF = false) then –Allow Package files? set {theResult, isPackage} to (j’s getResourceValue:(reference) forKey:(NSURLIsPackageKey) |error|:(missing value)) if (isPackage as boolean) = true then (anArray’s addObject:j) end if end if end repeat return (anArray’s valueForKey:"lastPathComponent") as list end getFilesByIncludedStringInName:fromDirectory:exceptPackages: –Make CotEditor’s front window to Vertical display mode (Tategaki) on makeWinVertical() activate application "CotEditor" tell application "System Events" tell process "CotEditor" try click menu item 3 of menu 1 of menu item "文章の方向" of menu 1 of menu bar item "フォーマット" of menu bar 1 end try end tell end tell end makeWinVertical |
表示中のCotEditor書類の「次」のファイルを縦書きでオープン v2
CotEditorでオープン中の書類の「次」のファイルを縦書きでオープンするAppleScriptです。
CotEditorでオープン中の書類のパスを取得して、同一フォルダ内にあるファイル名一覧からオープン中の書類の「次」に該当する書類をオープンします。
ファイルオープン後にCotEditorのメニューをGUI Scriptingで強制的に操作して縦書きに設定します。
CotEditor v3.3.2のメニューにバグがあって、横書きのメニュー項目にも縦書きのメニュー項目にも「縦書き」と書いてあり、メニュー項目を名称で指定するとうまく動きません。そこだけItem No.で指定しています。このメニュー項目の不具合については、近い将来のアップデートで修正される見込みです。
▲CotEditor内蔵のScript Menuから実行するとGUI Scriptingの実行が制限されて縦書きにならない
▲OS側のScript Menuから実行すると問題なく実行できる
AppleScript名:表示中のCotEditor書類の「次」のファイルを縦書きでオープン v2 |
— Created 2017-12-15 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use bPlus : script "BridgePlus" property |NSURL| : a reference to current application’s |NSURL| property NSArray : a reference to current application’s NSArray property NSString : a reference to current application’s NSString property SMSForder : a reference to current application’s SMSForder property NSPredicate : a reference to current application’s NSPredicate property NSFileManager : a reference to current application’s NSFileManager property NSMutableArray : a reference to current application’s NSMutableArray property NSSortDescriptor : a reference to current application’s NSSortDescriptor property NSURLIsPackageKey : a reference to current application’s NSURLIsPackageKey property NSURLIsDirectoryKey : a reference to current application’s NSURLIsDirectoryKey property NSDirectoryEnumerationSkipsHiddenFiles : a reference to current application’s NSDirectoryEnumerationSkipsHiddenFiles property NSDirectoryEnumerationSkipsPackageDescendants : a reference to current application’s NSDirectoryEnumerationSkipsPackageDescendants property NSDirectoryEnumerationSkipsSubdirectoryDescendants : a reference to current application’s NSDirectoryEnumerationSkipsSubdirectoryDescendants load framework tell application "CotEditor" set dCount to count every document if dCount = 0 then return tell front document set curPath to path end tell tell window 1 set aBounds to bounds end tell end tell set aPath to NSString’s stringWithString:curPath set fileName to (aPath’s lastPathComponent()) –ファイル名 set pathExtension to aPath’s pathExtension() as string set parentFol to (aPath’s stringByDeletingLastPathComponent()) as string —親フォルダ –同じフォルダから同じ拡張子のファイルのファイル名を取得 set fList to my getFilesByIncludedStringInName:(pathExtension) fromDirectory:(parentFol) exceptPackages:(true) –昇順ソート set aArray to NSArray’s arrayWithArray:fList set desc1 to NSSortDescriptor’s sortDescriptorWithKey:"self" ascending:true selector:"localizedCaseInsensitiveCompare:" set bArray to aArray’s sortedArrayUsingDescriptors:{desc1} –ファイル名検索 set aIndex to (SMSForder’s indexesOfItem:fileName inArray:bArray inverting:false) as list if aIndex = {} then display notification "Error: File Not Found" return end if set bIndex to (contents of first item of aIndex) + 1 + 1 –0 based to 1 based conversion & next one set aLen to length of (bArray as list) if bIndex > aLen then display notification "Error: Out of bounds" return end if set newFile to contents of item bIndex of (bArray as list) set newPath to parentFol & "/" & newFile tell application "CotEditor" set oldDoc to front document open (POSIX file newPath) as alias tell window 1 set bounds to aBounds end tell close oldDoc without saving end tell makeWinVertical() of me –縦書き表示 –指定フォルダ内の指定文字列を含むファイル名のlistを抽出する on getFilesByIncludedStringInName:(fileNameStr as string) fromDirectory:(sourceFolder) exceptPackages:(packageF as boolean) set fileManager to NSFileManager’s defaultManager() set aURL to |NSURL|’s fileURLWithPath:sourceFolder set theOptions to (NSDirectoryEnumerationSkipsPackageDescendants as integer) + (NSDirectoryEnumerationSkipsHiddenFiles as integer) + (NSDirectoryEnumerationSkipsSubdirectoryDescendants as integer) set directoryContents to fileManager’s contentsOfDirectoryAtURL:aURL includingPropertiesForKeys:{} options:theOptions |error|:(missing value) set findPredicates to NSPredicate’s predicateWithFormat_("lastPathComponent CONTAINS %@", fileNameStr) set foundItemList to directoryContents’s filteredArrayUsingPredicate:findPredicates –Remove Folders From found URL Array set anArray to NSMutableArray’s alloc()’s init() repeat with i in foundItemList set j to contents of i set {theResult, isDirectory} to (j’s getResourceValue:(reference) forKey:(NSURLIsDirectoryKey) |error|:(missing value)) –Collect files if (isDirectory as boolean = false) then (anArray’s addObject:j) else if (packageF = false) then –Allow Package files? set {theResult, isPackage} to (j’s getResourceValue:(reference) forKey:(NSURLIsPackageKey) |error|:(missing value)) if (isPackage as boolean) = true then (anArray’s addObject:j) end if end if end repeat return (anArray’s valueForKey:"lastPathComponent") as list end getFilesByIncludedStringInName:fromDirectory:exceptPackages: –Make CotEditor’s front window to Vertical display mode (Tategaki) on makeWinVertical() activate application "CotEditor" tell application "System Events" tell process "CotEditor" try click menu item 3 of menu 1 of menu item "文章の方向" of menu 1 of menu bar item "フォーマット" of menu bar 1 end try end tell end tell end makeWinVertical |
指定フォルダ以下のテキストファイルのファイル名冒頭についている数字から欠番を求める
AppleScript名:指定フォルダ以下のテキストファイルのファイル名冒頭についている数字から欠番を求める |
— Created 2017-09-04 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use framework "Foundation" use scripting additions use mdLib : script "Metadata Lib" version "1.0.0" –https://www.macosxautomation.com/applescript/apps/Script_Libs.html#Metadata_Lib use bPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html property NSString : a reference to current application’s NSString property SMSForder : a reference to current application’s SMSForder property NSIndexSet : a reference to current application’s NSIndexSet property NSMutableSet : a reference to current application’s NSMutableSet property NSMutableArray : a reference to current application’s NSMutableArray property NSRegularExpression : a reference to current application’s NSRegularExpression property NSRegularExpressionAnchorsMatchLines : a reference to current application’s NSRegularExpressionAnchorsMatchLines property NSRegularExpressionDotMatchesLineSeparators : a reference to current application’s NSRegularExpressionDotMatchesLineSeparators load framework –BridgePlus’s force framework loading command –選択したフォルダ以下のPlain TextをすべてSpotlightで求める(POSIX path list) set theFolder to (choose folder) set a1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate() set aRes to retMissingNumberFromEachFiles(theFolder, {"public.plain-text"}) of me –> {} set b1Dat to current application’s NSDate’s timeIntervalSinceReferenceDate() set c1Dat to b1Dat – a1Dat on retMissingNumberFromEachFiles(theFolder, fileTypeList) set theFiles to mdLib’s searchFolders:{theFolder} searchString:"kMDItemContentType IN[c] %@" searchArgs:fileTypeList if theFiles = {} then return –取得したPOSIX Pathのリストからファイル名の部分のみ抽出 set anArray to NSMutableArray’s arrayWithArray:theFiles set bArray to (anArray’s valueForKeyPath:"lastPathComponent") as list –各ファイルの名称の冒頭から1~3桁 の数字を取り出して、全角–>半角変換を行いつつリストに追加 set nArray to NSMutableArray’s new() repeat with i in bArray set j to contents of i set aRes to (my findPattern:"^\\d{1,3}" inString:j) if aRes is not equal to {} then set jj to (contents of first item of aRes) as string set jj2 to (SMSForder’s transformedFrom:jj ICUTransform:"Fullwidth-Halfwidth" inverse:false) as integer (nArray’s addObject:jj2) end if end repeat –最大値、最小値をもとに連番リストを作成し、ファイル名から得られた配列データとの補集合を求める set maxRes to (nArray’s valueForKeyPath:"@max.self")’s intValue() set minRes to (nArray’s valueForKeyPath:"@min.self")’s intValue() –最小値から最大値までの連番リスト作成 set theIndexSet to NSIndexSet’s indexSetWithIndexesInRange:{minRes, maxRes} set theList to (SMSForder’s arrayWithIndexSet:theIndexSet) as list set aSet to NSMutableSet’s setWithArray:theList set bSet to NSMutableSet’s setWithArray:nArray aSet’s minusSet:bSet –補集合 return (aSet’s allObjects() as list) end retMissingNumberFromEachFiles on findPattern:thePattern inString:theString set theOptions to ((NSRegularExpressionDotMatchesLineSeparators) as integer) + ((NSRegularExpressionAnchorsMatchLines) as integer) set theRegEx to NSRegularExpression’s regularExpressionWithPattern:thePattern options:theOptions |error|:(missing value) set theFinds to theRegEx’s matchesInString:theString options:0 range:{location:0, |length|:length of theString} set theFinds to theFinds as list set theResult to {} set theNSString to NSString’s stringWithString:theString repeat with i in theFinds set theRange to (contents of i)’s range() set end of theResult to (theNSString’s substringWithRange:theRange) as string end repeat return theResult end findPattern:inString: |
指定フォルダ以下の指定形式の書類をすべてもとめて拡張子をはずしたファ
AppleScript名:指定フォルダ以下の指定形式の書類をすべてもとめて拡張子をはずしたファイル名に重複がないかチェック v2 |
— Created 2017-10-28 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use mdLib : script "Metadata Lib" version "1.0.0" –https://www.macosxautomation.com/applescript/apps/Script_Libs.html#Metadata_Lib set docUTIList to {"net.daringfireball.markdown", "com.apple.iwork.pages.sffpages"} set origFol to (choose folder) set dRes to detectDocNameDuplicateWithoutExt(origFol, docUTIList) of me –> true / false –origFolはaliasでもPOSIX pathでも可 on detectDocNameDuplicateWithoutExt(origFol, docTypeList as list) script spdMD property allResList : {} end script set (allResList of spdMD) to {} repeat with i in docTypeList set j to contents of i set aResList to (mdLib’s searchFolders:{origFol} searchString:("kMDItemContentTypeTree CONTAINS %@") searchArgs:{j}) if aResList = missing value or aResList = {} then –Hitしなかった else set (allResList of spdMD) to (allResList of spdMD) & aResList end if end repeat set aLen to length of contents of (allResList of spdMD) if aLen = 0 then error "No match" set anArray to current application’s NSArray’s arrayWithArray:(allResList of spdMD) set aRes to anArray’s valueForKeyPath:"lastPathComponent.stringByDeletingPathExtension" set b1Res to uniquify1DList(aRes as list, true) of me set b1Len to length of b1Res if aLen = b1Len then return true — No Duplicates else return false –Some duplicates end if end detectDocNameDuplicateWithoutExt –1D/2D Listをユニーク化 on uniquify1DList(theList as list, aBool as boolean) set aArray to current application’s NSArray’s arrayWithArray:theList set bArray to aArray’s valueForKeyPath:"@distinctUnionOfObjects.self" return bArray as list end uniquify1DList |
指定フォルダ以下の指定形式の書類をすべてもとめてファイル名に重複がないかチェック
AppleScript名:指定フォルダ以下の指定形式の書類をすべてもとめてファイル名に重複がないかチェック |
— Created 2017-10-28 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use mdLib : script "Metadata Lib" version "1.0.0" set origFol to POSIX path of (choose folder) set aResList to mdLib’s searchFolders:{origFol} searchString:("kMDItemContentTypeTree CONTAINS %@ || kMDItemContentTypeTree CONTAINS %@") searchArgs:{"net.daringfireball.markdown", "com.apple.iwork.pages.sffpages"} if aResList = missing value or aResList = {} then return false end if set anArray to current application’s NSArray’s arrayWithArray:aResList set aRes to anArray’s valueForKeyPath:"lastPathComponent" set bLen to length of (aRes as list) set b1Res to uniquify1DList(aRes as list, true) of me set b1Len to length of b1Res if bLen = b1Len then display dialog "No Duplicates" else display dialog "Some Duplicates" end if on getSameItemsInLists(aList as list, bList as list) –ASオブジェクトをCocoaオブジェクトに変換 set aArray to current application’s NSArray’s arrayWithArray:aList set bArray to current application’s NSArray’s arrayWithArray:bList — まとめる set allSet to current application’s NSMutableSet’s setWithArray:aArray allSet’s addObjectsFromArray:bArray –重複する要素のみ抜き出す set duplicateSet to current application’s NSMutableSet’s setWithArray:aArray duplicateSet’s intersectSet:(current application’s NSSet’s setWithArray:bArray) –重複部分だけを返す set resArray to duplicateSet’s allObjects() set resList to resArray as list return resList end getSameItemsInLists –1D/2D Listをユニーク化 on uniquify1DList(theList as list, aBool as boolean) set aArray to current application’s NSArray’s arrayWithArray:theList set bArray to aArray’s valueForKeyPath:"@distinctUnionOfObjects.self" return bArray as list end uniquify1DList |
指定ファイルのUTIを取得
AppleScript名:Vanilla Scriptで指定ファイルのUTIを求める |
set aFile to choose file
tell application "System Events" set aUTI to type identifier of aFile return aUTI end tell |
AppleScript名:指定ファイルのUTIを取得 |
— Created 2016-10-24 by Takaaki Naganoya — Modified 2016-10-25 by Shane Stanley — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use BridgePlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html set aFile to POSIX path of (choose file) set aUTI to retFileFormatUTIFromPath(aFile) of me on retFileFormatUTIFromPath(aPOSIXpath as string) load framework set aPath to current application’s NSString’s stringWithString:aPOSIXpath set aExt to (aPath’s pathExtension()) as string return (current application’s SMSForder’s UTIForExtension:aExt) as list of string or string –as anything end retFileFormatUTIFromPath |
AppleScript名:指定ファイルのUTIを取得 v2.scptd |
use AppleScript version "2.5" — El Capitan (10.11) or later use framework "Foundation" use scripting additions property |NSURL| : a reference to current application’s |NSURL| property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey set aPath to POSIX path of (choose file) set utiRes to retUTIfromPath(aPath) of me on retUTIfromPath(aPOSIXPath) set aURL to |NSURL|’s fileURLWithPath:aPOSIXPath set {theResult, theValue} to aURL’s getResourceValue:(reference) forKey:NSURLTypeIdentifierKey |error|:(missing value) if theResult = true then return theValue as string else return theResult end if end retUTIfromPath |
iBooksライブラリ中のepubファイルから情報を取得 v3
AppleScript名:iBooksライブラリ中のepubファイルから情報を取得 v3 |
— Created 2017/02/26 by Christopher Stone — Modified 2017/11/01 by Takaaki Naganoya use framework "Foundation" use scripting additions use mdLib : script "Metadata Lib" version "1.0.0" –https://www.macosxautomation.com/applescript/apps/Script_Libs.html#Metadata_Lib property NSString : a reference to current application’s NSString property NSMutableArray : a reference to current application’s NSMutableArray property NSPropertyListFormat : a reference to current application’s NSPropertyListFormat property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding property NSPropertyListImmutable : a reference to current application’s NSPropertyListImmutable property NSPropertyListSerialization : a reference to current application’s NSPropertyListSerialization set aPath to POSIX path of (path to library folder from user domain) set sourceFolder to aPath & "Containers/com.apple.BKAgentService/Data/Documents/iBooks/Books/" set textFiles to mdLib’s searchFolders:{sourceFolder} searchString:"kMDItemContentType contains %@ || kMDItemContentType contains %@ " searchArgs:{"com.apple.ibooks-folder", "org.idpf.epub-container"} set outDicList to NSMutableArray’s new() repeat with i in textFiles set aFile to (i as string) if aFile ends with "/" then set aFullPath to aFile & "iTunesMetadata.plist" else set aFullPath to aFile & "/iTunesMetadata.plist" end if try set xmlData to read ((POSIX file aFullPath) as alias) as «class utf8» set xRes to readPlistFromStr(xmlData) of me log xRes as list of string or string –as anything (maybe record or missing value) (*cover-writing-mode:vertical, genre:教育, scroll-axis:default, sort-artist:あっぷる, BKITunesMigratedMetadata:PersistentID:6.68315366592803E+18, seriesTitle:Everyone Can Code, sort-name:Swiftによるあぷりけーしょん開発:入門編, itemId:1209648719, apple-id:xxxxxxxxxxxx@xxx.xxx, fileExtension:ibooks, year:2017, releaseDate:2017-03-19T07:00:00Z, BKInsertionDate:512115887, asset-info:flavor:pluspub, file-size:60642970, book-info:publication-version:162901775, PageProgression:default, asset-info:flavor:pluspub, file-size:60642970, package-file-hash:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX, BKAllocatedSize:82993152, longDescription:このコースでは、Swiftという言語を使って基本的なプログラミングの土台をしっかりと作り上げていきます。基本的なiOSアプリケーションを一から開発するために必要なツール、手法、概念を活用して、実践的な練習に取り組みます。さらに、プログラミングと優れたアプリケーション開発の土台となる、ユーザーインターフェイス設計の基本原則についても学習します。このコースを受講するにあたってプログラミングの経験は必要ありません。プログラミングの経験がある場合、レッスンの最初の方は簡単に読み進めていただくとよいでしょう。このブックではプログラミングの基礎にとどまらず、ソフトウェア開発ツールや概念、ベストプラクティスについても学習できます。, artistId:9.39801385E+8, artistName:Apple Education, isPreview:false, BKDisplayName:mzbf.eqmpijqw..d2.dlv.d2.dlv.ibooks, human-friendly-publication-version:1.1, shouldDisableTouchEmulation:true, vendorId:379015, drmVersionNumber:0, kind:ebook, s:143462, genreId:10037, explicit:2, seriesAdamId:1.118575554E+9, publisher:Apple Inc. – Education, versionRestrictions:16843008, BKGenerationCount:2, desktopSupportLevel:supported, primaryLanguage:ja, itemName:Swiftによるアプリケーション開発:入門編, purchaseDate:2017-03-25T06:21:26Z, shouldDisableOptimizeSpeed:true, obeyPageBreaks:1, pageCount:244*) if xRes is not equal to missing value then (outDicList’s addObject:xRes) end if end try end repeat return outDicList as list of string or string –as anything –stringのplistを読み込んでNSDictionaryに on readPlistFromStr(theString) set aSource to NSString’s stringWithString:theString set pListData to aSource’s dataUsingEncoding:(NSUTF8StringEncoding) set aPlist to NSPropertyListSerialization’s propertyListFromData:pListData mutabilityOption:(NSPropertyListImmutable) |format|:(NSPropertyListFormat) errorDescription:(missing value) return aPlist end readPlistFromStr |
画像を文字認識して文字エリアを塗りつぶし v3
▲Original Image
▲Filtered Image(CIColorMonochrome)
▲Filtered Image(CIColorPosterize)
▲Result Image
AppleScript名:画像を文字認識して文字エリアを塗りつぶし v3 |
— Created 2017-11-19 by Takaaki Naganoya — Modified 2018-02-11 by Takaaki Naganoya –v3:画像の前処理を付加 use AppleScript version "2.5" use scripting additions use framework "Foundation" use framework "AppKit" use framework "QuartzCore" use framework "AppKit" set retinaF to (current application’s NSScreen’s mainScreen()’s backingScaleFactor()) as real –> 2.0 (Retina) / 1.0 (Non Retina) set imgPath to POSIX path of (choose file of type {"public.image"}) set anImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:imgPath set aCIImage to convNSImageToCIimage(anImage) –モノクロ化フィルタ set bCIImage to monochromefilterACGImage(aCIImage) of me –2階調ポスタライズフィルタ set cCIImage to posterizefilterACGImage(bCIImage) of me –文字領域認識 set detectList to textDetect(cCIImage) of me –描画開始 anImage’s lockFocus() repeat with i in detectList set origX to (x of origin of i) / retinaF set origY to (y of origin of i) / retinaF set sizeX to (width of |size| of i) / retinaF set sizeY to (height of |size| of i) / retinaF set theRect to {{x:origX, y:origY}, {width:sizeX, height:sizeY}} set theNSBezierPath to current application’s NSBezierPath’s bezierPath (theNSBezierPath’s appendBezierPathWithRect:theRect) set rRnd to (random number from 1 to 10) / 10 set gRnd to (random number from 1 to 10) / 10 set bRnd to (random number from 1 to 10) / 10 set fillColor to (current application’s NSColor’s colorWithCalibratedRed:rRnd green:gRnd blue:bRnd alpha:0.6) fillColor’s |set|() –色設定 theNSBezierPath’s fill() –ぬりつぶし end repeat anImage’s unlockFocus() –描画ここまで set aUUIDstr to (current application’s NSUUID’s UUID()’s UUIDString()) as string set aPath to ((current application’s NSString’s stringWithString:imgPath)’s stringByDeletingLastPathComponent()’s stringByAppendingPathComponent:aUUIDstr)’s stringByAppendingPathExtension:"png" set fRes to saveImageRepAtPathAsPNG(anImage, aPath) of me on openImageFile(imageFile) — imageFile: POSIX path 形式のファイルパス set fileURL to current application’s |NSURL|’s fileURLWithPath:imageFile return current application’s CIImage’s alloc()’s initWithContentsOfURL:fileURL end openImageFile –画像を指定パスにPNG形式で保存 on saveImageRepAtPathAsPNG(anImage, outPath) set imageRep to anImage’s TIFFRepresentation() set aRawimg to current application’s NSBitmapImageRep’s imageRepWithData:imageRep –書き出しファイルパス情報を作成 set pathString to current application’s NSString’s stringWithString:outPath set newPath to pathString’s stringByExpandingTildeInPath() –書き出し set myNewImageData to (aRawimg’s representationUsingType:(current application’s NSPNGFileType) |properties|:(missing value)) return (myNewImageData’s writeToFile:newPath atomically:true) as boolean end saveImageRepAtPathAsPNG on textDetect(imageRef) — 検出器のオプションを NSDictonary で作成 set optDic1 to current application’s NSDictionary’s dictionaryWithObject:(current application’s CIDetectorAccuracyHigh) forKey:(current application’s CIDetectorAccuracy) set textDetector to current application’s CIDetector’s detectorOfType:(current application’s CIDetectorTypeText) context:(missing value) options:optDic1 — 文字エリア検出を実行 set optDic2 to current application’s NSDictionary’s dictionaryWithObject:true forKey:(current application’s CIDetectorReturnSubFeatures) set textArray to textDetector’s featuresInImage:imageRef options:optDic2 set fList to {} — 検出されたテキストの位置とサイズをログに出力 repeat with i from 1 to (count of textArray) set typeFace to item i of textArray set bList to (typeFace’s subFeatures()) repeat with ii in bList set aBounds to ii’s |bounds|() set aType to ii’s type() set the end of fList to aBounds end repeat end repeat return fList end textDetect on convCIimageToNSImage(aCIImage) set aRep to current application’s NSBitmapImageRep’s alloc()’s initWithCIImage:aCIImage set tmpSize to aRep’s |size|() set newImg to current application’s NSImage’s alloc()’s initWithSize:tmpSize newImg’s addRepresentation:aRep return newImg end convCIimageToNSImage on convNSImageToCIimage(aNSImage) set tiffDat to aNSImage’s TIFFRepresentation() set aRep to current application’s NSBitmapImageRep’s imageRepWithData:tiffDat set newImg to current application’s CIImage’s alloc()’s initWithBitmapImageRep:aRep return newImg end convNSImageToCIimage –Posterizeフィルタ on posterizefilterACGImage(aCIImage) set aFilter to current application’s CIFilter’s filterWithName:"CIColorPosterize" aFilter’s setDefaults() aFilter’s setValue:aCIImage forKey:"inputImage" aFilter’s setValue:2 forKey:"inputLevels" set aOutImage to aFilter’s valueForKey:"outputImage" return aOutImage end posterizefilterACGImage –Monochromeフィルタ on monochromefilterACGImage(aCIImage) set aFilter to current application’s CIFilter’s filterWithName:"CIColorMonochrome" aFilter’s setDefaults() aFilter’s setValue:aCIImage forKey:"inputImage" aFilter’s setValue:1.0 forKey:"inputIntensity" set aOutImage to aFilter’s valueForKey:"outputImage" return aOutImage end monochromefilterACGImage |
JPEG画像の破損チェック
かつて、破損JPEG画像はアプリケーションのクラッシュを引き起こすケースもあり、Mac OS Xでもなかなか細心の注意をはらって事前のチェックを行なっていました(Mac OS X 10.4のころ)。
AppleScriptによるバッチ処理では、大量のデータを相手にします。そのため、途中でエラーを発生させるようなイレギュラーなデータにはエラートラップを仕掛けてあらかじめ対処しておきますが、クラッシュを引き起こすような破損データについては事前に手の施しようがありません。
# 破損画像によるクラッシュが発生して処理が停止するトラブルに直面したときには、入稿データの添付画像の破損チェックを自動で行うようにして対処しました。そもそも破損していては話にならないので
この破損画像が引き起こすクラッシュは(iOSの方で)クラッカーからの格好の標的にされたため(初期の「脱獄」の手口がこの破損画像にともなうクラッシュ→実行権限乗っ取りでした)、対策がすすみ、iOSと共通基盤を持っているMac OS Xでも同様の対策が行われたためか、Mac OS X→OS X→macOSと呼称が変わるにつれて徐々にクラッシュしないように強化されてきた機能でもあります。
今日、破損画像にそれほど神経質にならなくても済むようになっていますが、古いOSを使い続けている環境がないわけではありません。そうした環境においては、画像処理前の破損画像のチェックは重要な処理であり続けることでしょう。
また、巨大な画像データを遅い回線/サーバー経由でダウンロードして処理する場合には、「念のため」チェックを行なっておくべきかもしれません。
本ScriptのようにJPEGマーカーの有無をチェックするのは、破損画像検出の手口としては入門レベルであり、画像処理を行うプログラムで実際に読み込み+表示+書き出しを行わせるぐらいの処理をしておく必要があります(読み込めて表示できても、書き出しができない破損画像にも遭遇しました)。
実際にさまざまな現場で集めた「破損画像」は、大切に自分の手元に集めてあります。
AppleScript名:JPEG画像の破損チェック |
— Created 2006-10-17 by Somebody — Modified 2015-10-06 by Takaaki Naganoya set aFile to choose file of type {"public.jpeg"} set dRes to VerifyCompleteJPEG(aFile) of me — to verify whether a JPEG is a111 full or partial (e.g. partially downloaded) JPEG — last two JPEG file bytes must be (ASCII character 255) & (ASCII character 217) on VerifyCompleteJPEG(f) try set s to read f from -2 for 2 on error return false –error "JPEG image is too short or currupted" end try if s = (ASCII character 255) & (ASCII character 217) then return true else return false end if end VerifyCompleteJPEG |