我可以使用 AR CORE 场景形式 API 在表面渲染 2D 图像或 GIF 图像吗?

Can I render 2D images or GIF images on surface using AR CORE scene-form API?

我正在尝试识别一张二维图像,一旦图像 tracking/recognition 成功完成,

我必须在表面上放置一张 2D 图片或 GIF 图片。

我正在使用场景形式API。

我可以渲染 3D 图像和视频,但我的要求是渲染 GIF 图片或 2D 图片。

求推荐!!!

代码-

片段:

package com.example.setupboxscanner;

import com.google.ar.core.Config;
import com.google.ar.core.Session;
import com.google.ar.sceneform.ux.ArFragment;

public class CustomArFragment extends ArFragment {

    @Override
    protected Config getSessionConfiguration(Session session) {
        Config config = new Config(session);
        config.setUpdateMode(Config.UpdateMode.LATEST_CAMERA_IMAGE);
        config.setFocusMode(Config.FocusMode.AUTO);
        session.configure(config);
        this.getArSceneView().setupSession(session);

        ((MainActivity)getActivity()).setupDatabase(config, session);

        return config;
    }

}

主要活动:

package com.example.setupboxscanner;

import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.ar.core.Anchor;
import com.google.ar.core.AugmentedImage;
import com.google.ar.core.AugmentedImageDatabase;
import com.google.ar.core.Config;
import com.google.ar.core.Frame;
import com.google.ar.core.Session;
import com.google.ar.core.TrackingState;
import com.google.ar.sceneform.AnchorNode;
import com.google.ar.sceneform.FrameTime;
import com.google.ar.sceneform.Scene;
import com.google.ar.sceneform.rendering.ModelRenderable;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

import java.util.Collection;

public class MainActivity extends AppCompatActivity  implements Scene.OnUpdateListener {

    private CustomArFragment arFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        arFragment = (CustomArFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
        arFragment.getArSceneView().getScene().addOnUpdateListener(this);
    }

    public void setupDatabase(Config config, Session session){
       Bitmap setTopBoxImagesFront  = BitmapFactory.decodeResource(getResources(), R.drawable.front);
      //  Bitmap setTopBoxImagesRear  = BitmapFactory.decodeResource(getResources(), R.drawable.rear);
        AugmentedImageDatabase aid = new AugmentedImageDatabase(session);
        aid.addImage("image1", setTopBoxImagesFront);
       // aid.addImage("image2", setTopBoxImagesRear);

        config.setAugmentedImageDatabase(aid);
    }

    @Override
    public void onUpdate(FrameTime frameTime) {

        Frame frame = arFragment.getArSceneView().getArFrame();
        Collection<AugmentedImage> images = frame.getUpdatedTrackables(AugmentedImage.class);

        for (AugmentedImage image : images) {
            if(image.getTrackingState() == TrackingState.TRACKING) {
                if(image.getName().equals("image1")) {
                    Anchor anchor = image.createAnchor(image.getCenterPose());
                    createModel(anchor);
                }
            }
        }
    }

   // @TargetApi(24)
    private void createModel(Anchor anchor) {

        Log.e("-----><>>",""+Uri.parse("//android_assets/front.jpg"));
        ModelRenderable.builder().setSource(this, Uri.parse("model.sfb")).build()
                .thenAccept(modelRenderable -> placeModel(modelRenderable, anchor));
    }

    private void placeModel(ModelRenderable modelRenderable, Anchor anchor) {
        AnchorNode anchorNode = new AnchorNode(anchor);
        anchorNode.setRenderable(modelRenderable);
        arFragment.getArSceneView().getScene().addChild(anchorNode);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


}

场景形式资产:

sceneform.asset('sampledata/ArcticFox_Posed.obj',
        'default',
        'sampledata/ArcticFox_Posed.sfa',
        'src/main/assets/ArcticFox_Posed')

ActivityMain.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
<fragment
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragment"
    android:name="com.example.setupboxscanner.CustomArFragment"/>



</androidx.coordinatorlayout.widget.CoordinatorLayout>

感谢您的提问。我在尝试通过 ARCore 渲染 gif and/or 2D 图像时遇到了类似的问题。幸运的是,有一种非常简单的方法可以做到这一点。您可以将此 gif 图像视图 Adding gif image in an ImageView in android 用于新的 XML 布局文件。然后在将布局附加到节点(可以是锚节点或只是相对于相机的节点 [我称之为浮动节点])之后,使用 ViewRenderable 在 ARcore Session 中渲染该布局。您应该可以清楚地查看 gif and/or 图片。

在将使用 ViewRenderable 呈现的新 XML 布局中,我有这个视图来加载 gif:

 <pl.droidsonroids.gif.GifImageView
        android:layout_width="173dp"
        android:layout_height="183dp"
        android:src="@drawable/loading2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />