streaming PNG image files with bolt from client to server

I am creating a game where a bunch of players draw a picture before having the image sent though the stream system. I'm not exactly clear as to what I have done wrong, and the documentation on the stream serveice does not help either(it says how to send, but not how to recive image for some reason).

anyway this is what I need: have the client mark the image so the server knows which client sent it, then have it sent through BOLT stream, then recive it on the other end and display it on a set of "canvas" which each marked to the corrosponding player.

code below, and it currently as a class on its own. the main connection program was based on the bolt samples lobbymanager:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class sendReciveImage : Bolt.GlobalEventListener
{
    /*
    public override void Connected(BoltConnection connection)
    {
        // Configure this connection to send at 1000kb/s
        connection.SetStreamBandwidth(1024 * 1000);
    }*/
    private const string ImageChannelName = "ImageChannelName";
    private static UdpKit.UdpChannelName ImageTranferChannel;

    public override void BoltStartBegin()
    {
        ImageTranferChannel = BoltNetwork.CreateStreamChannel(ImageChannelName, UdpKit.UdpChannelMode.Reliable, 1);//creates channel
    }
    //open image file and convert to byte
    public void CreateFolder()
    {
        if (!(Directory.Exists("drawings/")))
        {
            var folder = Directory.CreateDirectory("drawings/");
        }
    }
    private byte[] ImagetoByte(string filename)
    {
        byte[] imageByteData = null;
        string[] filepaths;

        if (Directory.Exists("drawings/" + filename + ".png"))
        {
            BoltLog.Info("loading image");
            filepaths = Directory.GetFiles("drawings/" + filename + ".png");

            WWW www = new WWW("file://" + filepaths[0]);//"download file from disk"
            
            Texture2D new_texture = new Texture2D(1315, 1991);//create texture2D 
            www.LoadImageIntoTexture(new_texture);//insert image into texture

            imageByteData = ImageConversion.EncodeToPNG(new_texture);//encodes the image
        }
        else
        {
            BoltLog.Info("FILE DOES NOT EXIST");
        }
        return imageByteData;
    }
    private Texture2D ByteToImageTexture(byte[] imageByteData)//insert byte array and it retyrbs a texture2D
    {
        Texture2D drawing = new Texture2D(1315, 1991);

        drawing.LoadImage(imageByteData);
        drawing.Apply();

        return drawing;
    }

    public void sendDrawing(string imagename)
    {
        byte[] imageByteData=ImagetoByte(imagename);
        BoltNetwork.Server.StreamBytes(ImageTranferChannel, imageByteData);

    }
    
    public Texture2D reciveImage(BoltConnection connection)
    {
        byte[] imagebyte=null;
        Texture2D drawing=null;
        //code for reciving image goes here

        drawing.LoadImage(imagebyte);
        return drawing;
    }
    
    public override void SceneLoadLocalDone(string scene)//debuging
    {
        if (BoltNetwork.IsClient)
        {
            BoltLog.Info("sending image");
            sendDrawing("test image");

        }
        else if (BoltNetwork.IsServer)
        {
           // reciveImage(BoltNetwork.c);
        }
    }
}

Comments

  • Hi,

    We suggest you taking a look at the "NetworkedPaint" sample, as it shows how you can transfer textures using the Stream System.

    Link: https://github.com/BoltEngine/Bolt-Sample/tree/master/NetworkedPaint

    --
    Ramon Melo
    Photon Bolt Team
  • Howardxu23
    edited April 2021
    I'm not sure what I'm missing, but my code saying that UdpStreamData is missing from my code when I pasted it over from some reason, and I cannot locate where.

    EDIT: turns out I need to import Udpkit. dang it, it does not state clearly anywhere that it needs to do that
  • Hmm still does not seem to work, and I’m not entirely sure on how exactly one implements it. Is there a more step by step guide of sending and receiving image though bolt stream?

  • Hi,

    The core of the implementation you are looking for is in this file: https://github.com/BoltEngine/Bolt-Sample/blob/master/NetworkedPaint/Scripts/Network/CharacterPaintChannelManager.cs

    There is no extra documentation other than the code itself, but it should be straightforward to adapt to your needs.
    We are using a Protocol Token in order to store all information about the target entity, texture, and so on, so it can be serialized/deserialized on the other ends.

    --
    Ramon Melo
    Photon Bolt Team
  • Howardxu23
    edited April 2021
    so let's see
    I would need to include size, width, height and format of the texture/image that I want and put it into the created object of the class PlayerTextureMeta, but turning the image directly into bytes would not work?

    I have one more quetion though, what is the "entityID" the code refrecnes to? is it possible for the serailiser to accept player usernames to allow the server to differenciate who is sent from? since I would need that to allow the players to see the results of who's drawing during voting, and targeted reciver or something since I would need to have 2 different sets of code for the clients and the server.

    the stream transmission is one way only, from client to the server only, no client to client or server to cleint

    With that said, I do have issues understanding how code works exactly unless it is explained line by line, or as close to one, I'm sorry :s