I am trying to create a montage file composed of various thumbnails uploaded (privately) to S3 with Shrine.
The code for this action resides in a Sidekiq worker (at Heroku) which should send an email with the above processed image as an email attachment. (Then just dumps the image)
Here is my attempt:
images = []
@user.photos.first(25).each do |photo|
images << File.read(photo.image[:thumb].url)
end
processed_image = MiniMagick::Tool::Montage.new do |image|
images.each {|i| image << i}
image.tile "5x5"
image << "output.jpg"
end
attachments.inline['images.jpg'] = processed_image
Though I get error :
2019-11-04T18:17:59.638Z 30695 TID-ot0uksdbv WARN: Errno::ENOENT: No such file or directory @ rb_sysopen - https://mysite.s3.eu-west-1.amazonaws.com/photo/thumb/5cb924406fa8944e5279a15b46f250f6.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIJJCEGJCEVP2A%2F20191104%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20191104T181759Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=38706b7526fd0a8095a2f387521063d4d8901c4523696ff7e1f60ae2d
It seems it can't open the thumb at S3 (I have obfuscated the link above, but when pasted in browser it returns the image correctly)
I have tried to pass the link directly in the block :
images << photo.image[:thumb].url
But this time it seems I get errors from MiniMagick
montage-im6.q16: not authorized
HTTPS' @ error/delegate.c/InvokeDelegate/1717. montage-im6.q16: unable to open file
': No such file or directory @ error/constitute.c/ReadImage/544. montage-im6.q16: not authorizedHTTPS' @ error/delegate.c/InvokeDelegate/1717. montage-im6.q16: unable to open file
': Operation not permitted @ error/constitute.c/ReadImage/544. montage-im6.q16: not authorizedHTTPS' @ error/delegate.c/InvokeDelegate/1717. montage-im6.q16: unable to open file
': Operation not permitted @ error/constitute.c/ReadImage/544. montage-im6.q16: not authorizedHTTPS' @ error/delegate.c/InvokeDelegate/1717. montage-im6.q16: unable to open file
': Operation not permitted @ error/constitute.c/ReadImage/544. montage-im6.q16: not authorized `HTTPS' @ error/delegate.c/InvokeDelegate/1717.
Not very sure how to handle this..
You need to download the files to disk before processing, and use the local paths in your montage command. Also, you'll need to read the result file from the output path, as the montage command returns only stdout.
Together it could look something like this:
# download input images to disk
input_images = @user.photos.first(25)
.map { |photo| photo.image[:thumb] }
.map(&:download)
# create temporary file for output image
processed_image = Tempfile.new ["montage", ".jpg"], binmode: true
MiniMagick::Tool::Montage.new do |montage|
montage.merge! input_images.map(&:path)
montage.tile "5x5"
montage << processed_image.path
end
attachments.inline['images.jpg'] = File.binread(processed_image.path)
# close and delete temporary files
[*input_images, processed_image].each(&:close!)