카테고리 없음

react- img to webview

pishio 2025. 6. 16. 09:49

아래는 React Native에서 사진을 촬영하고 base64 이미지 데이터를 WebView로 전달,
WebView에서는 색을 추출한 후 React Native로 다시 전달하는 전체 흐름을 구현한 코드입니다.



✅ 구조
1. React Native
• 카메라 사용 (예: react-native-image-picker)
• 촬영 후 base64 이미지 WebView에 전달
2. WebView
• 전달받은 base64 이미지를 canvas에 그려서 색 추출
• 색 정보를 window.ReactNativeWebView.postMessage로 React Native에 전달



🔧 필요한 패키지

npm install react-native-image-picker react-native-webview




📱 React Native 코드

// CameraPreviewWithWebView.js
import React, { useRef, useState } from 'react';
import { View, Button, Alert } from 'react-native';
import { WebView } from 'react-native-webview';
import { launchCamera } from 'react-native-image-picker';

const htmlContent = `
<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    body { margin: 0; background: #000; display: flex; flex-direction: column; align-items: center; justify-content: center; }
    canvas { display: none; }
    img { width: 100%; max-width: 300px; }
  </style>
</head>
<body>
  <img id="photo" />
  <canvas id="canvas"></canvas>

  <script>
    function processImage(base64) {
      const img = document.getElementById('photo');
      const canvas = document.getElementById('canvas');
      const ctx = canvas.getContext('2d');
      
      img.onload = function () {
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img, 0, 0);

        // 중앙 픽셀 색 추출
        const x = Math.floor(img.width / 2);
        const y = Math.floor(img.height / 2);
        const pixel = ctx.getImageData(x, y, 1, 1).data;
        const [r, g, b, a] = pixel;

        const color = { r, g, b, a };
        window.ReactNativeWebView.postMessage(JSON.stringify(color));
      };

      img.src = base64;
    }

    window.addEventListener('message', (event) => {
      const base64 = event.data;
      processImage(base64);
    });
  </script>
</body>
</html>
`;

export default function CameraPreviewWithWebView() {
  const webViewRef = useRef(null);

  const takePhoto = () => {
    launchCamera(
      {
        mediaType: 'photo',
        includeBase64: true,
        cameraType: 'back',
      },
      (response) => {
        if (response.didCancel || response.errorCode) {
          Alert.alert('Camera cancelled or failed');
        } else if (response.assets && response.assets.length > 0) {
          const base64 = `data:${response.assets[0].type};base64,${response.assets[0].base64}`;
          // WebView에 base64 이미지 전달
          webViewRef.current.postMessage(base64);
        }
      }
    );
  };

  const handleMessage = (event) => {
    try {
      const color = JSON.parse(event.nativeEvent.data);
      Alert.alert('Extracted Color', `R: ${color.r}, G: ${color.g}, B: ${color.b}`);
    } catch (e) {
      console.error('Failed to parse message', e);
    }
  };

  return (
    <View style={{ flex: 1 }}>
      <Button title="Take Photo" onPress={takePhoto} />
      <WebView
        ref={webViewRef}
        originWhitelist={['*']}
        source={{ html: htmlContent }}
        onMessage={handleMessage}
        javaScriptEnabled
        injectedJavaScript={`window.isReactNativeWebView = true; true;`}
        style={{ flex: 1 }}
      />
    </View>
  );
}




🔍 흐름 요약
1. 버튼 누르면 launchCamera → 사진 찍고 base64 획득
2. postMessage()로 WebView에 base64 이미지 전달
3. WebView는 이미지 로딩 후 canvas에 그림
4. 중심 픽셀의 색상 추출
5. postMessage()로 React Native에 색상 전달
6. React Native는 onMessage에서 결과 처리 (Alert, 저장 등)



필요하다면:
• 터치한 위치의 색 추출
• 다양한 영역의 평균 색상
• 이미지 확대/축소 기능
• 색상 추출 시 좌표도 함께 전달

등을 추가할 수 있습니다. 필요하시면 말씀 주세요!