当相机处于活动状态时,我让用户通过屏幕内的水平列表选择任何过滤器。
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的图像捕捉然后问题发生。它有点像某种模式,但显然不是那么准确。我只用一个曲线文件试过这个实验。
我如何让它工作? 这是对图书馆的错误估计吗? 或者它只是一个变量操作错误?或者可能是设置?
答案 0 :(得分:0)
黑色图像也出现问题。我的代码:
GPUImage gpuImage = new GPUImage(context);
gpuImage.setImage(sourceBitmap);
gpuImage.setFilter(filter);
Bitmap bitmap = gpuImage.getBitmapWithFilterApplied();
在我的情况下,将此代码放入 synchronized 方法解决了这个问题。看起来getBitmapWithFilterApplied
不是线程安全的,或者库中存在一些竞争条件。