我是AR的新手。我想知道是否有一种方法可以使用ARCore for android将您在手机上保存的图片显示到表面。就像我能够使用具有预编码图像的Sceneform示例一样,但现在我想将我的图片文件夹中的照片显示到表面。我读到了纹理,但我不确定它是如何工作的。 感谢您的提示。
修改: 所以我创建了一个类,用户可以从中选择一个我通过Uri保存的图像
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == this.RESULT_CANCELED) {
return;
}
if (requestCode == GALLERY) {
if (data != null) {
contentURI = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentURI);
String path = saveImage(bitmap);
Toast.makeText(imageSelector.this, "Image Saved!", Toast.LENGTH_SHORT).show();
//set the image selected to bitmap so that imageView can display it
imageview.setImageBitmap(bitmap);
Intent intent = new Intent(this, HelloSceneformActivity.class);
intent.putExtra("imageUri", contentURI.toString());
startActivity(intent);
从ARclass方面我调用了intent并按照以下方式解析
//start the intent for the image chosen from the library
Bundle extras = getIntent().getExtras();
Uri myUri = Uri.parse(extras.getString("imageUri"));
// When you build a Renderable, Sceneform loads its resources in the background while returning
// a CompletableFuture. Call thenAccept(), handle(), or check isDone() before calling get().
ModelRenderable.builder()
.setSource(this, myUri)
.build()
.thenAccept(renderable -> andyRenderable = renderable)
.exceptionally(
throwable -> {
Toast toast =
Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return null;
});
我可以选择图片,但程序崩溃,我收到此错误
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.google.ar.sceneform.samples.hellosceneform/com.google.ar.sceneform.samples.hellosceneform.HelloSceneformActivity}: java.lang.IllegalArgumentException: Unable to parse url: 'content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F460/ORIGINAL/NONE/1926270799'
Caused by: java.lang.IllegalArgumentException: Unable to parse url: 'content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F460/ORIGINAL/NONE/1926270799'
at com.google.ar.sceneform.utilities.LoadHelper.remoteUriToInputStreamCreator(Unknown Source:56)
at com.google.ar.sceneform.utilities.LoadHelper.fromUri(Unknown Source:40)
at com.google.ar.sceneform.rendering.Renderable$Builder.build(Renderable.java:343)
at com.google.ar.sceneform.rendering.ModelRenderable$Builder.build(ModelRenderable.java:44)
at com.google.ar.sceneform.samples.hellosceneform.HelloSceneformActivity.onCreate(HelloSceneformActivity.java:92)
at android.app.Activity.performCreate(Activity.java:7174)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
答案 0 :(得分:1)
根据https://github.com/google-ar/sceneform-android-sdk/issues/79,您目前无法从自定义URI加载:
在1.0中我们将所有file:// uris解释为相对于assets文件夹,这就是我们无法从外部存储加载的原因。因此,为了从Uri加载纹理,您需要将资源文件夹(即捆绑到您的apk中)放入,或者通过http:/在线提供它。 / scheme。
这意味着此时仅支持http://和file:// URIs,后者只能相对于assets文件夹。在https://github.com/google-ar/sceneform-android-sdk/issues/64上的malik-at-work回答中证实了这一点:
基于URI的文件加载不是在查看外部存储。现在,它只使用file://和以http://
开头的远程uris查找应用程序资产
编辑:我建议的解决方法是将ViewRenderable与内部使用单个ImageView的布局结合使用。 ViewRenderable可以在场景中创建2D布局,您只需将图像设置为ImageView,就像在通常的Android应用程序中一样,并根据自己的喜好定位/旋转生成的对象。您可以在solarsystem-Sceneform-example中找到ViewRenderable的示例用法,使用它实现速度的滑块。
编辑2: 似乎这已在Sceneform 1.4中修复,因为现在已经关闭了第一个提到的问题。
答案 1 :(得分:0)
您可以将图像作为Uri列表传递
public class MainActivity2 extends AppCompatActivity {
Button Gallery, AR;
private static final int PICK_IMAGE = 100;
Uri imageUri;
ImageView imageview;
private ArFragment arFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Gallery = findViewById(R.id.select);
AR = findViewById(R.id.ar);
imageview = findViewById(R.id.imageView);
AR.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent myIntent = new Intent(MainActivity2.this, MainActivity.class);
MainActivity2.this.startActivity(myIntent);
}
});
Gallery.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openGallery();
}
});
}
private void openGallery() {
Intent gallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(gallery, PICK_IMAGE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == PICK_IMAGE) {
imageUri = data.getData();
imageview.setImageURI(imageUri);
setContentView(R.layout.activity_main);
arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
assert arFragment != null;
arFragment.setOnTapArPlaneListener((hitResult, plane, motionEvent) - > {
Anchor anchor = hitResult.createAnchor();
createViewRenderable(hitResult.createAnchor());
});
}
}
private void addModeltoScene(Anchor anchor, ModelRenderable modelRenderable) {
AnchorNode anchorNode = new AnchorNode(anchor);
TransformableNode transformableNode = new TransformableNode(arFragment.getTransformationSystem());
transformableNode.setParent(anchorNode);
transformableNode.setRenderable(modelRenderable);
arFragment.getArSceneView().getScene().addChild(anchorNode);
transformableNode.select();
}
private void createViewRenderable(Anchor anchor) {
ViewRenderable
.builder()
.setView(this, R.layout.text)
.build()
.thenAccept(viewRenderable - > {
addtoScene(viewRenderable, anchor);
});
}
private void addtoScene(ViewRenderable viewRenderable, Anchor anchor) {
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setRenderable(viewRenderable);
arFragment.getArSceneView().getScene().addChild(anchorNode);
View view = viewRenderable.getView();
ViewPager viewPager = view.findViewById(R.id.viewPager);
List < Uri > images = new ArrayList < > ();
images.add(imageUri);
Adapter adapter = new Adapter(images);
viewPager.setAdapter(adapter);
}
class Adapter extends PagerAdapter {
List < Uri > images;
Adapter(List < Uri > images) {
this.images = images;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View view = getLayoutInflater().inflate(R.layout.item, container, false);
ImageView imageView = view.findViewById(R.id.imageView);
imageView.setImageURI(imageUri);
container.addView(view);
return view;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((ImageView) object);
}
@Override
public int getCount() {
return images.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
}
}
我在同一篇文章上写过一篇文章。请检查出来。这是关于以AR形式显示图库中的2D图像。 https://medium.com/@deveshbhatla952/displaying-2-d-images-from-external-storage-in-ar-form-using-google-sceneform-2baae45f1a42 我已经尝试过了,效果很好。