Skip to content

Commit

Permalink
optimize blur example
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Apr 15, 2024
1 parent ed4c89c commit 25d0fbf
Showing 1 changed file with 46 additions and 59 deletions.
105 changes: 46 additions & 59 deletions package/example/src/CameraPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,8 @@ import type { Routes } from './Routes'
import type { NativeStackScreenProps } from '@react-navigation/native-stack'
import { useIsFocused } from '@react-navigation/core'
import { usePreferredCameraDevice } from './hooks/usePreferredCameraDevice'
import type { SkPoint } from '@shopify/react-native-skia'
import { ClipOp, PaintStyle, PointMode, Skia, TileMode } from '@shopify/react-native-skia'
import { useTensorflowModel } from 'react-native-fast-tflite'
import { useResizePlugin } from 'vision-camera-resize-plugin'
import type { Face } from 'react-native-vision-camera-face-detector'
import { ClipOp, Skia, TileMode } from '@shopify/react-native-skia'
import type { Contours, Face } from 'react-native-vision-camera-face-detector'
import { detectFaces } from 'react-native-vision-camera-face-detector'

const ReanimatedCamera = Reanimated.createAnimatedComponent(Camera)
Expand Down Expand Up @@ -181,67 +178,57 @@ export function CameraPage({ navigation }: Props): React.ReactElement {
location.requestPermission()
}, [location])

// idk why but for some reason the face bounding boxes are divided by 2?
const MULTIPLIER = 2
const frameProcessor = useSkiaFrameProcessor((frame) => {
'worklet'

frame.render()

const result = detectFaces({
frame: frame,
options: {
performanceMode: 'fast',
contourMode: 'all',
landmarkMode: 'none',
},
})
const blurRadius = 25
const blurFilter = Skia.ImageFilter.MakeBlur(blurRadius, blurRadius, TileMode.Repeat, null)
const paint = Skia.Paint()
paint.setImageFilter(blurFilter)

// idk why but for some reason the face landmarks are divided by 2 relative to the Frame?
const MULTIPLIER = 1.9
const frameProcessor = useSkiaFrameProcessor(
(frame) => {
'worklet'

frame.render()

const result = detectFaces({
frame: frame,
options: {
performanceMode: 'fast',
contourMode: 'all',
landmarkMode: 'none',
classificationMode: 'none',
},
})

const blurRadius = 20
const blurFilter = Skia.ImageFilter.MakeBlur(blurRadius, blurRadius, TileMode.Repeat, null)
const paint = Skia.Paint()
paint.setImageFilter(blurFilter)
const faces = result.faces as unknown as Face[]

const debug = Skia.Paint()
debug.setColor(Skia.Color('red'))
for (const face of faces) {
if (face.contours == null) {

Check failure on line 207 in package/example/src/CameraPage.tsx

View workflow job for this annotation

GitHub Actions / Lint JS (eslint, prettier)

Unnecessary conditional, the types have no overlap.
console.log('no countours for this face!')
continue
}

for (const face of result.faces as unknown as Face[]) {
// detect faces
const path = Skia.Path.Make()

if (face.contours == null) {
console.log('no countours for this face!')
continue
}

const path = Skia.Path.Make() // Function to add a series of points to the path
const addContourToPath = (pointsArray: SkPoint[]) => {
if (pointsArray.length > 0) {
path.moveTo(pointsArray[0].x * 2, pointsArray[0].y * 2)
pointsArray.slice(1).forEach((point) => {
path.lineTo(point.x * 2, point.y * 2)
const necessaryContours: (keyof Contours)[] = ['FACE', 'LEFT_CHEEK', 'RIGHT_CHEEK']
for (const key of necessaryContours) {
const points = face.contours[key]
path.moveTo(points[0].x * MULTIPLIER, points[0].y * MULTIPLIER)
points.slice(1).forEach((point) => {
path.lineTo(point.x * MULTIPLIER, point.y * MULTIPLIER)
})
path.close() // Close each contour to complete its loop
path.close()
}
}

// Iterate over each key in the contours object to add to the path
Object.keys(face.contours).forEach((key) => {
addContourToPath(face.contours[key])
})

// Save the current state of the canvas
frame.save()

// Set the path as the clipping region
frame.clipPath(path, ClipOp.Intersect, true)

// Draw the image with the blur filter applied within the clipping region
frame.drawImage(frame.__skImage, 0, 0, paint)

// Restore the canvas to remove the clip
frame.restore()
}
}, [])
frame.save()
frame.clipPath(path, ClipOp.Intersect, true)
frame.drawImage(frame.__skImage, 0, 0, paint)
frame.restore()
}
},
[paint],
)

const videoHdr = format?.supportsVideoHdr && enableHdr
const photoHdr = format?.supportsPhotoHdr && enableHdr && !videoHdr
Expand Down

0 comments on commit 25d0fbf

Please sign in to comment.