diff options
author | Jack Yoo <jyoo@codeaurora.org> | 2016-09-26 13:21:57 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-10-13 15:56:58 -0700 |
commit | aa24e964a6c6f7849ba843a37df1387c0894d725 (patch) | |
tree | bae3f952ba0e74a1639b5931fa297de7f2bfa34c | |
parent | e42adc9e85653ed4b9aa1f71b6343bccc28d155c (diff) | |
download | android_packages_apps_Snap-aa24e964a6c6f7849ba843a37df1387c0894d725.tar.gz android_packages_apps_Snap-aa24e964a6c6f7849ba843a37df1387c0894d725.tar.bz2 android_packages_apps_Snap-aa24e964a6c6f7849ba843a37df1387c0894d725.zip |
SnapdragonCamera: SelfieMirror Camera2
SelfieMirror filter for camera2.
Change-Id: Id5fda369a56421199a8c2537491608b8667fb77e
CRs-Fixed: 1071798
-rw-r--r-- | jni/image_util_jni.cpp | 58 | ||||
-rw-r--r-- | res/values/camera2arrays.xml | 10 | ||||
-rw-r--r-- | res/xml/capture_preferences.xml | 8 | ||||
-rw-r--r-- | res/xml/setting_menu_preferences.xml | 9 | ||||
-rw-r--r-- | src/com/android/camera/CaptureModule.java | 10 | ||||
-rw-r--r-- | src/com/android/camera/SettingsManager.java | 1 | ||||
-rw-r--r-- | src/com/android/camera/imageprocessor/PostProcessor.java | 20 | ||||
-rw-r--r-- | src/com/android/camera/imageprocessor/ZSLQueue.java | 4 | ||||
-rw-r--r-- | src/com/android/camera/imageprocessor/filter/BeautificationFilter.java | 20 |
9 files changed, 104 insertions, 36 deletions
diff --git a/jni/image_util_jni.cpp b/jni/image_util_jni.cpp index a4779b3d7..16f4469c3 100644 --- a/jni/image_util_jni.cpp +++ b/jni/image_util_jni.cpp @@ -44,8 +44,8 @@ JNIEXPORT jint JNICALL Java_com_android_camera_imageprocessor_FrameProcessor_nat jint imageWidth, jint imageHeight, jint degree, jobjectArray outBuf); JNIEXPORT jint JNICALL Java_com_android_camera_imageprocessor_FrameProcessor_nativeNV21toRgb( JNIEnv *env, jobject thiz, jobjectArray yvuBuf, jobjectArray rgbBuf, jint width, jint height); -JNIEXPORT jint JNICALL Java_com_android_camera_imageprocessor_PostProcessor_nativeFlipVerticalNV21( - JNIEnv* env, jobject thiz, jbyteArray yvuBytes, jint width, jint height); +JNIEXPORT jint JNICALL Java_com_android_camera_imageprocessor_PostProcessor_nativeFlipNV21( + JNIEnv* env, jobject thiz, jbyteArray yvuBytes, jint width, jint height, jboolean isVertical); #ifdef __cplusplus } #endif @@ -154,30 +154,52 @@ jint JNICALL Java_com_android_camera_imageprocessor_FrameProcessor_nativeNV21toR return 0; } -jint JNICALL Java_com_android_camera_imageprocessor_PostProcessor_nativeFlipVerticalNV21( - JNIEnv* env, jobject thiz, jbyteArray yvuBytes, jint width, jint height) +jint JNICALL Java_com_android_camera_imageprocessor_PostProcessor_nativeFlipNV21( + JNIEnv* env, jobject thiz, jbyteArray yvuBytes, jint width, jint height, jboolean isVertical) { jbyte* imageDataNV21Array = env->GetByteArrayElements(yvuBytes, NULL); uint8_t *buf = (uint8_t *)imageDataNV21Array; int ysize = width * height; uint8_t temp1, temp2; - for(int x=0; x < width; x++) { - for(int y=0; y < height/2; y++) { - temp1 = buf[y*width + x]; - buf[y*width + x] = buf[(height-1-y)*width + x]; - buf[(height-1-y)*width + x] = temp1; + + if(isVertical) { + for (int x = 0; x < width; x++) { + for (int y = 0; y < height / 2; y++) { + temp1 = buf[y * width + x]; + buf[y * width + x] = buf[(height - 1 - y) * width + x]; + buf[(height - 1 - y) * width + x] = temp1; + } } - } - for(int x=0; x < width; x+=2) { - for(int y=0; y < height/4; y++) { - temp1 = buf[ysize + y*width + x]; - temp2 = buf[ysize + y*width + x + 1]; - buf[ysize + y*width + x] = buf[ysize + (height/2-1-y)*width + x]; - buf[ysize + y*width + x + 1] = buf[ysize + (height/2-1-y)*width + x + 1]; - buf[ysize + (height/2-1-y)*width + x] = temp1; - buf[ysize + (height/2-1-y)*width + x + 1] = temp2; + for (int x = 0; x < width; x += 2) { + for (int y = 0; y < height / 4; y++) { + temp1 = buf[ysize + y * width + x]; + temp2 = buf[ysize + y * width + x + 1]; + buf[ysize + y * width + x] = buf[ysize + (height / 2 - 1 - y) * width + x]; + buf[ysize + y * width + x + 1] = buf[ysize + (height / 2 - 1 - y) * width + x + 1]; + buf[ysize + (height / 2 - 1 - y) * width + x] = temp1; + buf[ysize + (height / 2 - 1 - y) * width + x + 1] = temp2; + } + } + } else { + for (int x = 0; x < width/2; x++) { + for (int y = 0; y < height; y++) { + temp1 = buf[y * width + x]; + buf[y * width + x] = buf[y * width + (width -1 - x)]; + buf[y * width + (width - 1 - x)] = temp1; + } + } + for (int x = 0; x < width/2; x += 2) { + for (int y = 0; y < height / 2; y++) { + temp1 = buf[ysize + y * width + x]; + temp2 = buf[ysize + y * width + x + 1]; + buf[ysize + y * width + x] = buf[ysize + y * width + (width - 1 - x - 1)]; + buf[ysize + y * width + x + 1] = buf[ysize + y * width + (width - 1 - x)]; + buf[ysize + y * width + (width - 1 - x - 1)] = temp1; + buf[ysize + y * width + (width - 1 - x)] = temp2; + } } } + env->ReleaseByteArrayElements(yvuBytes, imageDataNV21Array, JNI_ABORT); return 0; }
\ No newline at end of file diff --git a/res/values/camera2arrays.xml b/res/values/camera2arrays.xml index 107ae5bb5..438d1389a 100644 --- a/res/values/camera2arrays.xml +++ b/res/values/camera2arrays.xml @@ -603,6 +603,16 @@ <item>@string/setting_on_value</item> </string-array> + <string-array name="pref_camera2_selfiemirror_entries" translatable="false"> + <item>@string/setting_off</item> + <item>@string/setting_on</item> + </string-array> + + <string-array name="pref_camera2_selfiemirror_entryvalues" translatable="false"> + <item>@string/setting_off_value</item> + <item>@string/setting_on_value</item> + </string-array> + <string-array name="pref_camera2_filter_mode_entries" translatable="false"> <item>@string/pref_camera_filter_mode_entry_off</item> <item>@string/pref_camera_filter_mode_entry_on</item> diff --git a/res/xml/capture_preferences.xml b/res/xml/capture_preferences.xml index fd1424f50..07c3df83e 100644 --- a/res/xml/capture_preferences.xml +++ b/res/xml/capture_preferences.xml @@ -169,6 +169,14 @@ camera:singleIcon="@drawable/ic_settings_continuous" camera:title="@string/pref_camera_longshot_title"/> + <IconListPreference + camera:defaultValue="@string/setting_off_value" + camera:key="pref_camera2_selfiemirror_key" + camera:title="@string/pref_camera_selfiemirror_title" + camera:entries="@array/pref_camera2_selfiemirror_entries" + camera:singleIcon="@drawable/ic_settings_selfiemirror" + camera:entryValues="@array/pref_camera2_selfiemirror_entryvalues" /> + <CountDownTimerPreference camera:defaultValue="@string/pref_camera_timer_default" camera:key="pref_camera2_timer_key" diff --git a/res/xml/setting_menu_preferences.xml b/res/xml/setting_menu_preferences.xml index a0c1ac7dc..835fed504 100644 --- a/res/xml/setting_menu_preferences.xml +++ b/res/xml/setting_menu_preferences.xml @@ -77,7 +77,12 @@ android:key="pref_camera2_longshot_key" android:layout="@layout/preference" android:title="@string/pref_camera_longshot_title" /> - + <SwitchPreference + android:defaultValue="false" + android:icon="@drawable/ic_settings_selfiemirror" + android:key="pref_camera2_selfiemirror_key" + android:layout="@layout/preference" + android:title="@string/pref_camera_selfiemirror_title" /> <ListPreference android:entries="@array/pref_camera2_picturesize_entries" android:entryValues="@array/pref_camera2_picturesize_entryvalues" @@ -263,4 +268,4 @@ android:summary="Version" android:title="Version Info" /> </PreferenceCategory> -</PreferenceScreen>
\ No newline at end of file +</PreferenceScreen> diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java index 997525c50..065a9606f 100644 --- a/src/com/android/camera/CaptureModule.java +++ b/src/com/android/camera/CaptureModule.java @@ -1388,7 +1388,7 @@ public class CaptureModule implements CameraModule, PhotoController, mImageReader[i] = ImageReader.newInstance(mPictureSize.getWidth(), mPictureSize.getHeight(), imageFormat, PostProcessor.MAX_REQUIRED_IMAGE_NUM); } - if ((mPostProcessor.isFilterOn() || getFrameFilters().size() != 0 || mPostProcessor.isZSLEnabled()) + if ((mPostProcessor.isFilterOn() || getFrameFilters().size() != 0 || mPostProcessor.isZSLEnabled() || mPostProcessor.isSelfieMirrorOn()) && i == getMainCameraId()) { mImageReader[i].setOnImageAvailableListener(mPostProcessor.getImageHandler(), mImageAvailableHandler); } else { @@ -1926,7 +1926,7 @@ public class CaptureModule implements CameraModule, PhotoController, mFrameProcessor.onOpen(getFrameProcFilterId(), mPreviewSize); } - if(mPostProcessor.isFilterOn() || getFrameFilters().size() != 0 || mPostProcessor.isZSLEnabled()) { + if(mPostProcessor.isFilterOn() || getFrameFilters().size() != 0 || mPostProcessor.isZSLEnabled() || mPostProcessor.isSelfieMirrorOn()) { setUpCameraOutputs(ImageFormat.YUV_420_888); } else { setUpCameraOutputs(ImageFormat.JPEG); @@ -2900,7 +2900,7 @@ public class CaptureModule implements CameraModule, PhotoController, if (seconds > 0) { mUI.startCountDown(seconds, true); } else { - if((mPostProcessor.isFilterOn() || getFrameFilters().size() != 0) + if((mPostProcessor.isFilterOn() || getFrameFilters().size() != 0 || mPostProcessor.isSelfieMirrorOn()) && mPostProcessor.isItBusy()) { warningToast("It's still busy processing previous scene mode request."); return; @@ -3077,6 +3077,10 @@ public class CaptureModule implements CameraModule, PhotoController, updatePreview = true; applyFaceDetection(mPreviewRequestBuilder[cameraId]); break; + case SettingsManager.KEY_FLASH_MODE: + updatePreview = true; + applyFlash(mPreviewRequestBuilder[cameraId], cameraId); + break; } return updatePreview; } diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java index e6ced7439..aa11c6be8 100644 --- a/src/com/android/camera/SettingsManager.java +++ b/src/com/android/camera/SettingsManager.java @@ -107,6 +107,7 @@ public class SettingsManager implements ListMenu.SettingsListener { public static final String KEY_EXPOSURE = "pref_camera2_exposure_key"; public static final String KEY_TIMER = "pref_camera2_timer_key"; public static final String KEY_LONGSHOT = "pref_camera2_longshot_key"; + public static final String KEY_SELFIEMIRROR = "pref_camera2_selfiemirror_key"; public static final String KEY_VIDEO_DURATION = "pref_camera2_video_duration_key"; public static final String KEY_VIDEO_QUALITY = "pref_camera2_video_quality_key"; public static final String KEY_VIDEO_ENCODER = "pref_camera2_videoencoder_key"; diff --git a/src/com/android/camera/imageprocessor/PostProcessor.java b/src/com/android/camera/imageprocessor/PostProcessor.java index 72ac30fb9..41dbca33d 100644 --- a/src/com/android/camera/imageprocessor/PostProcessor.java +++ b/src/com/android/camera/imageprocessor/PostProcessor.java @@ -35,6 +35,7 @@ import android.graphics.Rect; import android.graphics.YuvImage; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; +import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraMetadata; import android.hardware.camera2.CaptureFailure; @@ -350,6 +351,13 @@ public class PostProcessor{ return false; } + public boolean isSelfieMirrorOn() { + if (SettingsManager.getInstance().getValue(SettingsManager.KEY_SELFIEMIRROR).equalsIgnoreCase("on")) { + return true; + } + return false; + } + public void onOpen(int postFilterId, boolean isLongShotOn, boolean isFlashModeOn) { mImageHandlerTask = new ImageHandlerTask(); @@ -669,6 +677,15 @@ public class PostProcessor{ filter.init(resultImage.width, resultImage.height, resultImage.stride, resultImage.stride); filter.addImage(resultImage.outBuffer, null, 0, new Boolean(false)); } + + if(isSelfieMirrorOn() && !mController.isBackCamera()) { + if(mController.getMainCameraCharacteristics() != null && + mController.getMainCameraCharacteristics().get(CameraCharacteristics.SENSOR_ORIENTATION) == 90) { + nativeFlipNV21(resultImage.outBuffer.array(), resultImage.stride, resultImage.height, true); + } else { + nativeFlipNV21(resultImage.outBuffer.array(), resultImage.stride, resultImage.height, false); + } + } } //End processing FrameProessor filter clear(); @@ -719,8 +736,7 @@ public class PostProcessor{ } } - private native int nativeFlipVerticalNV21(byte[] buf, int stride, int height); - + private native int nativeFlipNV21(byte[] buf, int stride, int height, boolean isVertical); static { System.loadLibrary("jni_imageutil"); } diff --git a/src/com/android/camera/imageprocessor/ZSLQueue.java b/src/com/android/camera/imageprocessor/ZSLQueue.java index ce2da1c6b..792489cbc 100644 --- a/src/com/android/camera/imageprocessor/ZSLQueue.java +++ b/src/com/android/camera/imageprocessor/ZSLQueue.java @@ -290,9 +290,9 @@ public class ZSLQueue { } if( captureResult.get(CaptureResult.CONTROL_AE_STATE) != null && - captureResult.get(CaptureResult.CONTROL_AF_STATE) != null && + captureResult.get(CaptureResult.FLASH_MODE) != null && captureResult.get(CaptureResult.CONTROL_AE_STATE).intValue() == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED && - captureResult.get(CaptureResult.CONTROL_AF_STATE).intValue() != CaptureResult.FLASH_MODE_OFF) { + captureResult.get(CaptureResult.FLASH_MODE).intValue() != CaptureResult.FLASH_MODE_OFF) { return true; } diff --git a/src/com/android/camera/imageprocessor/filter/BeautificationFilter.java b/src/com/android/camera/imageprocessor/filter/BeautificationFilter.java index c9c559d3e..ec60db749 100644 --- a/src/com/android/camera/imageprocessor/filter/BeautificationFilter.java +++ b/src/com/android/camera/imageprocessor/filter/BeautificationFilter.java @@ -56,17 +56,11 @@ public class BeautificationFilter implements ImageFilter { private static boolean DEBUG = false; private static String TAG = "BeautificationFilter"; private static boolean mIsSupported = false; - private int mStrengthValue = 0; private static int FACE_TIMEOUT_VALUE = 60; //in frame count private int mFaceTimeOut = FACE_TIMEOUT_VALUE; public BeautificationFilter(CaptureModule module) { mModule = module; - String value = SettingsManager.getInstance().getValue(SettingsManager.KEY_MAKEUP); - try { - mStrengthValue = Integer.parseInt(value); - } catch(Exception e) { - } } @Override @@ -120,18 +114,26 @@ public class BeautificationFilter implements ImageFilter { return; } Rect rect = faces[0].getBounds(); + int strengthValue = 100; + try { + String str = SettingsManager.getInstance().getValue(SettingsManager.KEY_MAKEUP); + strengthValue = Integer.parseInt(str); + } catch(Exception e) { + } int value = nativeBeautificationProcess(bY, bVU, mWidth, mHeight, mStrideY, (int)(rect.left*widthRatio), (int)(rect.top*heightRatio), - (int)(rect.right*widthRatio), (int)(rect.bottom*heightRatio), mStrengthValue, mStrengthValue); + (int)(rect.right*widthRatio), (int)(rect.bottom*heightRatio), strengthValue, strengthValue); if(DEBUG) { if(value == -1) { Log.d(TAG, "library initialization is failed."); } else if(value == -2) { Log.d(TAG, "No face is recognized"); - } else if(value >= 0 && !((Boolean)isPreview).booleanValue()){ - Log.d(TAG, "Successful beautification"); } } + if(value >= 0 && !((Boolean)isPreview).booleanValue()){ + Log.i(TAG, "Successful beautification at "+faces[0].toString()+ + " widthRatio: "+widthRatio+" heightRatio: "+ heightRatio+" Strength: "+strengthValue); + } } @Override |