Send image generated by PHP (GD) to Amazon S3

1

I have the following code to send an image up in my S3 bucket:

// Send.class.php
public function sendFile($file, $file_name) {
    try {
        $s3 -> putObject([
            "Bucket" => "mybucket",
            "Key" => "image/".$file_name,
            "SourceFile" => $file,
            "ACL" => "public-read"
        ]);

        return true;
    } catch(S3Exception $e) {
        return false;
    }
}

// index.php
$send = new Send();

$send -> sendFile($_FILES["file"]["tmp_name"], $_FILES["file"]["name"]);

The above code works fine, however, I want to send PHP-generated images (originally javascript-originated - jQuery - where I'm using the jqScribble : link ) for my bucket too, then I tried:

// index.php

error_reporting(E_ALL); // mostrar erros
ini_set('display_errors', 'On'); // mostrar erros

$send = new Send();

$data = $_POST["imgdt"]; // imagem originada no JavaScript

$data = substr($data, strpos($data, ",") + 1);

$data = base64_decode($data);
$imgRes = imagecreatefromstring($data);

ob_start();
imagepng($imgRes);
$imageImage = ob_get_contents();
ob_end_clean();

$send -> sendFile($imageImage, "test.png");

But, the following error is returned:

  

Fatal error: in /var/www/html/vendor/guzzlehttp/psr7/src/functions.php   online 299

And the function that corresponds to error line (299) is:

function try_fopen($filename, $mode)
{
    $ex = null;
    set_error_handler(function () use ($filename, $mode, &$ex) {
        $ex = new \RuntimeException(sprintf( // linha 299
            'Unable to open %s using mode %s: %s',
            $filename,
            $mode,
            func_get_args()[1]
        ));
    });

    $handle = fopen($filename, $mode);
    restore_error_handler();

    if ($ex) {
        /** @var $ex \RuntimeException */
        throw $ex;
    }

    return $handle;
}

As I understand it, the error occurs because it is not possible to open the file using the fopen function, but I do not know which alternatives to use. How can I resolve this?

    
asked by anonymous 02.12.2016 / 03:37

1 answer

1

The putObject method expects a file path, but you are passing a stream. For this you can use the S3 Stream Wrapper, which enables the use of the wrapper s3://

Your function should look like this:

public function sendFile($fileContents, $file_name) {
    try {

        // registra o stream wrapper pra poder usar o protocolo s3://
        $s3->registerStreamWrapper();

        // abre o stream
        $s3Stream = fopen('s3://'.'mybucket'.'/image/'.$file_name, 'w', false, stream_context_create(
            array(
                's3' => array(
                    'ContentType'=> 'image/png'
                )
            )
        ) );

        //escreve
        fwrite($s3Stream, $fileContents);

        //fecha
        fclose($s3Stream);

        return true;
    } catch(S3Exception $e) {
        return false;
    }
}

You can find the documentation here: link

    
09.12.2016 / 17:48