Streaming video to a website that is accessible through internet

I'm trying to send a JPEG image to a website via internet.  Should i encode the image to BASE 64 format to do this or simply send the JPEG as string

  • while converting it to Base64 String your image size will be increased around 37% to Original size,
    I would recommends to send JPEG as simply string,
    I got one sample for sending camera image to a web page, may be it is related to your query gadget.renesas.com/.../4.html

    Regards,
    Ritesh

  • In reply to RiteshGohil:

    Thanks for the reply.But this example is for a web server.I want to send it to a website using a php script. I want to simply send the JPEG file content using AT+CIPSEND

  • In reply to RiteshGohil:

    i found a way to reconstruct a JPEG from hex values of JPEG.

    forum.dolphindatalab.com/thread-2940.html
  • In reply to jihas:

    Okay! In that case Base 64 option is better because it gives us a encoded string in a proper format,
    I am finding other way round for this problem, mostly by passing an image as Binary file and imagecreatefromstring and imagepng function on php side.

  • In reply to RiteshGohil:

    I tried many Libraries to convert jpeg to Base64 but they are all fail to convert the full jpeg.It only converts the start portion of jpeg only.

    This code capture image in every 6 seconds and outputs the jpeg image in hex format.

    #include <Arduino.h>
    #include <Camera.h>
    #include "SdUsbConnect.h"

    #define IMAGE_HW 160
    #define IMAGE_VW 120

    Camera camera(IMAGE_HW, IMAGE_VW); // CMOS Camera
    SdUsbConnect storage("storage");
    void setup() {
    Serial2.begin(115200);
    Serial.begin(115200);
    pinMode(PIN_ESP_IO0, OUTPUT);
    pinMode(PIN_ESP_EN, OUTPUT);
    digitalWrite(PIN_ESP_IO0, HIGH);
    digitalWrite(PIN_ESP_EN, LOW);
    delay(10);
    digitalWrite(PIN_ESP_EN, HIGH);
    pinMode(PIN_LED_RED, OUTPUT);
    pinMode(PIN_LED_GREEN, OUTPUT);
    pinMode(PIN_LED_YELLOW, OUTPUT);
    delay(6000);
    if(Serial2.find("ready"))
    {
    Serial.println("ESP READY");
    }

    // Camera
    camera.begin();

    // SD & USB
    Serial.print("Finding strage..");
    storage.wait_connect();
    Serial.println("done");
    }

    void loop()
    {

    FILE * wp = fopen("/storage/lychee_camera123.jpg", "w");
    if (wp != NULL)
    {
    digitalWrite(PIN_LED_YELLOW, HIGH);
    size_t size = camera.createJpeg();
    fwrite(camera.getJpegAdr(), sizeof(char), (int) size, wp);
    fclose(wp);
    digitalWrite(PIN_LED_YELLOW, LOW);
    }
    else
    {
    Serial.print("Not found jpg");
    digitalWrite(PIN_LED_RED, HIGH);
    delay(1);
    }

    FILE * fp = fopen("/storage/lychee_camera123.jpg", "r");
    if (fp != NULL)
    {
    digitalWrite(PIN_LED_GREEN, HIGH);
    fseek(fp, 0, SEEK_END);
    uint32_t jpegSize = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    uint8_t * buffer = (uint8_t*) malloc(jpegSize);
    Serial.print("size:");delay(5);Serial.println(jpegSize);
    delay(5);
    for (uint32_t i = 0; i <= jpegSize; i++)
    {
    buffer[i] = (uint8_t) fgetc(fp);
    if(buffer[i] < 0x10)
    {
    Serial.print("0");
    delay(3);
    }
    Serial.print(buffer[i],HEX);
    delay(5);
    Serial.print(" ");
    delay(3);
    }
    fclose(fp);
    for (uint32_t i = 0; i <= jpegSize; i++)
    {
    if(buffer[i] < 0x10)
    {
    Serial.print("0");
    delay(3);
    }
    Serial.print(buffer[i],HEX);
    delay(5);
    Serial.print(" ");
    delay(3);
    }
    Serial.println();
    }
    delay(6000);
    }
  • In reply to jihas:

    The above code generates hex values starting at FF D8 .Copy the hex values from FF D8 to FF D9 at the end and copy it to a text file and save it as 'jpegimg.txt'

    Then run the following python code to regenerate the JPEG image

    import binascii
    #reading the file contains hex values
    f=open('jpegimg.txt','r')
    input_jpeg=f.read()
    #removing white spaces and newlines from readed string
    input_jpeg=input_jpeg.strip()
    input_jpeg=input_jpeg.replace(' ', '')
    print input_jpeg
    f=open('testjpg.jpg','wb')
    f.write(binascii.a2b_hex(input_jpeg))
    f.close



    I'm planning to use python at server side to reproduce the jpeg


    Will upload the final code when ready

  • In reply to jihas:

    Hey, I had one question now!
    is there any particular reason for converting image into HEX? I am asking because you need more time for encode and decode it to Hex logic

    I would suggest you to read file in Binary and send it to php or python server, in that case you have both buffer and size plus you don't need any additional encode or decode function, php and python both had fread and fwrite which is binary safe that means our purpose is solved, no need to reconstruct it to Jpg or header loss

    you can correct me if I am wrong.

    Regards,
    Ritesh
  • In reply to RiteshGohil:

    How can i send it as binary without increase in data size?? I think the AT+CIPSEND command treat the data as strings.So if i have to send 1 byte as binary it will take 8 bytes. Instead i can send it as HEX or char but if i use char the data contains special characters that may change at the receiving end.
    To reproduce the image i need to write the hex string as binary at server side

    you can correct me if I am wrong.

    Regards,
    Jihas
  • In reply to jihas:

    Yes, you are right, there is no way we can send it as binary
    One thing I got idea is, you can use TCP socket communication using PHP or Python, in that case you can transfer you image to socket client server model.
    is it possible to use Socket communication for your case?

    Regards,
    Ritesh
  • In reply to jihas:

    In normal mode the AT+CIPSEND only supports 2048 bytes data packets.
    By changing the mode to wifi pass through mode( by AT+CIPMODE=1 )we can able to send larger data's.
    And the GET request can't handle data's with size more than 4kb , It's better to use POST request to send images or large files

    AT+CIPMODE=1
    AT+CIPSTART="TCP","example.com",80
    AT+CIPSEND //no need to send size
    POST /projects/2018/exmple.php? HTTP/1.1\r\nHost: example.com\r\nContent-Length: <size of the data+2>\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\ndata=<data>\r\n

    then we have to send escape sequence "+++" to exit from wifi pass through mode.A delay of 1000ms before and after the escape sequence is necessary

    example
    void upload_photo()
    {
    int cnt=1;
    FILE * fp = fopen("/storage/lychee_camera123.jpg", "r");
    if (fp != NULL)
    {
    fseek(fp, 0, SEEK_END);
    uint32_t jpegSize = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    uint8_t * buffer = (uint8_t*) malloc(jpegSize);
    Serial.print("size:");delay(5);Serial.println(jpegSize);
    delay(5);
    for (uint32_t i = 0; i < jpegSize; i++)
    {
    buffer[i] = (uint8_t) fgetc(fp);
    if(buffer[i]==0xD9 && buffer[i-1]==0xFF)
    {
    content_length=i*2;
    break;
    }
    }
    fclose(fp);
    for(int i=0;i<5;i++)
    {
    if(cnt==1)
    {
    if(sent("AT+CIPMODE=1")&&recv("OK"))
    {
    cnt++;
    }
    else
    {
    reset_esp32();
    }
    }
    if(cnt==2)
    {
    if(sent("AT+CIPSTART=\"TCP\",\"example.com\",80")&&recv("OK"))
    {
    cnt++;
    }
    }
    if(cnt==3)
    {
    break;
    }
    }
    if(sent("AT+CIPSEND")&&recv(">"))
    {
    Serial2.print("POST /projects/2018/setimage.php? HTTP/1.1\r\nHost: example.com\r\nContent-Length: ");
    Serial2.print(content_length+2);
    Serial2.print("\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\ndata=");
    for(uint32_t i = 0; i <=jpegSize; i++)
    {
    if(buffer[i] < 0x10)
    {
    Serial2.print('0');
    delay(1);
    }
    Serial2.print(buffer[i],HEX);
    delay(1);
    }
    Serial2.println("\r\n");
    delay(1000);
    Serial2.print("+++");
    delay(1000);
    }