Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load images directly from S3 bucket or using a resource #70

Closed
bensquire opened this issue May 31, 2018 · 12 comments
Closed

Load images directly from S3 bucket or using a resource #70

bensquire opened this issue May 31, 2018 · 12 comments

Comments

@bensquire
Copy link

Not sure if this is possible, but could php-vips load data directly from an S3 bucket? Currently we're having to load the image into a string and then pass that into php-vips. For example:

$buffer = file_get_contents("s3://$bucket/$filename");

if ($buffer === false) {
    throw new NotFoundException('Unable to open file.');
}

$im = \Jcupitt\Vips\Image::newFromBuffer($buffer);
$rotated = $im->rot('d' . $rotation);
return $rotated->writeToBuffer('.' . $desiredExtension);

but this involves loading what could potentially be a 15MB file directly into memory before it can be processed.

Using:

$im = \Jcupitt\Vips\Image::newFromFile("s3://$bucket/$filename");

results in an error:

VipsForeignLoad: file "s3://foo/bar.jpg" not found

even though we've registered our S3Connection within a stream wrapper. I also tried to load the image using a resource, e.g:

$stream = fopen("s3://$bucket/$filename", 'r');

but get the error:

Argument 1 passed to Jcupitt\Vips\Image::newFromBuffer() must be of the type string, resource given

so that scuppered that idea as well.

Thanks in advance for the help!

@jcupitt
Copy link
Member

jcupitt commented May 31, 2018

Hello @bensquire,

No, you have to go via a string. This is oe of those features that's been talked about a lot, but has never quite happened, for various reasons. Maybe in the next version.

Some background:

lovell/sharp#30

@bensquire
Copy link
Author

@jcupitt Thanks for the prompt response and additional information.

I'll hope it does make it into the next version as we're using php-vips to do image manipulation on GET requests, using resources I hope would improve speed/performance etc.

Fingers crossed and thanks for the hard work!

@jcupitt
Copy link
Member

jcupitt commented Jun 1, 2018

It probably wouln't make a huge difference since S3 will supply that 15mb in only a few ms.

Speedup checklist:

  • use thumbnail for image resizing, not resize
  • use access="sequential" when you can
  • if you are doing pixel arithmetic, keep the format as small as you can by casting results back down
  • add cache nodes for results that will be reused a lot

@bensquire
Copy link
Author

Thanks @jcupitt

I'm looking to use the thumbnail method as suggested. I can see how I can set width & height, but how can set whether I want it to crop or not? I noticed libvips has smart crop, but that wasn't accepted as an option?

I don't think point 2 and 3 apply to us. But we have point 4 already.

Thanks!
Ben

@jcupitt
Copy link
Member

jcupitt commented Jun 1, 2018

Could you explain what kind of cropping you need to do?

@bensquire
Copy link
Author

So for example, we have an image. It's 1024x768.

We allow users to specify a new image size for thumbs with an optional "fit" flag. So if for example, I specify a new image size of 800x300, the difference between fit and non-fit, would be that one would equally trim the edges, the other would just force the content into the new image size...

Actually as I play with the thumbnail method, I see that its main concern is the image width...

@jcupitt
Copy link
Member

jcupitt commented Jun 1, 2018

Ah OK. Just set crop to centre and it should do what you want:

$ vips thumbnail image.jpg x.jpg 800 --height 300 --crop centre

In PHP (untested):

$thumb = Vips\Image::thumbnail($buffer, 800, ["height" => 300, "crop" => "centre"]);

@jcupitt
Copy link
Member

jcupitt commented Jun 1, 2018

... that will crop the top and bottom equally. To force an aspect ratio change, use "size" => "force" rather than crop.

@bensquire
Copy link
Author

@jcupitt That is exactly what I was looking for, thank-you. How can I derive these sort of options for myself?

@jcupitt
Copy link
Member

jcupitt commented Jun 1, 2018

You can use the vips command-line tool to get a summary:

$ vips thumbnail_buffer
generate thumbnail from buffer
usage:
   thumbnail_buffer buffer out width [--option-name option-value ...]
where:
   buffer       - Buffer to load from, input VipsBlob
   out          - Output image, output VipsImage
   width        - Size to this width, input gint
			default: 1
			min: 1, max: 10000000
optional arguments:
   height       - Size to this height, input gint
			default: 1
			min: 1, max: 10000000
   size         - Only upsize, only downsize, or both, input VipsSize
			default: both
			allowed: both, up, down, force
   auto-rotate  - Use orientation tags to rotate image upright, input gboolean
			default: true
   crop         - Reduce to fill target rectangle, then crop, input VipsInteresting
			default: none
			allowed: none, centre, entropy, attention
   linear       - Reduce in linear light, input gboolean
			default: false
   import-profile - Fallback import profile, input gchararray
   export-profile - Fallback export profile, input gchararray
   intent       - Rendering intent, input VipsIntent
			default: relative
			allowed: perceptual, relative, saturation, absolute
operation flags: nocache 

Or the C docs have the details:

http://jcupitt.github.io/libvips/API/current/libvips-resample.html#vips-thumbnail

Obviously that's for C, but it and the PHP interface are just thin layers over the underlying object model, so it should be easy to see how to translate the options into PHP.

It'd be nice if the PHP docs listed all the options, but sadly php-doc does not seem to allow optional arguments to magic methods.

@bensquire
Copy link
Author

Thanks @jcupitt!

@jcupitt
Copy link
Member

jcupitt commented Oct 12, 2019

PR to add true streaming, so you could (eg.) open an S3 bucket directly:

libvips/libvips#1443

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants