高斯模糊場景:手機相機不同于工業相機以及車載相機,手機相機的模式切換往往會伴隨著預覽解析度的改變,而解析度的切換伴隨手機App->Framework->HAL->Drivel一層層的下發上傳,所造成的時間延遲已經帶來了不可忽略的視覺沖擊,為了緩解這種沖擊,引入高斯模糊對手機切換解析度場景進行處理,提高用戶體驗舒適度,
應用層處理高斯模糊:
1.處理時機:肯定是越早越好,放到CameraActivity的Resume階段,保證了每一次切換都可以調到高斯模糊的showPreviewAnim(0)方法,
@Override
protected void onResumeTasks() {
super.onResumeTasks();
PictureQuality.enterCameraMode();
mCameraAppUI.showPreviewAnim(0);
mCameraAppUI.removeTopSurface();
CameraSysTrace.onEventSystrace("CameraActivity.onResumeTasks", false, true);
}
//高斯模糊的處理,getPreviewBlurDrawable拿到最后的預覽Bitmap
public void showPreviewAnim(int duration) {
if (mSwitchAnim == null || mSwitchAnim.getVisibility() == View.VISIBLE) {
return;
}
if (!mPause) {
getPreviewBlurDrawable();
}
if (mLastBitmap == null) {
mLastBitmap = mDefaultBitmap;
}
//RectF rect = new RectF(0, 0, 720, 1280);
RectF rect = mPreviewManager.getPreviewArea();
if (!isCameraSwitch) {
mSwitchAnim.setVisibility(View.VISIBLE);
startSwitchAnimation(0.0f, 1.0f, duration);
mSwitchAnim.setSwitchAnimInfo(mLastBitmap, rect);
}
}
2.高斯模糊去除時機:這個肯定是要在舊的預覽session已經切斷,新的預覽session創建且上傳資料之后去除高斯模糊效果,可通過下發預覽請求時的回呼函式達到這個時機的監控以及把握,CaptureCallback回呼函式的onCaptureFailed捕捉舊預覽切斷的時機,onCaptureCompleted捕捉新預覽第一幀資料上傳時機,
//下發repeatingPreview請求
mSession.setRepeatingRequest(mBuilder.build(), mCaptureCallback, mModeHandler);
//mCaptureCallback回呼函式監控
private final CaptureCallback mCaptureCallback = new CaptureCallback() {
@Override
public void onCaptureCompleted(@Nonnull CameraCaptureSession session,
@Nonnull CaptureRequest request, @Nonnull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
if (mCamera2Proxy == null
|| mModeDeviceCallback == null
|| session.getDevice() != mCamera2Proxy.getCameraDevice()) {
return;
}
if (!CameraUtil.isStillCaptureTemplate(result) && !mFirstFrameArrived) {
mFirstFrameArrived = true;
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
LogHelper.d(TAG, "[onCaptureCompleted] hidePreviewAnim");
((CameraAppUI) ((CameraActivity) mActivity).getAppUi()).hidePreviewAnim(0);
}
}, 700);
}
}
@Override
public void onCaptureFailed(@Nonnull CameraCaptureSession session,
@Nonnull CaptureRequest request, @Nonnull CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
}
3.高斯模糊預覽幀獲:通過應用層接收預覽buffer的CaptureSurface的OnImageAvailable來獲取預覽的Image,高斯模糊對之前解析度下的最后一幀Buffer進行模糊處理,
private PreviewImageCallback mPreviewImageCallback;
public interface PreviewImageCallback {
void onPreviewImageCallback(Image image);
}
public void setPreviewCallback(PreviewImageCallback captureCallback) {
mPreviewImageCallback = captureCallback;
}
public final OnImageAvailableListener mCaptureImageListener = new OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader imageReader) {
int format = image.getFormat();
int width = image.getWidth();
int height = image.getHeight();
if((format == ImageFormat.YUV_420_888 && "previewImage".equalsIgnoreCase(mCaptureType))) {
if(mPreviewImageCallback != null) {
mPreviewImageCallback.onPreviewImageCallback(image);
}
image.close();
}
}
}
//每次下發repeatingPreview請求時
mPreviewImageSurface.setPreviewCallback(this);
@Override
public void onPreviewImageCallback(Image image) {
//拿到了預覽幀Image
((CameraAppUI) ((CameraActivity) mActivity).getAppUi()).setPreviewBitmap(image);
}
public void getPreviewBlurDrawable() {
mLastBitmap = mDefaultBitmap;
GaussianBlur blur = new GaussianBlur(mApp.getActivity());
Bitmap preview;
preview = getPreviewBitmap(mPreviewImageData);
if (preview != null) {
Bitmap bitmap = blur.blurBitmap(mApp.getActivity(), blur.small(preview));
if (bitmap != null) {
mLastBitmap = bitmap;
}
}
}
4.對最后的預覽幀Bitmap進行高斯模糊處理:對Bitmap資料的高斯模糊處理也是引入canvas以及一些Matrix的方式進行坐標的模糊處理,上代碼,
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final DisplayMetrics metrics = new DisplayMetrics();
mApp.getActivity().getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int[] loc = new int[2];
getPreviewFrameLayout().getLocationOnScreen(loc);
int x = loc[0];
int y = loc[1];
if (mBlurBitmapWidth > 0 && mBlurBitmapHeight > 0) {
mPreviewRatio = CameraUtil.determineRatio((int) mBlurBitmapWidth, (int) mBlurBitmapHeight);
canvas.drawColor(mBgColor);
mMatrix.reset();
final Bitmap bitmap = changeBitmapSize(mBlurBitmap, mBlurBitmapWidth, mBlurBitmapHeight);
mMatrix.postTranslate(x, y);
canvas.drawBitmap(bitmap, mMatrix, null);
}
}
經過高斯模糊處理后:


對比華為手機模式切換時候的高斯模糊處理:


轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/287415.html
標籤:其他
下一篇:C標準輸出流
