画像を読む 11

画像データを macOSのスピーチ機能で読むプログラムを書いています。前ページでも書いたように、開発の大体の方向はありますが、最終的な形を現在考えている訳ではありません。制作ノートと思って読んでください。誰かの役に立つようにスクリプトを公開しています。



ナビゲーションとワーク・ウインドウ

2つ作ったウインドウの一つをナビゲーションの為だけとしました。データを読み上げが終わった時点と、次のデータに移るタイミングの調整が微妙で、4000〜5000ミリセコンドくらいのインターバルが良いようです。

スタック・ウインドウ「navWd」に書き込んだスクリプト。
on openStack
   -- プログラムを開いた時「ワーク・ウインドウ」も同時に開く
   open stack "LWd"
   set the hilited of btn "open2nd" of stack "navWd" to true
end openStack

-- ビデオのスクリーン・ショットを作成しているLCファイルと
-- 同じフォルダー内にテンポで格納するファイル・パスを取得するファンクション
function theFolderPath
   if the environment is "development" then  
      set the itemDel to "/"
      return item 1 to -2 of the filename of this stack
   else   
      put the fileName of this stack into tPath
      set the itemDel to "/"
      switch the platform
         case "MacOS"
            put item 1 to -5 of tPath into tResult
            break
         case "Win32"
            put item 1 to -2 of tPath into tResult
            break
      end switch
      return tResult
   end if
end theFolderPath

「navWd」のカード1に書き込んだスクリプト
-- モザイクのアレイ(配列)をグローバルにする
global gMosaicArray

-- 「02モザイク」で書いたドラッグ&ドロップ(一部修正)
on dragEnter
   set the acceptDrop to true
end dragEnter

on dragDrop
   put dragData["files"] into tPath
   if word 1 of the target is "player" then
      set the filename of the target to ("file://"&tPath) 
      snapshotVideo 
      set the tOriginalData of image "tImage" of stack "LWd" \
            to the imageData of image "tImage" of stack "LWd" 
      set the endTime of player "tVideo" to the duration of player "tVideo"
      set the endvalue of sb "timeBar" to the duration of player "tVideo"
      set the thumbpos of sb "timeBar" to 0
      set the currentTime of player "tVideo" to the 0
      set the thumbpos of sb "mosaicBar" to 100
      makeMosaic 
   else
      beep
      exit to top
   end if
end dragDrop

-- 動いているビデオ画面をスクリーン・ショットするコマンド
-- ロケーションはグローバルにしないといけない
command snapshotVideo 
   export snapshot from rect globalLoc(the topLeft of player "tVideo"), \
         globalLoc(the bottomRight of player "tVideo") to \
         file theFolderPath() & "/snap/videoSnap.jpg" as JPEG
end snapshotVideo

command makeMosaic  
   -- スクリーン・ショットをモザイクにしてワーク・ウインドウにセット
   put the rect of player "tVideo" of  of stack "navWd" into tRectImage
   put the width of player "tVideo" of  of stack "navWd" into tWidth
   put the height of player "tVideo" of stack "navWd" into tHeight
   set the rect of image "tImageS" of stack "navWd" to tRectImage 
   set the text of image "tImageS" of stack "navWd" to \
         url ("binfile:" & theFolderPath() & "/snap/videoSnap.jpg")   
   put  (the thumbpos of sb "mosaicBar" / 100) into tPercent
   set the width of image "tImageS" of stack "navWd" to tWidth * tPercent
   set the height of image "tImageS" of stack "navWd" to tHeight * tPercent
   set the width of image "tImage" of stack "LWd" \
         to the width of image "tImageS" of stack "navWd"
   set the height of image "tImage" of stack "LWd" \
         to the height of image "tImageS" of stack "navWd" 
   set the imagedata of image "tImage" of stack "LWd" \
         to the imagedata of image "tImageS" of stack "navWd" 
   set the rect of image "tImage" of stack "LWd" \
         to the rect of cd 1 of stack "LWd"
   set the loc of image "tImageS" of stack "navWd" to \
         -500, item 2 of the loc of player "tVideo" of stack "navWd"
end makeMosaic

ファンクション「mosaicArray」にバグがあったので、次に修正しています。バグはイメージ・データのマルチ・アレイ(多層配列)をASCIIで扱ったのでASCIIに行替えシンボルが混じっていたので、正確な配列を作れないのが原因でした。 修正はASCIIを10進数に変換してから配列としました。
function mosaicArray  --バグです。
   -- image "tImageS" のアレイのファンクション
   put the width of image "tImageS" of stack "navWd" into tWidth
   put the height of image "tImageS" of stack "navWd" into tHeight
   get the imagedata of image "tImageS" of stack "navWd"
   put "" into mosaicArray
   repeat with j=1 to tHeight 
      if j=1 then
         repeat with i=1 to (tWidth * 4 * j) step 4
            put char i to (i +3) of it & tab after mosaicArray
            if i >= (tWidth * 4 -4 ) then
               put cr after mosaicArray
               exit repeat
            end if
         end repeat
      else
         if j>1 then
            repeat with i=tWidth * 4 * (j -1)+1 to tWidth * 4 * j step 4 
               put char i to (i +3) of it & tab after mosaicArray
               if i >= (tWidth * 4 * j ) then
                  put cr after mosaicArray
                  exit repeat
               end if
            end repeat
         end if
      end if
   end repeat
   return mosaicArray
end mosaicArray

function halfPixMosaic
   -- モザイクの位置の中心を得るためのファンクション
   put (the width of image "tImage" of stack "LWd" / \
         the width of image "tImageS" of stack "navWd") / 2 , \
         (the height of image "tImage" of stack "LWd" / \
         the height of image "tImageS" of stack "navWd") / 2 into tHalfPix
   return tHalfPix
end halfPixMosaic

ファンクション「mosaicArray」のバグ修正に伴って、「mosaicArray」で得られた10進数を扱うファンクション「mosaicRGB」に、次回修正します。
function mosaicRGB tRandomWidth, tRandomHeight  -- 次回バグを修正します
   -- モザイクのRGBカラー値を得るファンクション
   put gMosaicArray into mosaicRow 
   split mosaicRow by row
   set itemDel to tab
   -- ロケーションのX,Y値を「mosaicRow」に入れてピクセルのバイナリを得る
   put item tRandomWidth of mosaicRow[tRandomHeight] into tRGB

   -- 得られたピクセル・データのバイナリの始めはアルファなので
   -- アイテム2から4までを数値に変換
   put charToNum(char 2 of tRGB) \
         &", " & charToNum(char 3 of tRGB)\
         &", " & charToNum(char 4 of tRGB) into tRGB
  
   -- 変換した数値が得られなかったら空白を返す
   if tRGB is ", , " then put "" into tRGB
   if tRGB is not "" then 
      return "RGB Value: " & tRGB
   else
      return ""
   end if
end mosaicRGB

「TimeBar」ビデオ・プレイヤーのコントロール(スクロール)・バー内
-- ビデオプレイをキャンセルして止めるID
global gVideoTimerID 

on mouseUp
   get the thumbpos of sb "timeBar" 
   set the currentTime of player "tVideo" to it
   -- ビデオを止めた時点で画像をスクリーン・ショットする
   snapshotVideo 
end mouseUp

on mouseDown 
  -- ビデオプレイをキャンセルして止める
  cancel gVideoTimerID 
end mouseDown

「PlayVideo」ビデオ・プレイヤーをスタートするボタン
-- グローバル: モザイク・アレイとビデオを止めるID
global gMosaicArray, gVideoTimerID  
-- ローカル:このボタン内だけでハンドラーをまたいで使用する
local tRandomWidth, tRandomHeight


on mouseUp 
-- ビデオ・プレイヤーにファイル名がセットされていない場合ハンドラーを抜ける
   emptyFileName "tVideo" 
   start player "tVideo"
   videoTimer 
end mouseUp

-- ビデオ・プレイヤーにファイル名がセットされていない場合ハンドラーを抜ける
command emptyFileName pPlayerName
   if the filename of player pPlayerName is empty then
      beep
      exit to top
   end if
end emptyFileName

command videoTimer
   put the hilitedButtonName of grp "tInterval" into tInterval
   send videoTimer to me in tInterval milliseconds
   
   -- このハンドラーをキャンセルする際のID
   put the result into gVideoTimerID
   set the thumbpos of sb "timeBar" to the currentTime of player "tVideo"
   snapshotVideo  --// 現時点のビデオのスナップをJPEGでファイルする
   makeMosaic  -- // スナップショットをモザイクに
   
   -- ランダムにロケーションを選ぶコマンド
   randomLoc 
   
   -- ビデオ・プレイヤーが最後まで行ったら、IDでキャンセルしてストップ
   -- 全ての処理をする
   if the thumbpos of sb "timeBar" is the endValue of sb "timeBar" then
      cancel gVideoTimerID   -- コマンド「videoTimer」キャンセル
      set the thumbpos of sb "timeBar" to 0
      set the currentTime of player "tVideo" to the 0
      stop player "tVideo"
      snapshotVideo 
      cancel gVideoTimerID
      stop player "tVideo"
      wait 100
      hide grc "tRect" of stack "LWd"
      put "" into fld "tRGB" of stack "LWd"
   end if
end videoTimer


-- ランダムにロケーションを選ぶコマンド
command randomLoc 
   put the loc of grc "tRect" of stack "LWd" into tOldLoc
   
   -- モザイクの位置からランダムを
   put random(the width of image "tImageS" of stack "navWd") \
         into tRandomWidth
   put random(the height of image "tImageS" of stack "navWd") \
         into tRandomHeight
         
   -- ワーク・ウインドウの1つのモザイクの半分のサイズ(モザイクの中央値を出すため)
   put halfPixMosaic() into tHalfPix
   
   -- ワーク・ウインドウのイメージ上のロケーション
   put ceiling((item 1 of tHalfPix * tRandomWidth * 2 \
         - item 1 of tHalfPix)), ceiling((item 2 of tHalfPix * \
         tRandomHeight * 2 - item 2 of tHalfPix)) into tRandomLoc 
   -- カンマを1000の単位と読み間違えないように空白を入れる
   replace "," with ", " in tRandomLoc 
   
   -- ロケーションを示すグラフィックを見せる
   show grc "tRect" of stack "LWd"
   
   -- 「navWd」のボタン「tSpeak」がハイライトの場合
   if the hilite of btn "tSpeaK" is true then
      --// スピーク・ロケーション & RGB値 //--
      speakLoc tRandomLoc   
      put "Location: " & tRandomLoc &cr & mosaicRGB(tRandomWidth, \
            tRandomHeight) into fld "tRGB" of stack "LWd"
   end if
   
   -- グラフィック「tRect」をロケーションに移動
   move grc "tRect" of stack "LWd" from tOldLoc to tRandomLoc in 30 ticks
end randomLoc

command speakLoc pLoc
   put the hilitedButtonName of grp "readSpeed" of stack "navWd" into tSpeed
   revSetSpeechVoice (fld "tVoice" of stack "navWd")
   revSetSpeechVolume 130
   revSetSpeechSpeed tSpeed
   
  -- パラメータ「pText」を読み上げる 
   revspeak pLoc
end speakLoc


「Pause Video」と「Stop Video」は、ほとんど前と同じ


モザイク・ビデオとセカンド・ウインドウ

モザイク・ビデオとセカンド・ウインドウ 2




アーチスト:小島健治 / Artist: Kenji Kojima

アーチスト:小島健治
kenjikojima.com


クリエイティブ・コモンズ
Attribution-NonCommercial-NoDerivatives

Click and Go to PayPal

日本からのドネーションは こちらをクリック

LiveCode 6 初心者開発入門