유니티와 파이썬 socket 연결하고 파이썬에 이미지 저장하기

 

 

이미지 업로드 하는 코드

using System;
using System.Net.Sockets;
using System.IO;
using SimpleFileBrowser;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Windows;
using File = System.IO.File;

public class ImageCaptureAndSend : MonoBehaviour
{
    public string serverIP = "127.0.0.1"; // Python 서버 IP 주소
    public int serverPort = 65432;         // Python 서버 포트
    public RawImage rawImageDisplay;      // RawImage 컴포넌트

    public void CaptureAndSendImage()
    {
        // RawImage의 텍스처를 Texture2D로 변환
        Texture2D texture = RawImageToTexture2D(rawImageDisplay);
        if (texture == null)
        {
            Debug.LogError("RawImage does not have a texture.");
            return;
        }
        // 이미지를 PNG로 변환
        byte[] imageBytes = texture.EncodeToPNG();
        // 소켓을 통해 전송
        SendImageToServer(imageBytes);
    }
    public void AttachAndDisplayImage()
    {
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
        string filePath = ShowFileDialog();
        if (!string.IsNullOrEmpty(filePath))
        {
            byte[] imageBytes = File.ReadAllBytes(filePath);
            Texture2D texture = new Texture2D(2, 2);
            if (texture.LoadImage(imageBytes))
            {
                DisplayImageInRawImage(texture);
                Debug.Log("Selected image displayed in RawImage.");
            }
            else
            {
                Debug.LogError("Failed to load image from file.");
            }
        }
        else
        {
            Debug.LogWarning("No file selected.");
        }
#endif
#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
    string filePath = ShowFileDialogMacOS();
    if (!string.IsNullOrEmpty(filePath))
    {
        byte[] imageBytes = File.ReadAllBytes(filePath);
        Texture2D texture = new Texture2D(2, 2);
        if (texture.LoadImage(imageBytes))
        {
            DisplayImageInRawImage(texture);
            Debug.Log("Selected image displayed in RawImage.");
        }
        else
        {
            Debug.LogError("Failed to load image from file.");
        }
    }
    else
    {
        Debug.LogWarning("No file selected.");
    }
#endif
    }
    private string ShowFileDialogMacOS()
    {
        // macOS용 파일 대화상자 호출
        string filePath = UnityEditor.EditorUtility.OpenFilePanel("Select an Image", "", "png,jpg,jpeg");
        if (string.IsNullOrEmpty(filePath))
        {
            Debug.LogWarning("No file selected.");
        }
        return filePath;
    }
    private string ShowFileDialog()
    {
        // Windows 플랫폼에서는 OpenFileDialog를 대체
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
        using (System.Windows.Forms.OpenFileDialog openFileDialog = new System.Windows.Forms.OpenFileDialog())
        {
            openFileDialog.Title = "Select an Image";
            openFileDialog.Filter = "Image Files (*.png;*.jpg;*.jpeg)|*.png;*.jpg;*.jpeg";
            openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);

            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                return openFileDialog.FileName;
            }
        }
#endif
        // 기본 파일 경로 반환
        Debug.LogWarning("File dialog not supported on this platform.");
        return null;
    }
    
    private void SendImageToServer(byte[] imageBytes)
    {
        try
        {
            // TCP 클라이언트 생성
            TcpClient client = new TcpClient(serverIP, serverPort);
            NetworkStream stream = client.GetStream();

            // 이미지 크기를 먼저 전송
            byte[] sizeInfo = BitConverter.GetBytes(imageBytes.Length);
            Array.Reverse(sizeInfo); // 빅 엔디안으로 변환
            stream.Write(sizeInfo, 0, sizeInfo.Length);
            
            // 이미지 데이터를 전송
            stream.Write(imageBytes, 0, imageBytes.Length);
            Debug.Log("Image sent to server successfully.");

            // 연결 종료
            stream.Close();
            client.Close();
        }
        catch (Exception e)
        {
            Debug.LogError($"Error sending image to server: {e.Message}");
        }
    }

    private void DisplayImageInRawImage(Texture2D texture)
    {
        if (rawImageDisplay != null)
        {
            rawImageDisplay.texture = texture;
            rawImageDisplay.rectTransform.sizeDelta = new Vector2(texture.width, texture.height);
            Debug.Log("Image displayed in RawImage.");
        }
        else
        {
            Debug.LogError("RawImage component is not assigned.");
        }
    }
    private Texture2D RawImageToTexture2D(RawImage rawImage)
    {
        if (rawImage.texture == null)
        {
            Debug.LogError("RawImage does not have a valid texture.");
            return null;
        }
        // RawImage 텍스처 타입 확인
        if (rawImage.texture is Texture2D existingTexture2D)
        {
            Debug.Log("RawImage contains a Texture2D. Returning it directly.");
            return existingTexture2D;
        }
        // RenderTexture로 변환 후 Texture2D로 복사
        try
        {
            Texture texture = rawImage.texture;
            RenderTexture renderTexture = RenderTexture.GetTemporary(
                texture.width,
                texture.height,
                0,
                RenderTextureFormat.Default,
                RenderTextureReadWrite.Linear);

            Graphics.Blit(texture, renderTexture);
            RenderTexture previous = RenderTexture.active;
            RenderTexture.active = renderTexture;

            Texture2D texture2D = new Texture2D(texture.width, texture.height, TextureFormat.RGB24, false);
            texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
            texture2D.Apply();

            RenderTexture.active = previous;
            RenderTexture.ReleaseTemporary(renderTexture);

            Debug.Log("Successfully converted RawImage texture to Texture2D.");
            return texture2D;
        }
        catch (Exception e)
        {
            Debug.LogError($"Error converting RawImage texture to Texture2D: {e.Message}");
            return null;
        }
    }

}

 

 

파이썬에서 소켓 통신 연결하기 

import socket
import struct
from PIL import Image
import io


def start_server(host='127.0.0.1', port=65432):
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((host, port))
    server_socket.listen(1)
    print(f"Server listening on {host}:{port}")

    while True:
        conn, addr = server_socket.accept()
        print(f"Connection established with {addr}")

        # Receive the size of the incoming data
        data_size = struct.unpack('>I', conn.recv(4))[0]
        print(f"Expecting {data_size} bytes of data")

        # Receive the image data
        data = b""
        while len(data) < data_size:
            packet = conn.recv(4096)
            if not packet:
                break
            data += packet

        print("Image received. Processing...")

        # Convert bytes to image
        image = Image.open(io.BytesIO(data))
        image.show()  # Display the received image (optional)

        # Save the received image
        image.save("ReceivedImage.png")
        print("Image saved as 'ReceivedImage.png'")

        conn.close()

if __name__ == "__main__":
    start_server()