2

我目前正在尝试在一个带有expo-camera. 为此,我需要访问与屏幕上特定像素相关的颜色信息,这些信息是根据用户交互选择的。

获取该信息的最佳方式是什么?

我的第一个想法是拍摄一张照片并使用点击坐标在图像中找到我正在搜索的像素,然后从该图像中提取信息。为此,我尝试使用该react-native-pixel-color库(和类似的库),但它似乎已被放弃。

请注意,我目前不了解 Swift,因此如果一切都失败了,编写原生解决方案通常是最后的手段。

谢谢!

4

1 回答 1

0

我想到了。好消息:与完全托管的 Expo 兼容。坏消息:它非常难看(您的模块仍然值得编写)。

总结是:

  1. 使用 expo-camera 显示来自用户相机的视图
  2. 使用 expo-gl 将相机视图从 expo-camera 加载到 GLView
  3. 使用 expo-gl 拍摄 GLView 的快照
  4. 使用 expo-image-manipulator 将步骤 3 中拍摄的快照缩小到屏幕上所需的区域
  5. 使用 react-native-canvas 将像素读入 ImageData 对象

一些代码: 首先,我的导入:

import { Camera } from "expo-camera";
import React, { useState, useEffect, useRef, useCallback } from "react";
import { GLView } from "expo-gl";
import * as FileSystem from "expo-file-system";
import * as ImageManipulator from "expo-image-manipulator";
import Canvas, { Image as CanvasImage } from "react-native-canvas";
import { StyleSheet, Text, TouchableOpacity, View, Image } from "react-native";

步骤 1 和 2 在这里完成: https ://github.com/expo/expo/blob/master/apps/native-component-list/src/screens/GL/GLCameraScreen.tsx

唯一需要的修饰是将结尾更改为fragShaderSource以下内容:

void main() {
  fragColor = vec4(texture(cameraTexture, uv).rgb, 1.0);
}`;

这是因为 Expo 的演示反转了颜色。

第三步:将用GLView的onContextCreate传入的gl变量传入这个:

const takeFrame = async (gl) => {
  const snapshot = await GLView.takeSnapshotAsync(gl, {
    format: "jpeg",
  });
  return snapshot.uri;
};

第 4 步:在此处从 takeFrame 传入 uri:

const cropFrame = async (uri) => {
  // Find minX, minY, width, height

  const result = await ImageManipulator.manipulateAsync(uri, [
    {
      crop: {
        originX: minX,
        originY: minY,
        width,
        height
      },
    },
  ]);

  return result.uri;
};

第五步:需要提取base64版本的图片,传入react-native-canvas:

const readImage = async (imgSrc, width, height) => {
  setImgUri(imgSrc);
  canvas.width = width;
  canvas.height = height;
  const context = canvas.getContext("2d");
  const image = new CanvasImage(canvas);

  const options = { encoding: "base64", compress: 0.4 };
  const base64 = await FileSystem.readAsStringAsync(imgSrc, options);
  const src = "data:image/jpeg;base64," + base64;
  image.src = src;
  image.addEventListener("load", () => {
    context.drawImage(image, 0, 0);
    context
      .getImageData(0, 0, canvas.width, canvas.height)
      .then((imageData) => {
        console.log(
          "Image data:",
          imageData,
          Object.values(imageData.data).length
        );
      })
      .catch((e) => {
        console.error("Error with fetching image data:", e);
      });
  });
};

请让我知道是否有更好的方法来做到这一点:)

于 2021-06-17T23:14:19.310 回答