2008-10-09 31 views
11

Đây là tình huống của tôi - Tôi muốn tạo hình ảnh jpeg đã được định lại kích thước từ hình ảnh do người dùng tải lên và gửi nó tới S3 để lưu trữ, nhưng tôi đang tìm cách tránh viết jpeg đã đổi kích thước đĩa và sau đó tải lại nó cho yêu cầu S3.Tạo hình ảnh mà không lưu trữ dưới dạng tệp cục bộ

Có cách nào để thực hiện điều này hoàn toàn trong bộ nhớ, với dữ liệu hình ảnh JPEG được định dạng, được lưu trong một biến không?

Trả lời

4

Thư viện Imagemagick sẽ cho phép bạn thực hiện điều đó. Có rất nhiều trình bao bọc PHP như this xung quanh nó (thậm chí có example code cho những gì bạn muốn làm trên trang đó;))

-1

Maye bằng cách sử dụng GD library.

Có chức năng sao chép một phần của hình ảnh và thay đổi kích thước hình ảnh đó. Tất nhiên phần có thể là toàn bộ hình ảnh, theo cách đó bạn sẽ chỉ thay đổi kích cỡ nó.

thấy imagecopyresampled

6

Một khi bạn đã có những JPEG trong bộ nhớ (sử dụng ImageMagick, GD, hoặc thư viện đồ họa của bạn lựa chọn), bạn sẽ cần phải tải lên các đối tượng từ bộ nhớ để S3.

Nhiều lớp PHP S3 dường như chỉ tập tin tải lên hỗ trợ, nhưng một trong những tại Undesigned dường như làm những gì chúng tôi sau đây -

// 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); 

Nếu bạn đang sử dụng GD thay vào đó, bạn có thể sử dụng imagecreatefromstring để đọc một hình ảnh từ một luồng, nhưng tôi không chắc liệu bạn có thể lấy kích thước của đối tượng kết quả hay không, theo yêu cầu của s3->inputResource ở trên - getimagesize trả về chiều cao, chiều rộng, v.v. nhưng không phải kích thước của tài nguyên hình ảnh.

+0

Tôi nên làm rõ - Tôi đang sử dụng lớp S3 không được thiết kế. Bạn có biết cách GD làm những gì bạn đã đăng ở trên không? Trước khi tôi chuyển sang cài đặt imagemagick, sẽ rất tuyệt nếu biết tôi hoàn toàn cần. – MPX

+0

GD của tôi hơi sơ sài - tôi biết bạn có thể đọc hình ảnh tương tự như ImageMagick, không chắc chắn về việc nhận kích thước đối tượng - được một thời gian kể từ khi tôi xem tài liệu và không thấy gì ở đó. ImageMagick cũng đáng để cài đặt mặc dù IMO! – ConroyP

+0

imagesx và imagesy trả về chiều rộng/chiều cao của nguồn nạp hình ảnh. –

6

Điều này có thể được thực hiện bằng thư viện GD và bộ đệm đầu ra. Tôi không biết làm thế nào hiệu quả này được so sánh với các phương pháp khác, nhưng nó không yêu cầu tạo ra các tập tin rõ ràng.

//$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

Hầu hết mọi người sử dụng PHP chọn một trong hai ImageMagick hoặc Gd2

Tôi chưa bao giờ sử dụng ImageMagick; phương pháp 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)); 
?> 

Hy vọng điều này sẽ hữu ích.

5

Khá muộn với trò chơi này, nhưng nếu bạn đang sử dụng thư viện S3 được đề cập bởi ConroyP và Imagick bạn nên sử dụng phương thức putObjectString() thay vì putObject() do thực tế getImageBlob trả về một chuỗi. Ví dụ cuối cùng đã làm việc cho tôi:

$headers = array(
    'Content-Type' => 'image/jpeg' 
); 
$s3->putObjectString($im->getImageBlob(), $bucket, $file_name, S3::ACL_PUBLIC_READ, array(), $headers); 

Tôi đã đấu tranh với điều này một chút, hy vọng nó sẽ giúp người khác!

+0

Tôi đã phải vật lộn với điều này trong hơn 3 tháng và thấy một số ánh sáng khi tôi đọc điều này. Tuy nhiên, điều này không làm việc cho tôi. 'getImageBlob' xuất hiện để trả về một chuỗi rỗng trong khi' writeImage' thành đĩa hoạt động. Bất kỳ ý tưởng? – John

+0

Tôi thích thư viện s3 này, nó nhỏ và đơn giản. Tuy nhiên nó không hỗ trợ thư mục s3 như xa như tôi có thể nhìn thấy. – Matt

5

Nhận ra đây là một chủ đề cũ, nhưng tôi đã dành thời gian đập đầu vào bức tường ngày hôm nay, và nghĩ rằng tôi sẽ nắm bắt giải pháp của tôi ở đây cho người tiếp theo.

Phương pháp này sử dụng AWS SDK for PHP 2 và GD để thay đổi kích thước hình ảnh (Bạn cũng có thể dễ dàng sử dụng 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

Điều này hoạt động hoàn hảo, nhờ Bart. Có một số đối tượng phản hồi mà tôi có thể sử dụng để tìm hiểu xem giao dịch có thành công không? – Matt

+0

Mỗi Tài liệu PHP (http://us2.php.net/manual/en/function.fwrite.php), fwrite sẽ trả về false do lỗi. – Bart

0

Tôi gặp phải sự cố tương tự, sử dụng kho đối tượng openstack và thư viện php-opencloud.

Đây là giải pháp của tôi, trong đó không sử dụng chức năng ob_startob_end_clean, nhưng lưu trữ hình ảnh trong bộ nhớ và trong tệp tạm thời. 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' 
]); 

Về php://temp (from the official documentation of php):

php: // bộ nhớ và php: // tạm thời là read-write suối cho phép dữ liệu tạm thời được lưu trữ trong một tập tin giống như vỏ bánh. Sự khác biệt duy nhất giữa hai bộ nhớ là bộ nhớ php: // sẽ luôn lưu trữ dữ liệu trong bộ nhớ, trong khi đó php: // tạm thời sẽ sử dụng một tệp tạm thời khi lượng dữ liệu được lưu trữ đạt đến giới hạn được xác định trước (mặc định là 2 MB). Vị trí của tệp tạm thời này được xác định theo cùng cách với hàm sys_get_temp_dir().

Giới hạn bộ nhớ của php: // temp có thể được điều khiển bằng cách thêm/maxmemory: NN, trong đó NN là lượng dữ liệu tối đa để lưu trong bộ nhớ trước khi sử dụng tệp tạm thời tính theo byte.

Các vấn đề liên quan