[JAVA] Comment transmettre des informations de pixels d'image de manière native depuis Unity

Il y a eu un cas où je voulais transmettre les informations de pixel d'une image de texture telle que RenderTexture de Unity de manière native, donc j'ai eu beaucoup de problèmes (surtout du côté Android), alors prenez note. Au fait, Android baise. Je veux que vous disparaissiez rapidement. Pour être plus précis, il s'agit d'un cas où vous souhaitez transmettre les données d'image à une bibliothèque Java à l'aide de WebCamera côté Unity.

Cliquez ici pour un exemple de projet https://bitbucket.org/HoshiyamaTakaaki/pixelreadstest

Tout d'abord, l'implémentation côté Unity

CameraOnPost.cs


RenderTexture.active = m_TargetTexture;
m_TargetTexture2D.ReadPixels(new Rect(0, 0, m_TargetTexture.width, m_TargetTexture.height), 0, 0);
m_TargetTexture2D.Apply();

var col = m_TargetTexture2D.GetPixels32();

var handle = default(GCHandle);
try
{
	handle = GCHandle.Alloc(col, GCHandleType.Pinned);
	var ptr = handle.AddrOfPinnedObject();
	libglutil_SetPixels(ptr.ToInt32(), m_TargetTexture.width, m_TargetTexture.height);
}
finally
{
	if (handle != default(GCHandle))
		handle.Free();
}

Du côté de l'iPhone, GetPixels32 d'Unity est raisonnablement rapide, donc je pense qu'il est normal d'obtenir les informations de couleur normalement du côté Unity et de passer le pointeur du côté natif. Dans le cas de RenderTexture, il est nécessaire de le déplacer une fois vers Texture2D, et il peut être nécessaire d'être prudent car cette zone devient une surcharge.

CameraOnPost.cs


m_NativePlugin.CallStatic("sendRgbaFrame", m_Context, m_TargetTexture.GetNativeTexturePtr().ToInt32(), m_TargetTexture.width, m_TargetTexture.height);
GL.InvalidateState();

Malheureusement, Android ne fonctionne pas bien avec les ReadPixels d'Unity. Et la livraison d'octet [] à Java est très lourde. C'est trop lourd à utiliser à ce stade. Ainsi, sur Android, la texture est transmise à Java telle quelle et ReadPixels est effectué du côté Java. En passant, vous pouvez passer la main à NDK si vous le faites comme vous l'avez fait sur iPhone. Il semble qu'il soit plus rapide de transférer un grand tableau d'octets vers Java via C # → NDK → JNI.

Du côté Java, utilisez la texture que vous avez reçue, dessinez la texture dans le frame buffer avec OpenGL ES et lisez-la avec glReadPixels. Mais les glReadPixels d'Android sont très lourds. C'est lourd après tout. L'utilisation de PBO (Pixel Buffer Object) le rend un peu plus rapide (et parfois plus lent), mais il reste lourd. De plus, PBO nécessite OpenGL ES3.0, et il n'est pas complet en Java, donc il marche dessus et donne des coups de pied. (Vous devez augmenter l'API SDK minimale à 24 pour terminer Java. Pouvez-vous l'augmenter ou stupide)

Afin de sauvegarder les informations RGBA acquises dans MP4, etc., il est nécessaire de les convertir davantage en YUV, et à ce stade, il est inévitable qu'il soit dans un état saccadé.

Cela peut ne pas être très utile pour le travail acharné, mais l'ajustement de la taille de RenderTexture améliorera les performances dans une certaine mesure.

De plus, Android a eu beaucoup de problèmes. J'ai également eu du mal à trouver un moyen d'inclure d'autres créés ainsi dans aar. Lorsque la version 64 bits du fichier so a été incluse, il a fallu beaucoup de temps pour résoudre le problème d'apparition d'une fenêtre contextuelle et de se terminer au moment où l'application créée avec Unity a été démarrée.

En créant cet échantillon, j'ai emprunté beaucoup d'informations à nos prédécesseurs. Et j'ai vu beaucoup de questions (cadavres) sans réponses. Tout le monde a des problèmes avec Android.

Merci beaucoup.

Recommended Posts

Comment transmettre des informations de pixels d'image de manière native depuis Unity
Comment déployer à partir d'une image Docker locale vers Heroku
Comment obtenir les informations les plus longues de Twitter à partir du 12/12/2016
[IOS 14] Comment obtenir des données d'image de type Data directement à partir de PHPickerViewController?
[Rails 5] Comment utiliser gem gon ~ Comment passer des variables de Rails à JS ~
[rails] Comment afficher les informations de base de données
Comment passer Oracle Java Silver
[Swift5] Comment communiquer de ViewController à Model et transmettre une valeur
Comment passer du HTML à Haml
Comment recadrer une image avec libGDX
[Rails] Comment convertir ERB en Haml
Comment brouiller l'image (super facile)
Comment appeler le code Swift 5.3 depuis Objective-C
[Flutter] Comment utiliser C / C ++ depuis Dart?
Java: Comment envoyer des valeurs du servlet au servlet
Comment passer la valeur à un autre écran
Pour implémenter la publication d'images à l'aide de rails
[Struts] Comment passer des valeurs entre jsps
[Spring MVC] Comment transmettre des variables de chemin
Comment ajouter des informations sur la version de l'application aux informations Sentry
Comment lier Rails6 Vue (à partir de la construction de l'environnement)
Comment obtenir un heapdump à partir d'un conteneur Docker
Comment vider de la base de données (DB) vers le fichier de départ
Comment réduire l'image de Spring Boot Docker
Comment créer une classe qui hérite des informations de classe
Comment obtenir une classe depuis Element en Java
Comment créer un plug-in natif Unity (version Android)
Comment donner votre image à quelqu'un avec Docker
[Java] Comment passer de jdk ouvert à jdk oracle
Comment utiliser la portée et le traitement des passes (servist)
Comment obtenir l'optimisation SIMD pour HotSpot JavaVM
[ruby] Comment recevoir la valeur de l'entrée standard?