「Google Lensで画像を検索」機能の呼び出し過程を追う

「Google Lensで画像を検索」機能の呼び出し過程を追う

PC版Chromeに搭載された「Google Lensで画像を検索」機能が気になっている

ブラウザの右パネルを活用し始めた傾向がみられ、このUIも気になるのでコードを読んでいく daiiz

画像上でコンテキストメニューがクリックされた後、どういう流れを経て右パネルで検索結果が表示されるか
予想 daiiz
タブのスクリーンショットを撮る
画像の領域情報を保持する
スクリーンショットと領域情報がGoogle Lens APIに渡される
正解 (現時点での理解)
コンテキストメニューがクリックされた画像ノードを取得する
画像のビットマップからPNG形式のサムネイル画像をつくる
画像データそのものがGoogle Lens APIに渡される


未整理の調査メモ

「lens」で検索してみる

components/lens/lens_features.cc
おなじみのkで始まる定数の宣言
enable-side-panel
内部的にはregion-searchと呼ばれている?

components/lens/lens_entrypoints.cc
GetLensQueryParametersMap(lens::EntryPoint ep, bool is_side_panel_request)
エントリポイントとサイドパネルの有効化状況に応じてQueryParams Mapを組み立てる
kStartTimeQueryParameter: st
base::Time::Now().ToJavaTime();
kChromeSearchWithGoogleLensContextMenuItem: "ccm"
オプションを与えているだけで画像や領域情報は含まれていない
AppendOrReplaceQueryParametersForLensRequest内部で呼び出される

「AppendOrReplaceQueryParametersForLensRequest」で検索
気になる
chrome/browser/ui/views/lens/lens_side_panel_controller.cc
chrome/browser/ui/views/side_panel/lens/lens_unified_side_panel_view.cc

chrome/browser/ui/views/lens/lens_side_panel_controller.cc
void LensSidePanelController::LoadResultsInNewTab()
Open the latest URL visible on the side panel. This accounts for when the user uploads an image to Lens via drag and drop. This also allows any region selection changes to transfer to the new tab.
たぶんこのボタンが押されたときの挙動だ
今回深堀りしたい場所ではないので一旦撤退

コンテキストメニューから追っていく必要がある?

「で画像を検索」で検索
chrome/app/resources/generated_resources_ja.xtb
「VISUAL_SEAERCH_PROVIDER」

components/lens/lens_features.cc
Enables using Google as the visual search provider instead of Google Lens .
Google Lensの代わりにGoogleを使うオプション
関係ない

components/lens/lens_features.cc


chrome/browser/ui/tab_contents/core_tab_helper.cc

chrome/browser/ui/tab_contents/core_tab_helper.h


DoSearchByImageInNewTab (chrome/browser/ui/tab_contents/core_tab_helper.cc)
Handles the image thumbnail for the context node, composes a image search request based on the received thumbnail and opens the request in a new tab.
search_args.image_thumbnail_content に検索対象の画像データが格納されていそう
components/search_engines/template_url.h にもそれらしいコメントがある
search_args.image_thumbnail_content はどうやって作られる?
DoSearchByImageInNewTab関数の引数として const std::vector<uint8_t>& thumbnail_data が渡されている
この時点ですでに領域でのクロップは済んでいるはず?

PostContentToURL (chrome/browser/ui/tab_contents/core_tab_helper.cc)
Google Chrome Brandingの場合のみSidePanelにLensのリクエストを表示する
EdgeやBraveなどChrome以外のChromium製のブラウザでは使えない?
最終的にどちらかの下記の関数のどちらかでURLを開く
lens::OpenLensSidePanel(chrome::FindBrowserWithWebContents(web_contents()), open_url_params);
web_contents()->OpenURL(open_url_params);
修行が足りずこの2つの関数はどちらも全体像が見えてこない daiiz

lens::OpenLensSidePanel
chrome/browser/ui/lens/lens_side_panel_helper.h
chrome/browser/ui/views/lens/lens_side_panel_helper.cc
OpenWithURL(url_params) も見ておくか

browser_view->lens_side_panel_controller()->OpenWithURL(url_params)
browser_view->lens_side_panel_controller()
chrome/browser/ui/views/lens/lens_side_panel_controller.h
chrome/browser/ui/views/lens/lens_side_panel_controller.cc
最後の LoadURLWithParams() も見る

side_panel_view_->GetWebContents()->GetController().LoadURLWithParams
content/browser/renderer_host/navigation_controller_impl.cc
→ NavigateWithoutEntry(params)


SearchWithLensInNewTab (chrome/browser/ui/tab_contents/core_tab_helper)

SearchByImageInNewTabImpl
→ thumbnail_capturer_proxy->RequestImageForContextNode を介して、DoSearchByImageInNewTabが実行されるぽい
BindOnceとは?
難しそう。Passing Parameters As A unique_ptrの例と近いことやっている?

RequestImageForContextNode (chrome/common/chrome_render_frame.mojom)
実装は chrome/renderer/chrome_render_frame_observer.cc ?
cc
Copied!
void ChromeRenderFrameObserver::RequestImageForContextNode(
int32_t thumbnail_min_area_pixels,
const gfx::Size& thumbnail_max_size_pixels,
chrome::mojom::ImageFormat image_format,
RequestImageForContextNodeCallback callback) {
SkBitmapとか出てきているのでたぶんSKIA
完全にレンダリング層に来てしまった?
大雑把な流れ
WebNode context_node = render_frame()->GetWebFrame()->ContextMenuImageNode();
WebElement web_element = context_node.To<WebElement>();
web_element.ImageContents()
SkBitmap image = web_element.ImageContents();
必要に応じてこれをDownScaleしたものがSkBitmap thumbnail
ImageContents関数読みたいな daiiz
SkBitmap bitmap;
thumbnailを元にしてあれこれ経て作られる
必要に応じて要求されたフォーマットに変換する
std::vector<unsigned char> data;
browserプロセスに返すimage_dataができあがる
std::move(callback).Run(image_data, original_size, image_extension);
最後の行でoriginalSizeとともにcallbackに渡す

chrome/browser/lens/region_search/lens_region_search_controller.h
Creates and runs the drag and capture flow. When run, the user enters into a screenshot capture mode with the ability to draw a rectagular region around the web contents. When finished with selection, the region is converted into a PNG and sent to Lens.
領域のスクリーンショットがPNG画像としてLensに渡されることは分かった
drag操作を待ち受けるっぽいのでこれも違う?
画像の上で右クリックしたときに、その画像のバイナリデータを送るのではなく、タブのスクリーンショットを撮ってその画像の領域 (で切り抜いた結果?) をLens APIに渡している?daiiz
違うっぽかった
普通にimageElmenentにアクセスできていた

components/lens/lens_entrypoints.h
CHROME_SEARCH_WITH_GOOGLE_LENS_CONTEXT_MENU_ITEM
LWDは何のことか分からない

chrome/browser/renderer_context_menu/render_view_context_menu.cc

chrome/browser/renderer_context_menu/render_view_context_menu.cc



脱線
tools/metrics/actions/actions.xml 面白い
機能ごとにowner (担当開発者) が列挙されている
commitをウォッチしておこう
説明も用意されているのでこのファイルを眺めるだけで実験中の機能とかも把握できるのではないか
機能が実行されたことを記録している
chrome/browser/ui/browser_finder.cc
WebContent == タブ的なニュアンスなのかな
web_contents()->OpenURL()
実装はcontent/browser/web_contents/web_contents_impl.ccにある


web_contents()->OpenURL()
content/browser/web_contents/web_contents_impl.cc
→ LoadURLWithParams()

NavigationControllerImpl::NavigateWithoutEntry
content/browser/renderer_host/navigation_controller_impl.cc
長い
→ CreateNavigationRequestFromLoadParams

CreateNavigationRequestFromLoadParams
content/browser/renderer_host/navigation_controller_impl.cc
params.post_data に格納されているPOSTしたいデータもここで渡されている
またmojomだ

Powered by Helpfeel