GPUImageToneCurveFilter возвращает черное изображение после нескольких снимков камеры
Пока камера активна, я позволил пользователю выбрать любой фильтр через горизонтальный список прямо на экране.
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 ответ
Также есть проблема с черными изображениями. Мой код:
GPUImage gpuImage = new GPUImage(context);
gpuImage.setImage(sourceBitmap);
gpuImage.setFilter(filter);
Bitmap bitmap = gpuImage.getBitmapWithFilterApplied();
В моем случае помещение этого кода в синхронизированный метод решило проблему. Похоже getBitmapWithFilterApplied
не является потокобезопасным, или в библиотеке есть некоторое состояние гонки.