Created
October 5, 2023 17:47
-
-
Save timoisalive/2ea13e510e582f92dc3a8675f853671d to your computer and use it in GitHub Desktop.
Get image pixel data on Expo/React Native
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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?