Skip to content

Instantly share code, notes, and snippets.

@timoisalive
Created October 5, 2023 17:47
Show Gist options
  • Save timoisalive/2ea13e510e582f92dc3a8675f853671d to your computer and use it in GitHub Desktop.
Save timoisalive/2ea13e510e582f92dc3a8675f853671d to your computer and use it in GitHub Desktop.
Get image pixel data on Expo/React Native
import Expo2DContext from 'expo-2d-context'
import { Asset } from 'expo-asset'
import { GLView, GLViewProps } from 'expo-gl'
import React from 'react'
export type PixelData = {
asset: Asset
data: Uint8ClampedArray
height: number
width: number
}
export type PixelDataSource = Omit<PixelData, 'data'>
type GetPixelDataParams = {
expo2dContext: Expo2DContext
source: PixelDataSource
}
export const getPixelData = async (
params: GetPixelDataParams
): Promise<PixelData> => {
const { expo2dContext, source } = params
const rectangle = [0, 0, source.width, source.height] as const
// @ts-ignore
expo2dContext.drawImage(source.asset, ...rectangle)
return { ...source, data: expo2dContext.getImageData(...rectangle).data }
}
type GLViewWithPixelDataProps = Omit<
GLViewProps,
'enableExperimentalWorkletSupport' | 'msaaSamples' | 'onContextCreate'
> & {
isHidden?: boolean
source: PixelDataSource
onPixelDataChange: (pixelData: PixelData) => void
}
export function GLViewWithPixelData(props: GLViewWithPixelDataProps) {
const { isHidden = false, source, onPixelDataChange, ...rest } = props
return source.height > 0 && source.width > 0 ? (
<GLView
style={{
height: source.height,
width: source.width,
...(isHidden && {
opacity: 0,
pointerEvents: 'none',
position: 'absolute',
zIndex: -1,
}),
}}
onContextCreate={async (glContext) => {
if (
glContext.drawingBufferHeight > 1 &&
glContext.drawingBufferWidth > 1
) {
// @ts-ignore
const expo2dContext = new Expo2DContext(glContext, {
renderWithOffscreenBuffer: true,
})
const pixelData = await getPixelData({ expo2dContext, source })
onPixelDataChange(pixelData)
}
}}
{...rest}
/>
) : null
}
@fxxholub
Copy link

fxxholub commented Aug 8, 2024

It still works! Thats magic, only working code for reading pixels, that can be found on internet. Do you have an idea how to make it work for web thru expo?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment