Вот моя ситуация. Я хочу создать измененное изображение jpeg из загруженного пользователем изображения, а затем отправить его на S3 для хранения, но я хочу избежать записи измененного jpeg на диск, а затем перезагрузить его для запроса S3.
Есть ли способ сделать это полностью в памяти, с данными изображения JPEG, отформатированными, сохраненными в переменной?
Большинство людей, использующих PHP, выбирают либо ImageMagick, либо Gd2
Я никогда не использовал Imagemagick; метод Gd2:
<?php // assuming your uploaded file was 'userFileName' if ( ! is_uploaded_file(validateFilePath($_FILES[$userFileName]['tmp_name'])) ) { trigger_error('not an uploaded file', E_USER_ERROR); } $srcImage = imagecreatefromjpeg( $_FILES[$userFileName]['tmp_name'] ); // Resize your image (copy from srcImage to dstImage) imagecopyresampled($dstImage, $srcImage, 0, 0, 0, 0, RESIZED_IMAGE_WIDTH, RESIZED_IMAGE_HEIGHT, imagesx($srcImage), imagesy($srcImage)); // Storing your resized image in a variable ob_start(); // start a new output buffer imagejpeg( $dstImage, NULL, JPEG_QUALITY); $resizedJpegData = ob_get_contents(); ob_end_clean(); // stop this output buffer // free up unused memmory (if images are expected to be large) unset($srcImage); unset($dstImage); // your resized jpeg data is now in $resizedJpegData // Use your Undesigned method calls to store the data. // (Many people want to send it as a Hex stream to the DB:) $dbHandle->storeResizedImage( bin2hex($resizedJpegData) ); ?>
Надеюсь это поможет.
После того, как вы приобрели JPEG в памяти (используя ImageMagick , GD или вашу графическую библиотеку), вам необходимо загрузить объект из памяти в S3.
Многие PHP S3-классы, как представляется, поддерживают только файлы, но тот, на Undesigned, похоже, делает то, что мы здесь,
// Manipulate image - assume ImageMagick, so $im is image object $im = new Imagick(); // Get image source data $im->readimageblob($image_source); // Upload an object from a resource (requires size): $s3->putObject($s3->inputResource($im->getimageblob(), $im->getSize()), $bucketName, $uploadName, S3::ACL_PUBLIC_READ);
Если вы используете GD вместо этого, вы можете использовать imagecreatefromstring для чтения изображения из потока, но я не уверен, можете ли вы получить размер результирующего объекта, как требуется s3->inputResource
выше – getimagesize возвращает высота, ширина и т. д., но не размер ресурса изображения.
Это можно сделать с использованием библиотеки GD и буферизации вывода. Я не знаю, насколько эффективно это сравнивается с другими методами, но не требует явного создания файлов.
//$image contains the GD image resource you want to store ob_start(); imagejpeg($image); $jpeg_file_contents = ob_get_contents(); ob_end_clean(); //now send $jpeg_file_contents to S3
Довольно поздно в игру на этом, но если вы используете библиотеку S3, упомянутую ConroyP и Imagick, вы должны использовать метод putObjectString () вместо putObject () из-за того, что getImageBlob возвращает строку. Пример, который, наконец, помог мне:
$headers = array( 'Content-Type' => 'image/jpeg' ); $s3->putObjectString($im->getImageBlob(), $bucket, $file_name, S3::ACL_PUBLIC_READ, array(), $headers);
Я немного боролся с этим, надеюсь, это помогает кому-то другому!
Поймите, это старая нить, но я провел некоторое время, ударяя головой о стену на это сегодня, и подумал, что возьму здесь свое решение для следующего парня.
Этот метод использует AWS SDK для PHP 2 и GD для изменения размера изображения (Imagick также может быть легко использован).
require_once('vendor/aws/aws-autoloader.php'); use Aws\Common\Aws; define('AWS_BUCKET', 'your-bucket-name-here'); // Configure AWS factory $aws = Aws::factory(array( 'key' => 'your-key-here', 'secret' => 'your-secret-here', 'region' => 'your-region-here' )); // Create reference to S3 $s3 = $aws->get('S3'); $s3->createBucket(array('Bucket' => AWS_BUCKET)); $s3->waitUntilBucketExists(array('Bucket' => AWS_BUCKET)); $s3->registerStreamWrapper(); // Do your GD resizing here (omitted for brevity) // Capture image stream in output buffer ob_start(); imagejpeg($imageRes); $imageFileContents = ob_get_contents(); ob_end_clean(); // Send stream to S3 $context = stream_context_create( array( 's3' => array( 'ContentType'=> 'image/jpeg' ) ) ); $s3Stream = fopen('s3://'.AWS_BUCKET.'/'.$filename, 'w', false, $context); fwrite($s3Stream, $imageFileContents); fclose($s3Stream); unset($context, $imageFileContents, $s3Stream);
Библиотека Imagemagick позволит вам это сделать. Для него существует множество оболочек PHP, подобных этому (есть даже пример кода для того, что вы хотите делать на этой странице;))
Я сталкиваюсь с той же проблемой, используя хранилище объектов openstack и библиотеку php-opencloud .
Вот мое решение, которое не использует функцию ob_start
и ob_end_clean
, но сохраняет изображение в памяти и в временном файле. Размер памяти и временного файла может быть адаптирован во время выполнения .
// $image is a resource created by gd2 var_dump($image); // resource(2) of type (gd) // we create a resource in memory + temp file $tmp = fopen('php://temp', '$r+'); // we write the image into our resource \imagejpeg($image, $tmp); // the image is now in $tmp, and you can handle it as a stream // you can, then, upload it as a stream (not tested but mentioned in doc http://docs.aws.amazon.com/aws-sdk-php/v2/guide/service-s3.html#uploading-from-a-stream) $s3->putObject(array( 'Bucket' => $bucket, 'Key' => 'data_from_stream.txt', 'Body' => $tmp )); // or, for the ones who prefers php-opencloud : $container->createObject([ 'name' => 'data_from_stream.txt', 'stream' => \Guzzle\Psr7\stream_for($tmp), 'contentType' => 'image/jpeg' ]);
О php://temp
( из официальной документации php ):
php: // memory и php: // temp – это потоки чтения и записи, которые позволяют хранить временные данные в файловой оболочке. Единственное различие между ними заключается в том, что память php: // всегда будет хранить свои данные в памяти, тогда как php: // temp будет использовать временный файл, как только объем данных будет достигнут предопределенного предела (по умолчанию это 2 МБ). Местоположение этого временного файла определяется так же, как функция sys_get_temp_dir ().
Предел памяти php: // temp можно контролировать с помощью добавления / maxmemory: NN, где NN – это максимальный объем данных для хранения в памяти перед использованием временного файла в байтах.
Maye, используя библиотеку GD .
Существует функция копирования части изображения и изменения ее размера. Конечно, частью может быть весь образ, таким образом, вы только измените его размер.
см. imagecopyresampled