【Excel VBA】VBAプロジェクトのロックを強制的に解除する【マクロ】

※自作マクロのパスワードを忘れちゃったときなど、常識の範囲で実施しましょう。
※解除は全て自己責任で実施してください。何かあっても一切の責任を負いません。


通常であれば、「マクロ パスワード解除」とかでググれば沢山の方法が見つかります。

例えば
www.saka-en.com

neos21.hatenablog.com

tristore.net


このへんでしょうか。
まずはこれで試してください。

今回は、上記方法でダメだった場合の"もしかしたら"解除出来る方法について記載します。
※解除できなくても責めないでくださいね


まず、こちらに記載されているコードを標準モジュールに貼り付けます。
Excel VBAマクロ パスワード解除方法 | ホームページ制作のサカエン(墨田区)

すると、こんな感じのエラーになってしまいました。
f:id:puu_0328:20170608163735p:plain


Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Long, Source As Long, ByVal Length As Long)
Private Declare FunctionVirtualProtect Lib "kernel32" (lpAddress As Long, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As Long, ByVal pTemplateName As Long, ByVal hWndParent As Long, ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As Long


ダメ元で実行してみます。
f:id:puu_0328:20170608164911p:plain


当然ですが、エラーになります。
どうやらこのコードは32bit用なので、64bitには対応していないようです。
f:id:puu_0328:20170608164949p:plain


とりあえず、以下のエラー内容でググります。


コンパイルエラー:

このプロジェクトのコードは、64 ビット システムで使用するために

更新する必要があります。Declare ステートメントの確認および更新

を行い、次に Declare ステートメントに PtrSafe 属性を設定してく

ださい。


見つけました。
piyopiyocs.blog115.fc2.com

↑記事によると、「Declare」の後ろに「PtrSafe」をつければよいと書いています。

試してみると、たしかにコードが赤くなくなった!
f:id:puu_0328:20170608165537p:plain

いざ、実行!!!!!!





f:id:puu_0328:20170608165601p:plain






ガーン..._| ̄|○


問題となっているのは、ココ
f:id:puu_0328:20170608165751p:plain


仕方ないので更にググります。

すると発見!!!!!
Cracking Excel VBA Password 64-bit and 32-bitcalebhengeveld.wordpress.com


こちらには32bitと64bitの両方のコードを書いてくれています。

使っているExcelは64bit版なので、こちらのコードをモジュール1に貼り付けます。

Option Explicit

Private Const PAGE_EXECUTE_READWRITE = &H40

Private Declare PtrSafe Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As LongPtr, Source As LongPtr, ByVal Length As LongPtr)

Private Declare PtrSafe Function VirtualProtect Lib "kernel32" (lpAddress As LongPtr, _
ByVal dwSize As LongPtr, ByVal flNewProtect As LongPtr, lpflOldProtect As LongPtr) As LongPtr

Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As LongPtr

Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, _
ByVal lpProcName As String) As LongPtr

Private Declare PtrSafe Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer

Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean

Private Function GetPtr(ByVal Value As LongPtr) As LongPtr
    GetPtr = Value
End Function

Public Sub RecoverBytes()
    If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub

Public Function Hook() As Boolean
    Dim TmpBytes(0 To 5) As Byte
    Dim p As LongPtr
    Dim OriginProtect As LongPtr

    Hook = False

    pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")


    If VirtualProtect(ByVal pFunc, 6, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then

        MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 6
        If TmpBytes(0) <> &H68 Then

            MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 6

            p = GetPtr(AddressOf MyDialogBoxParam)

            HookBytes(0) = &H68
            MoveMemory ByVal VarPtr(HookBytes(1)), ByVal VarPtr(p), 4
            HookBytes(5) = &HC3

            MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 6
            Flag = True
            Hook = True
        End If
    End If
End Function

Private Function MyDialogBoxParam(ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer

    If pTemplateName = 4070 Then
        MyDialogBoxParam = 1
    Else
        RecoverBytes
        MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
                   hWndParent, lpDialogFunc, dwInitParam)
        Hook
    End If
End Function


更にモジュール2にこれを貼り付けます。

Sub unprotected()
    If Hook Then
        MsgBox "VBA Project is unprotected!", vbInformation, "*****"
    End If
End Sub


マクロの実行で[unprotected]を実行します。
f:id:puu_0328:20170608171113p:plain




結果は...?











f:id:puu_0328:20170608171357p:plain

できました!!
VBA Project is unprotected!」
が表示されたら成功です。




よかったよかった\(^o^)/

Google Cloud Platform に登録してCloud Vision APIの画像認識機能をお試ししてみる②

Google Cloud Platform の登録方法、Cloud Vision APIの画像認識機能の使い方

こちらを参照してください。puu-0328.hatenablog.com



①ラベル検出(LABEL_DETECTION)

ラベル検出(LABEL_DETECTION)は乗り物や動物など、画像に写っているさまざまなカテゴリの物体を検出できます。

まずは分かりやすく、この猫の写真でやってみます(ΦωΦ)

息切れしているオス猫(スコティッシュフォールド)|ぱくたそフリー写真素材
f:id:puu_0328:20170516164237p:plain

結果

   "labelAnnotations": [		
    {		
     "mid": "/m/01yrx",		
     "description": "cat",		
     "score": 0.9912357		

ちゃんとdescription(実行結果)に"cat"が返ってきました。
midというのは、画像を判断するために必要な一意のIDです。
scoreは画像を読み取った精度でが~1の範囲で返されます。
今回はかなり1に近いので、精度が高い(descriptionが信用できる)ことがわかります。




次は体が隠れてしまっている猫..

さびしいにゃん|ぱくたそフリー写真素材
f:id:puu_0328:20170516165023p:plain

結果

   "labelAnnotations": [
    {
     "mid": "/m/083jv",
     "description": "white",
     "score": 0.9419842
    }

description(実行結果)は"white"でした
間違った結果のくせに、精度が高い(自信満々)ですね。。



最後は手描きの猫です。

ペイントで描いた猫
f:id:puu_0328:20170516165814p:plain


結果

   "labelAnnotations": [		
    {		
     "mid": "/m/0215n",		
     "description": "cartoon",		
     "score": 0.86530787		
    }		


description(実行結果)は"cartoon(漫画)"でした。
精度はまあまあといった感じでしょうか。


②顔検出(FACE_DETECTION)

画像に含まれる複数の人物の顔を検出できます。
感情の状態や帽子の着用といった主要な顔の属性についても識別されます。
ただし、個人を特定する顔認識には対応していません。


顔検出は人物の表情だけでなく、目鼻の位置など返ってくる値が多いです。
参考:Method: images.annotate  |  Google Cloud Vision API  |  Google Cloud Platform

今回は、下表の結果のみ掲載します。

フィールド名 意味
detectionConfidence 顔検出の精度(0~1)
landmarkingConfidence 顔の各パーツを検出した精度(0~1)
joyLikelihood 顔が楽しんでいるか
sorrowLikelihood 顔が悲しんでいるか
angerLikelihood 顔が怒っているか
"surpriseLikelihood 顔が驚いているか
nderExposedLikelihood 肌の露出度)
blurredLikelihood 画像がぼやけているか
headwearLikelihood 帽子かなにかを被っているか

また、結果は精度(0~1)と以下の5段階で返ってきます。

結果 意味
VERY_LIKELY 非常に当てはまる
LIKELY あてはまる
UNKNOWN 不明
UNLIKELY 当てはまらない
VERY_UNLIKELY 全く当てはまらない


まずは、笑顔たっぷりのこの写真でやってみます

満面の笑みの女の子|ぱくたそフリー写真素材
f:id:puu_0328:20170516171921p:plain

結果

"detectionConfidence": 0.5244219,					
"landmarkingConfidence": 0.52761644,					
"joyLikelihood": "VERY_LIKELY",					
"sorrowLikelihood": "VERY_UNLIKELY",					
"angerLikelihood": "VERY_UNLIKELY",					
"surpriseLikelihood": "VERY_UNLIKELY",					
"underExposedLikelihood": "VERY_UNLIKELY",					
"blurredLikelihood": "VERY_UNLIKELY",					
"headwearLikelihood": "UNLIKELY"

_______日本語訳_______

顔検出の精度: 0.5244219(半分くらい)
顔の各パーツを検出した精度:0.52761644(半分くらい)
顔が楽しんでいるか:非常に当てはまる
顔が悲しんでいるか:全く当てはまらない
顔が怒っているかいるか:全く当てはまらない
顔が驚いているか:全く当てはまらない
肌の露出度:全く当てはまらない
画像がぼやけているか:全く当てはまらない
帽子か何かを被っているのか:当てはまらない			

画像のままの結果となりました。


次はこのように、目が隠れている画像です。

いちご少女|ぱくたそフリー写真素材
f:id:puu_0328:20170516172322p:plain

結果

200		
- Show headers -		
{		
 "responses": [		
  {		
  }		
 ]		
}	

何も返ってきませんでした。
どうやら、顔として検出できなかったようです。



最後は、この何tも言えない表情です。
人間に「どういう感情だと思う?」と聞いても答えが分かれそうですね
ちなみに、「腕っぷし自慢のウェーイ系 」という画像だそう。。

腕っぷし自慢のウェーイ系|ぱくたそフリー写真素材
f:id:puu_0328:20170516172739p:plain

結果

     "detectionConfidence": 0.99624336,
     "landmarkingConfidence": 0.683373,
     "joyLikelihood": "UNLIKELY",
     "sorrowLikelihood": "VERY_UNLIKELY",
     "angerLikelihood": "VERY_UNLIKELY",
     "surpriseLikelihood": "VERY_UNLIKELY",
     "underExposedLikelihood": "VERY_UNLIKELY",
     "blurredLikelihood": "VERY_UNLIKELY",
     "headwearLikelihood": "VERY_LIKELY"

_______日本語訳_______


顔検出の精度: 0.99624336(かなり精度が高い)
顔の各パーツを検出した精度:0.683373(まあまあ)
顔が楽しんでいるか:当てはまらない
顔が悲しんでいるか:全く当てはまらない
顔が怒っているかいるか:全く当てはまらない
顔が驚いているか:全く当てはまらない
肌の露出度:当てはまらない
画像がぼやけているか:全く当てはまらない
帽子か何かを被っているのか:非常に当てはまる
	

感情についてはUNNOWN(不明)が返ってくるかと思ったら、
どれも当てはまらない結果となりました。

帽子はちゃんと被っていることが認識されていますね。
(不自然なカツラの人とか、人工知能で見抜けるかも(^o^))



OCR:光学式文字認識(TEXT_DETECTION)

画像内のテキストを検出、抽出できます。幅広い言語がサポートされ、言語の種類も自動で判別されます。

こちらも結果が多いので、locale(文字の言語)とdescription(結果)のみ記載します。



まずは適当感満載の手作り画像で実践

てすと
f:id:puu_0328:20170516173719p:plain

結果

     "locale": "ja",
     "description": "てすとテストtest\n",

正しくdescription(実行結果)に"てすとテストtest\n"が返ってきました。
文字がはっきりしていれば、日本語と英語が混ざっていても問題なさそうです。
言語も"ja"(日本語)となっています。


次はこの記号/日本語/英語/ハングル文字が混ざった画像

出口への案内板|ぱくたそフリー写真素材
f:id:puu_0328:20170516174238p:plain

結果

     "locale": "lb",				
     "description": "58EE\n「Ir\nEE\nExit\n",				

「58EE  Ir  EE Exit」とは。。

ひどい結果。。( ;∀;)
かろうじて、「Exit」は読めているので出口であることは認識できるか。。と言った感じですね。
言語は"lb"だそう。 あまり馴染みがないですが、「インド・ヨーロッパ語族ルクセンブルク語」であってるのかな?(・.・;)





最後は人で作られた文字

人文字[英数字/記号]|ぱくたそフリー写真素材
f:id:puu_0328:20170516175212p:plain

結果

     "locale": "su",
     "description": "HELLO wo NLD\n",	


HELLO wo NLD。。
まあ、少し小文字にされたり、'R'が'N'と認識されたりしていますが、上出来のような気がします。
これなら手書き文字とかでも大丈夫かも。

言語は"su"(オーストロネシア語族:スンダ語)らしいです。。


最後に

今回は物体認識、感情認識、文字認識とやってみました。
精度は微妙ですが、条件分岐なんかで工夫すれば結構使えそうです。

今回は「Cloud Vision API 」を使って結果を取得しましたが、
実際にプログラム上でリクエスト送信&レスポンス取得についてやってみようと思います。

TortoiseSVNでコロン(:)などの無効な文字を含んだフォルダでブランチを作成してしまったとき【備忘録】

状況

TortoiseSVNで「半角コロン(:)やバックスラッシュ(\)といった、フォルダ名として無効な文字を含めてブランチを作成してしまいました。

Windows7では以下の通り、「\ / : * ? " < > |」といった文字が使えません。
f:id:puu_0328:20170516134740p:plain

それが何らかのタイミングでブランチを作成しちゃってたというものです(T_T)

このせいで、SVN更新でエラーとなったり、当該フォルダを削除も名前の変更もできない状態です。


もしファイルやフォルダが作成されただけであれば、こちらで対応できるようです。
www.atmarkit.co.jp


しかし、バージョン管理されている場合は当該フォルダをローカルで削除できても、その後SVNにコミットする必要があります。
だけど、SVN上に無効な文字が含まれているため、削除したことをコミットできない。。
そしてリポジトリブラウザからも「ファイル名、ディレクトリ名、またはボリュームラベルの構文が間違っています」
といったエラーが表示されてしまい、リネームや削除できない状況になりました。



そもそも何故無効な文字でブランチを作成できたのか

作成日時を確認してみると、eclipce上でブランチの作業をしているタイミングで作成していたようです。
→切り替えしようとしてエラーが発生した。
→つまり、eclipse上では無効な文字を含むフォルダを作成できる??
→作成できるということはリネームもできる!!!??

という発想になり、さっそくeclipseを起動
SVN リポジトリー・エクスプローラー」を表示。
f:id:puu_0328:20170516142043p:plain

SVNリポジトリーの当該フォルダを右クリックし、[リファクタリング]>[名前変更(R)...]を選択します。
f:id:puu_0328:20170516142737p:plain

名前を変更し、[OK]をクリックします。
f:id:puu_0328:20170516143012p:plain


これで、無効な文字がSVN上にも含まれなくなり、
正常にコミットや更新が行えるようになります。

いや~、ほんとうに焦りました。。なんとか対応できて良かったです(^^)

Google Cloud Platform に登録してCloud Vision APIの画像認識機能をお試ししてみる①

Cloud Vision APIとは

参照:Vision API - 画像コンテンツ分析  |  Google Cloud Platform
Google Cloud Vision API は、使いやすい REST API にパワフルな機械学習モデルが
組み込まれており、画像の内容を認識するアプリケーションの開発を可能にします。
Google Cloud Vision API は、膨大な数のカテゴリ(「ヨット」や「ライオン」、
エッフェル塔」など)に各画像を素早く分類する機能や、画像内の個々の物体や
人の顔を検出する機能、画像内に含まれているテキストを検出して読み取る機能を備えています。

また、画像カタログのメタデータ作成、不適切なコンテンツの管理、画像の感情分析を通じた
新しいマーケティング手法の導入が可能になります。
リクエストでアップロードされた画像を分析することも、Google Cloud Storage の
画像ストレージに統合することもできます。


ざっくりいうと、画像をCloud Vision APIに送れば、画像内の情報を人工知能が読取り、結果を返しますよ~
という感じでしょうか。



何ができるのか?

Method: images.annotate  |  Google Cloud Vision API  |  Google Cloud Platformによると

機能 指定するタイプ 説明
ラベル検出 LABEL_DETECTION 乗り物や動物など、画像に写っているさまざまなカテゴリの物体を検出できます。
顔検出 FACE_DETECTION 画像に含まれる複数の人物の顔を検出できます。感情の状態や帽子の着用といった主要な顔の属性についても識別されます。 ただし、個人を特定する顔認識には対応していません。
有害コンテンツ検出 SAFE_SEARCH_DETECTION アダルト コンテンツや暴力的コンテンツなど、画像に含まれる有害コンテンツを検出できます。
画像特性 IMAGE_PROPERTIES ドミナント カラーなど、画像の一般的特性を検出できます。
ロゴ検出 LOGO_DETECTION 画像に含まれる一般的な商品ロゴを検出できます。
ランドマーク検出 LANDMARK_DETECTION 画像に含まれる一般的な自然のランドマークや人工建造物を検出できます。
光学式文字認識(OCR TEXT_DETECTION 画像内のテキストを検出、抽出できます。幅広い言語がサポートされ、言語の種類も自動で判別されます。

といった機能が使えるようです。

すごいですね~(*^^*)
これらの機能を手作業でプログラミングしようとすると、とてつもなく大変ですが、
Cloud Vision APIであれば、適当な画像とパラメータを渡してやるだけで実現できるんです。
人工知能やドローン、VRなどなど色んな用途が考えられます。

2017/05/16 追記
いろいろ試した結果をこちらに載せました。↓
puu-0328.hatenablog.com





事前準備
Googleアカウント
これがないと始まりません。
Googleアカウントをお持ちでない方は、下記のリンクからGoogleアカウントを作成してください。
Google アカウントの作成
クレジット(デビットカード
Google Cloud Platform を利用するにはクレジット(デビット)カードが必要です。
手作業で課金しなければ、勝手に引き落としされることはありませんが、クレカ情報を入力するのに抵抗がある方は諦めてください(T_T)




Google Cloud Platformの登録

下記リンクにアクセスし、画面右上の[無料トライアル]をクリックします。

Vision API - 画像コンテンツ分析  |  Google Cloud Platform
f:id:puu_0328:20170515130444p:plain


国:[日本]を選択し、受託:機能についてメールでお知らせを受け取りたい場合のみ[はい]を選択。
利用規約を確認したら、[はい]を選択して[同意して続行]をクリックします。
f:id:puu_0328:20170515131003p:plain


支払いの請求先とクレジットカードを登録します。

支払いを現在ログインしているアカウントに請求する場合は初期表示のまま、その他の必須項目に入力します。
f:id:puu_0328:20170515134823p:plain



その他の請求先にしたい場合は[お支払いプロファイルを作成]を選択して各入力項目に入力します。
f:id:puu_0328:20170515134511p:plain


クレジット(デビット)カードの情報まで入力します。
また、クレジットカードの情報を登録しても、自動的に請求されることはありません。
すべて入力できたら、[無料トライアルを開始]をクリックします。
f:id:puu_0328:20170515135132p:plain



このような画面に遷移したら、登録完了です。
f:id:puu_0328:20170515135652p:plain






Cloud Vision APIを試す

Google Cloud Platform の検索フォームに「Cloud Vision」と入力すると
候補に[Google Cloud Vision API]が表示されるので、[Google Cloud Vision API]をクリックします。
f:id:puu_0328:20170515181506p:plain


[▶有効にする]を押下します。
f:id:puu_0328:20170515165133p:plain




Cloud Vision APIが有効になったことを確認したら、[このAPIAPI Explorerで試す]をクリックします。
f:id:puu_0328:20170515140457p:plain


[vision.images.annotate]をクリックします。
f:id:puu_0328:20170515165511p:plain


パラメータを指定します。
ここでは、「OCRの(光学文字認識)機能(TEXT_DETECTION)」を用いて、画像にどのような物体が含まれているか認識してみます。


[Request body]にJSON形式でパラメータを渡します。
Cloud Vision API のリクエストとレスポンス  |  Google Cloud Vision API ドキュメント  |  Google Cloud Platform
を参照すると以下のような形式で渡せばよい事がわかります。

{
"requests":[
    {
      "image":{
        "content":"/9j/7QBEUGhvdG9...image contents...eYxxxzj/Coa6Bax//Z"(渡したい画像(BASE64形式))
      },
      "features":[
        {
          "type":"LABEL_DETECTION", (使いたい機能のタイプ)
          "maxResults":1 (APIから返ってくる結果の数)
        }
      ]
    }
  ]
}


"content"に設定する画像はBASE64形式に変換する必要があります。
私はこちらを使わせて頂きました。
syncer.jp


[Request body]のテキストボックスをクリックします。
[--add a property--]が表示されるので、「requests」を選択します。
f:id:puu_0328:20170515150147p:plain


"request"の{}の中で「image」を選択、更に「content」を選択します。
f:id:puu_0328:20170515151552p:plain


"content":"_______________"の中に先程、画像をBASE64形式にエンコードしたものを貼り付けます。
※上記のツールでエンコードした文字列は「data:image/jpeg;base64,/9j/..」といった感じになってるはずです。
これの「data:image/jpeg;base64,」は削除して、「/9j/..」から始まるようにして貼り付けしてください。

f:id:puu_0328:20170515151829p:plain



"image"の{}の下で「features」を選択します。
f:id:puu_0328:20170515152030p:plain


"features"の{}の中で「type」を選択し、「TEXT_DETECTION」を入力します。
更に「maxResults」を選択し、「1」を入力します。
f:id:puu_0328:20170515152516p:plain


ここまでできたら、画面下の[Execute]をクリックします。
※[Execute]が[Analyze and execute]となっている場合、
認証が完了していませんので、[Analyze and execute]をクリックして認証してください。

f:id:puu_0328:20170515152943p:plain



実行結果

送った画像はこちらです。
f:id:puu_0328:20170515174835j:plain


リクエストパラメータとして
f:id:puu_0328:20170515175836p:plain
を送信し。

レスポンスとして、このようなパラメータが返ってきました。
一番下を確認すると、f:id:puu_0328:20170515180107p:plainが表示されていることから、
ちゃんと「test」という文字列が認識できていることが分かります。

200
 
- Show headers -
  
{
 "responses": [
  {
   "textAnnotations": [
    {
     "locale": "en",
     "description": "test\n",
     "boundingPoly": {
      "vertices": [
       {
        "x": 44,
        "y": 36
       },
       {
        "x": 162,
        "y": 36
       },
       {
        "x": 162,
        "y": 90
       },
       {
        "x": 44,
        "y": 90
       }
      ]
     }
    },
    {
     "description": "test",
     "boundingPoly": {
      "vertices": [
       {
        "x": 44,
        "y": 37
       },
       {
        "x": 162,
        "y": 36
       },
       {
        "x": 162,
        "y": 89
       },
       {
        "x": 44,
        "y": 90
       }
      ]
     }
    }
   ],
   "fullTextAnnotation": {
    "pages": [
     {
      "property": {
       "detectedLanguages": [
        {
         "languageCode": "en"
        }
       ]
      },
      "width": 188,
      "height": 118,
      "blocks": [
       {
        "property": {
         "detectedLanguages": [
          {
           "languageCode": "en"
          }
         ]
        },
        "boundingBox": {
         "vertices": [
          {
           "x": 44,
           "y": 37
          },
          {
           "x": 162,
           "y": 36
          },
          {
           "x": 162,
           "y": 89
          },
          {
           "x": 44,
           "y": 90
          }
         ]
        },
        "paragraphs": [
         {
          "property": {
           "detectedLanguages": [
            {
             "languageCode": "en"
            }
           ]
          },
          "boundingBox": {
           "vertices": [
            {
             "x": 44,
             "y": 36
            },
            {
             "x": 162,
             "y": 36
            },
            {
             "x": 162,
             "y": 90
            },
            {
             "x": 44,
             "y": 90
            }
           ]
          },
          "words": [
           {
            "property": {
             "detectedLanguages": [
              {
               "languageCode": "en"
              }
             ]
            },
            "boundingBox": {
             "vertices": [
              {
               "x": 44,
               "y": 37
              },
              {
               "x": 162,
               "y": 36
              },
              {
               "x": 162,
               "y": 89
              },
              {
               "x": 44,
               "y": 90
              }
             ]
            },
            "symbols": [
             {
              "property": {
               "detectedLanguages": [
                {
                 "languageCode": "en"
                }
               ]
              },
              "boundingBox": {
               "vertices": [
                {
                 "x": 44,
                 "y": 37
                },
                {
                 "x": 68,
                 "y": 37
                },
                {
                 "x": 68,
                 "y": 90
                },
                {
                 "x": 44,
                 "y": 90
                }
               ]
              },
              "text": "t"
             },
             {
              "property": {
               "detectedLanguages": [
                {
                 "languageCode": "en"
                }
               ]
              },
              "boundingBox": {
               "vertices": [
                {
                 "x": 69,
                 "y": 37
                },
                {
                 "x": 104,
                 "y": 37
                },
                {
                 "x": 104,
                 "y": 90
                },
                {
                 "x": 69,
                 "y": 90
                }
               ]
              },
              "text": "e"
             },
             {
              "property": {
               "detectedLanguages": [
                {
                 "languageCode": "en"
                }
               ]
              },
              "boundingBox": {
               "vertices": [
                {
                 "x": 104,
                 "y": 36
                },
                {
                 "x": 137,
                 "y": 36
                },
                {
                 "x": 137,
                 "y": 89
                },
                {
                 "x": 104,
                 "y": 89
                }
               ]
              },
              "text": "s"
             },
             {
              "property": {
               "detectedLanguages": [
                {
                 "languageCode": "en"
                }
               ],
               "detectedBreak": {
                "type": "EOL_SURE_SPACE"
               }
              },
              "boundingBox": {
               "vertices": [
                {
                 "x": 138,
                 "y": 36
                },
                {
                 "x": 162,
                 "y": 36
                },
                {
                 "x": 162,
                 "y": 89
                },
                {
                 "x": 138,
                 "y": 89
                }
               ]
              },
              "text": "t"
             }
            ]
           }
          ]
         }
        ],
        "blockType": "TEXT"
       }
      ]
     }
    ],
    "text": "test\n"
   }
  }
 ]
}
 

その他のパラメータ(detectedLanguagesとかboundingPolyとか)の詳細については
Method: images.annotate  |  Google Cloud Vision API  |  Google Cloud Platform
のフィールドを参照してください。



【備忘録】String型の配列に格納されたメールアドレスをInternetAddress[]型に変換して複数の宛先にメールを送信【java】

//MimeMessageを使用
 MimeMessage msg = new MimeMessage(session);
//String型の配列に適当なメールアドレスを格納
String[] addr = {"test@example.com","puu_0328@example.com","tefetishism@example.com"}; //InternetAddress型の配列を作成
InternetAddress[] addrList =new InternetAddress[addr.length];
int n = 0;
//拡張for文を使って1つ1つ入れていく
for(String str : addr){
addrList[n]=((new InternetAddress(str)));
n= n+1;
}
//「"utf-8"」は全角文字が入る場合に設定
msg.setFrom(new InternetAddress("送信元メールアドレス","送信元の名前","utf-8")); // 送信元設定
msg.setRecipients(Message.RecipientType.TO,addrList);// 宛先設定
msg.setSubject("メールの件名", "utf-8");//件名設定
msg.setSentDate(new Date());//送信日時
msg.setText("本文", "utf-8","plain");//本文
//送信する
 Transport.send(msg);

送信結果

f:id:puu_0328:20170417162636p:plain

※宛先メールアドレスはぼかしてます