SurfaceHolder回调永远不会在nexus6p上出现

时间:2016-10-30 17:37:55

标签: android android-camera surfaceview android-7.0-nougat

我正在开发一款获取屏幕当前像素颜色的Android应用 应用程序概念非常简单CameraPreview类实现SurfcaeHolder.Callback接口 并onSurfcaeChanged获得颜色 我的问题是代码在samsung6s上运行得很好但是它不能用于 nuxus6p 回调surfaceCreatedsurfaceChanged从未调用过 这是我的代码示例

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
String TAG = "TAG";
Context context;
OnColorDetected onColorDetected;
ColorDetectionPresenter presenter;
Camera.Size previewSize;
int midPixxel;

public CameraPreview(Context context, Camera camera, ColorDetectionPresenter presenter) {
    super(context);
    mCamera = camera;
    this.context = context;
    this.presenter = presenter;
    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
    mHolder = getHolder();
    mHolder.addCallback(this);
    // deprecated setting, but required on Android versions prior to 3.0
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void setOnColorDetected(OnColorDetected onColorDetected) {
    this.onColorDetected = onColorDetected;
}



public void surfaceDestroyed(SurfaceHolder holder) {
    // empty. Take care of releasing the Camera preview in your activity.
}


@Override
public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, now tell the camera where to draw the preview.
    try {
        Log.d("SURFACE_STATE","created");
        mCamera.setPreviewDisplay(holder);

        mCamera.setPreviewCallback(new Camera.PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
                int frameHeight = camera.getParameters().getPreviewSize().height;
                int frameWidth = camera.getParameters().getPreviewSize().width;
                // number of pixels//transforms NV21 pixel data into RGB pixels
                int rgb[] = new int[frameWidth * frameHeight];
                // convertion
                int[] myPixels = decodeYUV420SP(rgb, data, frameWidth, frameHeight);
                for (int i = 0; i < myPixels.length; i++) {

                    //Toast.makeText(context, MainActivity.getBestMatchingColorName(myPixels[i]), Toast.LENGTH_SHORT).show();
                }
            }
        });
        mCamera.startPreview();
    } catch (IOException e) {
        Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    // If your preview can change or rotate, take care of those events here.
    // Make sure to stop the preview before resizing or reformatting it.
    Log.d("SURFACE_STATE","changed");
    if (mHolder.getSurface() == null) {
        // preview surface does not exist
        return;
    }

    // stop preview before making changes
    try {
        mCamera.stopPreview();
    } catch (Exception e) {
        // ignore: tried to stop a non-existent preview
    }

    // set preview size and make any resize, rotate or
    // reformatting changes here

    // start preview with new settings

    try {
        Camera.Parameters parameters = mCamera.getParameters();
        mCamera.setPreviewDisplay(mHolder);
        List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
        if (previewSizes == null)
            previewSizes = parameters.getSupportedPictureSizes();
        // You need to choose the most appropriate previewSize for your
        previewSize = previewSizes.get(0);
        for(int i=0;i<previewSizes.size();i++){
            if(previewSizes.get(i).width>previewSize.width)
                previewSize=previewSizes.get(i);
        }
        // .... select one of previewSizes here
        cameraSetup(width, height);

        parameters.setPictureSize(previewSize.width, previewSize.height);
        mCamera.setParameters(parameters);
        mCamera.setPreviewCallback(new Camera.PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
                int frameHeight = camera.getParameters().getPreviewSize().height;
                int frameWidth = camera.getParameters().getPreviewSize().width;
                // number of pixels//transforms NV21 pixel data into RGB pixels
                int rgb[] = new int[frameWidth * frameHeight];
                // convertion
                int[] myPixels = decodeYUV420SP(rgb, data, frameWidth, frameHeight);
                String colorName = presenter.getBestMatchingColorName(myPixels[myPixels.length / 2]);
                onColorDetected.colorDetected(colorName);

            }
        });
        mCamera.startPreview();

    } catch (Exception e) {
        Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    }
}


int[] decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {

    // Pulled directly from:

    // http://ketai.googlecode.com/svn/trunk/ketai/src/edu/uic/ketai/inputService/KetaiCamera.java

    final int frameSize = width * height;


    for (int j = 0, yp = 0; j < height; j++) {
        int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;

        for (int i = 0; i < width; i++, yp++) {

            int y = (0xff & ((int) yuv420sp[yp])) - 16;

            if (y < 0)

                y = 0;

            if ((i & 1) == 0) {

                v = (0xff & yuv420sp[uvp++]) - 128;

                u = (0xff & yuv420sp[uvp++]) - 128;

            }


            int y1192 = 1192 * y;

            int r = (y1192 + 1634 * v);
            int g = (y1192 - 833 * v - 400 * u);
            int b = (y1192 + 2066 * u);

            if (r < 0)

                r = 0;

            else if (r > 262143)

                r = 262143;

            if (g < 0)

                g = 0;

            else if (g > 262143)

                g = 262143;
            if (b < 0)
                b = 0;
            else if (b > 262143)
                b = 262143;

            rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
        }
    }
    return rgb;
}

private void cameraSetup(int w, int h) {
    // set the camera parameters, including the preview size

    FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
    double cameraAspectRatio = ((double) previewSize.width) / previewSize.height;

    if (((double) h) / w > cameraAspectRatio) {
        lp.width = (int) (h / cameraAspectRatio + 0.5);
        lp.height = h;
    } else {
        lp.height = (int) (w * cameraAspectRatio + 0.5);
        lp.width = w;
        lp.topMargin = (h - lp.height) / 2;
    }
    lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;

    setLayoutParams(lp);
    requestLayout();
}
}

这就是我称呼它的方式

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    colorDetectionPresenter = new ColorDetectionPresenter();

    camera = Camera.open();
    cameraPreview = new CameraPreview(getActivity(), camera, colorDetectionPresenter);

    params = camera.getParameters();
    params.setPreviewFormat(ImageFormat.NV21);
    camera.setDisplayOrientation(90);
    siz = params.getSupportedPreviewSizes().get(0);
    params.setPreviewSize(siz.width, siz.height);
}

我尝试在onCreateonCreateViewonResume无效的情况下初始化相机预览 有什么建议 ? 它只对我的nexus6p起作用

0 个答案:

没有答案