1
/
5

【TECH BLOG】ZOZOGLASSのクロスプラットフォーム設計

こんにちは、AndroidエンジニアのAndyです。これまでにZOZOSUIT、ZOZOMAT、ZOZOGLASSのアプリ機能開発に取り組んできました。

ZOZOGLASSは肌の色を計測するデバイスで、オンラインでファンデーションを購入する際の手助けをします。ZOZOGLASSのユーザーは下図のような専用の眼鏡をかけ、アプリを使用して顔の肌の色を計測します。

この技術の開発中に、私たちはクロスプラットフォームであるが故の技術的ハードルに直面しました。本記事では、そこで使用されているテクノロジーの一部と、それらの課題をどのように解決していったのかを紹介します。

クロスプラットフォームにおける技術的課題

前述の通り、開発を進めていく中でさまざまな技術的課題に直面しました。その原因はiOSとAndroidを同時にカバーするため、クロスプラットフォームである必要があったからです。それに起因し、肌の色の計測パフォーマンスの課題やフェイストラッキングの課題が発生しました。

現在では、フェイストラッキングにはARCore Augmented Facesを使用し、肌の色の計測と色補正アルゴリズムにはC++ライブラリを使用し、この課題に対応しています。本記事では、その中でも活用している、KotlinでC++ライブラリを使用する方法を簡単なサンプルを用いて説明します。

C++による計測ライブラリの作成

ユーザーの肌の色を計測するためのライブラリを、C++で開発しました。C++は、高性能アプリケーションの作成に使用できるクロスプラットフォームな言語です。これにより、開発者はシステムリソースとメモリを高度に制御することが可能になります。C#やJavaとも類似する点ですが、オブジェクト指向プログラミング言語としてプログラムに明確な構造を与えてコードを再利用できます。

計測専用の眼鏡はさまざまな配色のユニークな模様でデザインされています。そして、C++ライブラリはスマートフォンのカメラでユーザーの顔をスキャンする際に、このユニークな模様を活用して色の補正をします。検出した顔の各領域を識別し、それらの領域に対して肌の色のカラーマップを生成します。

ネイティブアプリへのC++ライブラリの組み込み

パフォーマンスとUXの向上のために、スマートフォン向けのアプリはネイティブアプリとして開発することにしました。iOSアプリはSwift、AndroidアプリはKotlinを使用して開発されています。

しかし、iOSアプリでは、SwiftがC++と直接通信できないため、手動で中間レイヤーを追加する必要があります。例えば、すべてのC++の機能をObjective-Cモジュールにラップさせる方法があります。その場合、SwiftのアプリケーションからObjective-Cフレームワークを使用するだけなので、実装は容易です。

一方、Androidアプリの場合は、iOSアプリのように容易には実装できません。Android Native Development Kit(Android NDK。以下、NDK)を使用する必要があります。このNDKは、開発者がアプリの一部をネイティブコード(C++)で記述できるようにするツールセットです。

次章では、このNDKを利用したAndroidアプリの実装方法を説明します。

NDKを用いたAndroidアプリの実装方法

NDKには、以下のデフォルトツールが含まれています。

  • デバッガー
  • CMake
  • Java Native Interface(JNI)

JNIは、Kotlin/JavaとネイティブC++間のインタラクションの処理を司るインタフェースです。これは、Androidによって生成されたバイトコードがネイティブコードと通信する方法を定義してくれます。その結果、Kotlinのコードは、JNIを使用することでC++コードと通信が可能となります。

それらのAndroidによって生成されたバイトコードとネイティブコードは、双方で関数と変数を保持しています。JNIを使用すると、KotlinからC++で記述された関数を呼び出したり、その逆も可能になります。また、言語間で変数に格納されている値を読み取って変更することも可能です。

前述のように、C++で記述されたネイティブコードを処理する場合、ネイティブ関数を呼び出し、引数を渡し、結果を取得する必要があります。これを処理するために「プリミティブ型」が使用されます。そして、引数をネイティブコードの関数に渡したり、プリミティブ型の形式で結果を取得したりするためにJNIで定義された特別なネイティブ型が存在します。具体的にはJavaのドキュメントで記載されているように、Kotlin/Javaの各プリミティブに対応するネイティブ型が用意されています。


Java Native Interface Specification: 3 - JNI Types and Data Structures
This chapter discusses how the JNI maps Java types to native C types. This chapter covers the following topics: The following table describes Java primitive types and their machine-dependent native equivalents. The following definition is provided for con
https://docs.oracle.com/en/java/javase/17/docs/specs/jni/types.html

Android StudioでサンプルコードのNDKを動かしてみる

本章では、Android Studioを使い、簡単なサンプルを動かしながらNDKの利用方法を説明します。

環境準備とプロジェクト作成

Android StudioでNDKをサポートするには、以下のSDKを追加する必要があります。

続きはこちら

株式会社ZOZOでは一緒に働く仲間を募集しています
同じタグの記事
今週のランキング
株式会社ZOZOからお誘い
この話題に共感したら、メンバーと話してみませんか?