I have been trying to scan a QR code for a project. The Project is simple we have a QR code with some unique data in it like its location (eg:- 1st exit, front entrence1, etc) when a person scans the QR code an object is placed over the QR code for localization, and based on the QR code data, and many objects checkpoints are placed automatically relative to the object over the QR code through which the app shows the route kind of an ar indoor navigation system but the problem I'm facing is that I don't know how to use the latest version of arcore which uses openGL so I used the last latest sceneform which is way easy and there are tutorials on it but the problem is I don't have any idea how to scan the QR code using sceneform and then place an anchor over the QR code and then place an anchor over it so that I can place the object.
Is there any better way for localization because I'm using Firebase to store the relative location? is there any better way so then even if the camera loses vision for some time the points should automatically come to their original position.
I'm using this version of sceneform my Gorisse thomas:-
implementation "com.gorisse.thomas.sceneform:sceneform:1.23.0"
and also I want the code in Java and not in Kotlin
I have also tried Google's MLKit but it also seems to not work I tried every method and also tried AI like chatGPT and Black Box but none of them could provide me a working code even after some modifications it still didn't work
This is the Java code I tried till now and I also tried many modifications but it doesn't seem to work
import static androidx.constraintlayout.helper.widget.MotionEffect.TAG;
import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.media.Image;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.ar.core.Anchor;
import com.google.ar.core.ArImage;
import com.google.ar.core.HitResult;
import com.google.ar.core.Plane;
import com.google.ar.core.exceptions.NotYetAvailableException;
import com.google.ar.sceneform.AnchorNode;
import com.google.ar.sceneform.ArSceneView;
import com.google.ar.sceneform.math.Vector3;
import com.google.ar.sceneform.rendering.Color;
import com.google.ar.sceneform.rendering.MaterialFactory;
import com.google.ar.sceneform.rendering.ModelRenderable;
import com.google.ar.sceneform.rendering.ShapeFactory;
import com.google.ar.sceneform.ux.BaseArFragment;
import com.google.mlkit.vision.barcode.BarcodeScanner;
import com.google.mlkit.vision.barcode.BarcodeScannerOptions;
import com.google.mlkit.vision.barcode.common.Barcode;
import com.google.mlkit.vision.common.InputImage;
import com.google.mlkit.vision.barcode.BarcodeScanning;
import com.google.ar.core.Camera;
import com.google.ar.core.Frame;
import com.google.ar.core.TrackingState;
import com.google.ar.sceneform.ux.ArFragment;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.List;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
private ArFragment arFragment;
BarcodeScanner barcodeScanner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize the AR Fragment
arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.arFragment);
arFragment.setOnTapArPlaneListener(new BaseArFragment.OnTapArPlaneListener() {
@Override
public void onTapPlane(HitResult hitResult, Plane plane, MotionEvent motionEvent) {
planeCube(hitResult.createAnchor());
}
});
}
private void planeCube(Anchor anchor) {
MaterialFactory
.makeOpaqueWithColor(this, new Color(android.graphics.Color.BLUE))
.thenAccept(material -> {
ModelRenderable modelRenderable = ShapeFactory.makeCube(new Vector3(0.1f,0.1f,0.1f), new Vector3(0f,0.1f,0),material);
try {
planeModel(modelRenderable, anchor);
} catch (NotYetAvailableException e) {
e.printStackTrace();
}
});
}
private void planeModel(ModelRenderable modelRenderable, Anchor anchor) throws NotYetAvailableException {
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setRenderable(modelRenderable);
//arFragment.getArSceneView().getScene().addChild(anchorNode);
Image camera = Objects.requireNonNull(arFragment.getArSceneView().getArFrame()).acquireCameraImage();
InputImage inputImage = InputImage.fromMediaImage(camera, /* image rotation */ 0);
//Bitmap bit = convertFrameToBitmap(camera);
processImage(inputImage);
}
private Bitmap convertFrameToBitmap(Image image) {
if (image != null) {
int width = image.getWidth();
int height = image.getHeight();
Log.d(TAG, "convertFrameToBitmap: ");
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
bitmap.copyPixelsFromBuffer(buffer);
image.close(); // Close the ArImage to release resources
return bitmap;
}
return null;
}
private void processImage(InputImage image) {
Log.d(TAG, "processImage: "+image);
// Detect QR codes in the image.
barcodeScanner.process(image)
.addOnSuccessListener(barcodes -> {
for (Barcode barcode : barcodes) {
// Retrieve and process detected QR codes.
String qrCodeData = barcode.getRawValue();
Log.d("QRCode", "QR Code detected: " + qrCodeData);
// Place your AR object or show a toast message here.
}
})
.addOnFailureListener(e -> Log.e("QRCode", "Error detecting QR code: " + e.getMessage()));
}
}
This is my XML code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/arFragment"
android:name="com.google.ar.sceneform.ux.ArFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Can anyone provide me with some ideas or code to make this work? and checkpoints are placed based on the position of the QR code
Please anyone help me out your work will be greatly appreciated! Have a Good day
Thank you