2008-10-09 4 views
11

Вот моя ситуация. Я хочу создать изображение с измененным размером jpeg с загруженного пользователем изображения, а затем отправить его на S3 для хранения, но я хочу избежать записи измененного jpeg в диск, а затем перезагрузите его для запроса S3.Создание изображения без сохранения его как локального файла

Есть ли способ сделать это полностью в памяти, с данными изображения JPEG в формате, сохраненным в переменной?

ответ

4

Библиотека Imagemagick позволит вам это сделать. Есть много PHP оберток как this один вокруг для него (есть даже example code за то, что вы хотите сделать на этой странице;))

-1

Майи с помощью GD library.

Существует функция копирования части изображения и изменения ее размера. Конечно, частью может быть весь образ, таким образом, вы только измените его размер.

см imagecopyresampled

6

После того, как вы получили 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 возвращает высоту, ширину и т. д., но не размер ресурса изображения.

+0

Я должен был уточнить - я использую класс Undesigned S3. Знаете ли вы, что GD делает то, что вы разместили выше? Прежде чем я перейду к установке imagemagick, было бы неплохо узнать, нужно ли мне это делать. – MPX 2008-10-09 22:26:06

+0

Мой GD немного отрывочен - я знаю, что вы можете читать изображение в точности так же, как и ImageMagick, но не уверен в том, что вы хотите получить размер объекта, хотя прошло некоторое время с тех пор, как я просмотрел документы и ничего не видел. ImageMagick стоит установки, хотя ИМО! – ConroyP 2008-10-09 22:49:17

+0

imagesx и imagesy возвращает ширину/высоту изображения. – 2008-10-10 08:19:03

6

Это можно сделать с использованием библиотеки 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 
11

Большинство людей, использующих 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)); 
?> 

Надеюсь, что это поможет.

5

Довольно поздно, если вы используете библиотеку 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); 
5

Поймите, это старая нить, но я провел некоторое время, ударяя головой о стену на этом сегодня, и подумал, что возьму свое решение здесь для следующего парня.

Этот метод использует AWS SDK for 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); 
0

Я столкнулся с той же проблемой, используя хранилище объектов openstack и библиотеку php-opencloud.

Вот мое решение, которое делает не использовать функцию ob_start и ob_end_clean, но хранить изображение в памяти и в временный файл. The size of the memory and the temp file may be adapted at runtime.

// $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 (from the official documentation of php):

PHP: // память и PHP: // температура для чтения и записи потоков, которые позволяют временно хранить данные в файле типа обертка. Единственное различие между ними заключается в том, что память php: // всегда будет хранить свои данные в памяти, тогда как php: // temp будет использовать временный файл, как только объем данных будет достигнут предопределенного предела (по умолчанию это 2 МБ). Местоположение этого временного файла определяется так же, как функция sys_get_temp_dir().

Предел памяти php: // temp может управляться путем добавления/maxmemory: NN, где NN - это максимальный объем данных для хранения в памяти перед использованием временного файла в байтах.

 Смежные вопросы

  • Нет связанных вопросов^_^