几次摄像头捕获后,GPUImageToneCurveFilter返回黑色图像

时间:2015-01-24 03:27:17

标签: android android-camera gpuimage android-gpuimageview

当相机处于活动状态时,我让用户通过屏幕内的水平列表选择任何过滤器。

private void initializeVariables() {
    mGPUImage = new GPUImage(this);

    mGPUImage.setGLSurfaceView(glSurfaceView);

    mCameraLoader = new CameraLoader(this, mGPUImage);

    GPUImageFilterTools.showFilters(this, new GPUImageFilterTools.OnGpuImageFilterChosenListener() {
        @Override
        public void onGpuImageFilterChosenListener(GPUImageFilter filter) {
            if (mFilter == null || (filter != null)) {
                mFilter = filter;
                mGPUImage.setFilter(mFilter);
            }
        }
    }, hsv_camera_filters);
}

这是我的初始设置,hsv_camera_filters是org.lucasr.twowayview.TwoWayView的一个实例,可以显示选项。

这是我在用户选择过滤器时调用曲线文件的方式

private static GPUImageFilter createFilterForType(final Context context, final FilterType type) {
    GPUImageToneCurveFilter toneCurveFilter = null;
    switch (type) {
    case NONE:
        return new GPUImageFilter();
    case CONTRAST:
        return new GPUImageContrastFilter(1.5f);
    case CROSSPROCESS:
        toneCurveFilter = new GPUImageToneCurveFilter();
        toneCurveFilter.setFromCurveFileInputStream(context.getResources().openRawResource(
                R.raw.crossprocess));
        return toneCurveFilter;
    case TWO:
        toneCurveFilter = new GPUImageToneCurveFilter();
        toneCurveFilter.setFromCurveFileInputStream(context.getResources().openRawResource(
                R.raw.two));
        return toneCurveFilter;
    default:
        throw new IllegalStateException("No filter of that type!");
    }
}

xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#34393c"
    android:orientation="vertical">

    <android.opengl.GLSurfaceView
        android:id="@+id/camera"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="20dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:weightSum="100">

        <RelativeLayout
            android:id="@+id/camera_top_height"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="46"
            android:background="#34393c"
            android:gravity="center">

        </RelativeLayout>

        <LinearLayout
            android:id="@+id/camera_preview_size"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="22"
            android:orientation="vertical"></LinearLayout>

        <LinearLayout
            android:id="@+id/camera_bot_height"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="bottom"
            android:layout_weight="32"
            android:background="#34393c"
            android:gravity="center"
            android:orientation="vertical"
            android:weightSum="100">

            <org.lucasr.twowayview.TwoWayView xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:id="@+id/hsv_gallery_filters"
                style="@style/TwoWayView"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_weight="45"
                android:drawSelectorOnTop="true"
                tools:context=".ActivityCamera" />

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="55"
                android:gravity="center">

                <Button
                    android:id="@+id/camera_img_capture"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="onCapture"
                    android:text="capture"/>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

我开始像这样拍摄相机:

@OnClick(R.id.camera_img_capture)
public void onCapture() {
    mCameraLoader.getCamera().autoFocus(new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            takePicture();
        }
    });
}

private void takePicture() {
    Camera.Parameters paramss = mCameraLoader.getCamera().getParameters();
    List<Camera.Size> pictureSizes = paramss.getSupportedPictureSizes();

    /**
     * Note : do not allow flash mode when using front-camera. Flash mode is
     * off by default..Change default to auto
     */
    if (mCameraLoader.getCameraId() == 0) {
        switch (flashMode) {
            case 1:// 0 = no flash, 1 = auto flash, 2 = flash on
                paramss.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                break;
            case 2:
                paramss.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                break;
            default:
                paramss.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                break;
        }
    }

    for (int i = 0; i < pictureSizes.size(); i++) {
        if ((pictureSizes.get(i).height <= DEF_HEIGHT)
                && (pictureSizes.get(i).width <= DEF_WIDTH)) {
            mCameraSize = pictureSizes.get(i);
            paramss.setPictureSize(mCameraSize.width, mCameraSize.height);
            paramss.setPreviewSize(mCameraSize.width, mCameraSize.height);
            break;
        }
    }

    mCameraLoader.getCamera().setParameters(paramss);
    mCameraLoader.getCamera().takePicture(null, null, new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, final Camera camera) {
            mCameraLoader.onPause();

            final File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
            if (pictureFile == null) {
                Log.d(TAG, "Error creating media file, check storage permissions");
                return;
            }

            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

            /**
             * Note : detects camera angle and rearranges bytes to a desired
             * angle
             */
            Matrix matrix = new Matrix();
            if (mCameraLoader.getCameraId() == 0) {
                if (mOrientationRounded == 2) {
                    matrix.postRotate(90);
                } else if (mOrientationRounded == 4) {
                    matrix.postRotate(-90);
                }
            } else {
                if (mOrientationRounded == 2) {
                    matrix.postRotate(-90);
                } else if (mOrientationRounded == 4) {
                    matrix.postRotate(90);
                }
            }

            // Saves the image to the phone
            saveImage(mGPUImage.getBitmapWithFilterApplied(bitmap));
        }
    });
}

所以问题出现在1:10或1:12的图像捕捉与滤镜的比例,之后只需要1:4,1:3或1:2的图像捕捉然后问题发生。它有点像某种模式,但显然不是那么准确。我只用一个曲线文件试过这个实验。

我如何让它工作? 这是对图书馆的错误估计吗? 或者它只是一个变量操作错误?或者可能是设置?

1 个答案:

答案 0 :(得分:0)

黑色图像也出现问题。我的代码:

GPUImage gpuImage = new GPUImage(context);
gpuImage.setImage(sourceBitmap);
gpuImage.setFilter(filter);
Bitmap bitmap = gpuImage.getBitmapWithFilterApplied();

在我的情况下,将此代码放入 synchronized 方法解决了这个问题。看起来getBitmapWithFilterApplied不是线程安全的,或者库中存在一些竞争条件。