All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.nextop.fragment.ImageCaptureFragment Maven / Gradle / Ivy

package io.nextop.fragment;


import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.*;
import io.nextop.Nextop;
import io.nextop.NextopAndroid;
import io.nextop.R;
import io.nextop.rx.RxFragment;
import rx.Observer;
import rx.Subscription;

import javax.annotation.Nullable;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

// currently "rapid capture fragment" with goal to
// support all types of images capture and integrate smoothly with nextop upload
public class ImageCaptureFragment extends RxFragment {

    boolean previewStarted = false;

    TextureView textureView;
    SurfaceTexture surfaceTexture;

    boolean record = false;


    @Nullable
    Subscription previewSubscription = null;


    // CONFIG

    int frameIntervalMs = 200;
    int frameMaxWidthPx = 320;
    int frameMaxHeightPx = 480;



    public ImageCaptureFragment() {
    }



    public void onTouchPreview() {
        // implement here
    }

    public void onFrame(Bitmap frame) {
        // implement here
    }





    public void setRecord(boolean record) {
        this.record = record;
    }




    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_image_capture, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        View view = getView();

        textureView = (TextureView) view.findViewById(R.id.texture);

        textureView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onTouchPreview();
            }
        });

        textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {

            long lastPreviewCaptureNanos = 0L;

            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                surfaceTexture = surface;
                startPreview();
            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                surfaceTexture = null;
                stopPreview();
                return true;
            }


            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {
                if (record) {
                    long nanos = System.nanoTime();

                    if (TimeUnit.MILLISECONDS.toNanos(frameIntervalMs) <= nanos - lastPreviewCaptureNanos) {
                        lastPreviewCaptureNanos = nanos;


                        Bitmap bitmap = textureView.getBitmap();

                        int w = bitmap.getWidth();
                        int h = bitmap.getHeight();

                        int sw = w;
                        int sh = h;
                        if (frameMaxHeightPx < h) {
                            int t = frameMaxHeightPx;
                            sw = sw * t / sh;
                            sh = t;
                        }
                        if (frameMaxWidthPx < w) {
                            int t = frameMaxWidthPx;
                            sh = sh * t / sw;
                            sw = t;
                        }

                        if (w != sw || h != sh) {
                            bitmap = Bitmap.createScaledBitmap(bitmap, sw, sh, false);
                        }

                        onFrame(bitmap);
                    }

                }
            }


            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
                // Do nothing
            }

        });

    }







    void startPreview() {
        previewStarted = true;
        if (null == previewSubscription || previewSubscription.isUnsubscribed()) {
            if (null != surfaceTexture) {
                previewSubscription = NextopAndroid.getActive(getActivity()).camera().subscribe(new Observer() {
                    @Nullable
                    Nextop.CameraAdapter ca = null;

                    @Override
                    public void onNext(Nextop.CameraAdapter ca) {
                        stop();
                        assert null == this.ca;
                        try {
                            this.ca = ca;
                            Camera camera = ca.camera;
                            camera.setPreviewTexture(surfaceTexture);
                            setCameraDisplayOrientation(getActivity(), ca.cameraId, camera);
                            camera.startPreview();
                        } catch (IOException e) {
                            //
                        }
                    }

                    @Override
                    public void onCompleted() {
                        stop();
                        restart();
                    }

                    @Override
                    public void onError(Throwable e) {
                        stop();
                        restart();
                    }

                    void stop() {
                        if (null != ca) {
                            ca.camera.stopPreview();
                            ca = null;
                        }
                    }

                    void restart() {
                        if (previewStarted) {
                            startPreview();
                        }
                    }

                });
            }
        }
    }
    void stopPreview() {
        previewStarted = false;
        if (null != previewSubscription) {
            previewSubscription.unsubscribe();
        }
    }




    @Override
    public void onResume() {
        super.onResume();

        NextopAndroid.getActive(getActivity()).addCameraUser();
        startPreview();

    }

    @Override
    public void onPause() {
        super.onPause();

        stopPreview();
        NextopAndroid.getActive(getActivity()).removeCameraUser();
    }


    /** from the Android docs */
    public static void setCameraDisplayOrientation(Activity activity,
                                                   int cameraId, Camera camera) {
        android.hardware.Camera.CameraInfo info =
                new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0: degrees = 0; break;
            case Surface.ROTATION_90: degrees = 90; break;
            case Surface.ROTATION_180: degrees = 180; break;
            case Surface.ROTATION_270: degrees = 270; break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy