imgproxy is a fast and secure standalone server for resizing and converting remote images. The main principles of imgproxy are simplicity, speed, and security. It is a Go application, ready to be installed and used in any Unix environment—also ready to be containerized using Docker.
imgproxy can be used to provide a fast and secure way to replace all the image resizing code of your web application (like calling ImageMagick or GraphicsMagick, or using libraries), while also being able to resize everything on the fly, fast and easy. imgproxy is also indispensable when handling lots of image resizing, especially when images come from a remote source.
imgproxy.rb is a Ruby Gem for imgproxy that is framework-agnostic, but includes proper support for Ruby on Rails' most popular image attachment options.
imgproxy.rb provides easy configuration and URL generation as well as plug&play support for Active Storage and Shrine.
Add this to your Gemfile
:
gem "imgproxy"
or install system-wide:
gem install imgproxy
Next, some basic configuration. We will use a Ruby on Rails application as an example; place the following code to config/initializers/imgproxy.rb
:
# config/initializers/imgproxy.rb
Imgproxy.configure do |config|
# imgproxy endpoint
#
# Full URL to where your imgproxy lives.
config.endpoint = "http://imgproxy.example.com"
# Next, you have to provide your signature key and salt.
# If unsure, check out https://github.com/imgproxy/imgproxy/blob/master/docs/configuration.md first.
# Hex-encoded signature key
config.hex_key = "your_key"
# Hex-encoded signature salt
config.hex_salt = "your_salt"
# Base64 encode all URLs
# config.base64_encode_urls = true
# Always escape plain URLs
# config.always_escape_plain_urls = true
end
imgproxy.rb comes with built-in Active Storage support. To enable it, modify your initializer at config/initializers/imgproxy.rb
:
# config/initializers/imgproxy.rb
Imgproxy.extend_active_storage!
Now, to add imgproxy processing to your image attachments, just use the imgproxy_url
method:
user.avatar.imgproxy_url(width: 250, height: 250)
will give you an URL to your user's avatar, resized to 250x250px on the fly.
If you have configured both your imgproxy server and Active Storage to work with Amazon S3, you may want to use the short s3://...
source URL scheme instead of the long one generated by Rails:
# config/initializers/imgproxy.rb
Imgproxy.extend_active_storage!(use_s3: true)
You can do the same if you are using Google Cloud Storage:
# config/initializers/imgproxy.rb
Imgproxy.extend_active_storage!(use_gcs: true, gcs_bucket: "my_bucket")
Note that you need to explicitly provide GCS bucket name since Active Storage "hides" the GCS config.
You can also use imgproxy.rb's built-in Shrine support. To enable it, modify your initializer at config/initializers/imgproxy.rb
:
# config/initializers/imgproxy.rb
Imgproxy.extend_shrine!
Now you can use imgproxy_url
method of Shrine::UploadedFile
:
user.avatar.imgproxy_url(width: 250, height: 250)
will give you an URL to your user's avatar, resized to 250x250px on the fly.
Note: If you use Shrine::Storage::FileSystem
as storage, uploaded file URLs won't include the hostname, so imgproxy server won't be able to access them. To fix this, use host
option of Imgproxy.extend_shrine!
:
# config/initializers/imgproxy.rb
Imgproxy.extend_shrine!(host: "http://your-host.test")
Alternatively, you can launch your imgproxy server with the IMGPROXY_BASE_URL
setting:
IMGPROXY_BASE_URL="http://your-host.test" imgproxy
If you have configured both your imgproxy server and Shrine to work with Amazon S3, you may want to use the short s3://...
source URL scheme instead of the long one generated by Rails:
Imgproxy.extend_shrine!(use_s3: true)
If you use another gem for your attachment operations, you like to keep things minimal or Rails-free, or if you want to generate imgproxy URLs for pictures that did not originate from your application, you can use the Imgproxy.url_for
method:
Imgproxy.url_for(
"http://images.example.com/images/image.jpg",
width: 500,
height: 400,
resizing_type: :fill,
sharpen: 0.5
)
# => http://imgproxy.example.com/2tjGMpWqjO/rs:fill:500:400/sh:0.5/plain/http://images.example.com/images/image.jpg
You can reuse processing options by using Imgproxy::Builder
:
builder = Imgproxy::Builder.new(
width: 500,
height: 400,
resizing_type: :fill,
sharpen: 0.5
)
builder.url_for("http://images.example.com/images/image1.jpg")
builder.url_for("http://images.example.com/images/image2.jpg")
resizing_type
— defines how imgproxy will resize the image. See URL format guide for available values.width
— defines the width of the resulting image.height
— defines the height of the resulting image.dpr
— when set, imgproxy will multiply the image dimensions according to this factor for HiDPI (Retina) devices.enlarge
— when true, imgproxy will enlarge the image if it is smaller than the given size.extend
— when true, imgproxy will extend the image if the resizing result is smaller than the given size.extend_gravity
,extend_gravity_x
,extend_gravity_y
— define the gravity of the extend. These options accept the same values asgravity
,gravity_x
andgravity_y
(see below).gravity
— defines gravity that will be used when imgproxy needs to cut some parts of the image. See URL format guide for available values.gravity_x
,gravity_y
— specify gravity offset by X and Y axes. Whenfp
gravity is used, these are floating point numbers between 0 and 1 that define the coordinates of the center of the resulting image.crop_width
,crop_height
— define the size of an area of the image to be processed (crop before resize).crop_gravity
,crop_gravity_x
,crop_gravity_y
- define the gravity of the crop. These options accept the same values asgravity
,gravity_x
andgravity_y
(see above).padding
- defines padding size in css manner (you can use array here). See URL guide for more info.trim_threshold
- when set, imgproxy removes surrounding background.trim_color
,trim_equal_hor
,trim_equal_ver
- additional trim options described in the URL guide.quality
— defines the quality of the resulting image, percentage.max_bytes
— when set, imgproxy automatically degrades the quality of the image until the image is under the specified amount of bytes.background
— when set, imgproxy will fill the resulting image background with the specified color. Can be a hex-color string or an array of red, green and blue values (0-255).brightness
— when set, imgproxy will adjust brightness of the resulting image. Supported only by imgproxy pro.contrast
— when set, imgproxy will adjust contrast of the resulting image. Supported only by imgproxy pro.saturation
— when set, imgproxy will adjust saturation of the resulting image. Supported only by imgproxy pro.blur
— when set, imgproxy will apply the gaussian blur filter to the resulting image. Value is the size of a mask imgproxy will use.sharpen
— when set, imgproxy will apply the sharpen filter to the resulting image. Value is the size of a mask imgproxy will use.pixelate
— when set, imgproxy will apply the pixelate filter to the resulting image. Value is the size of a pixel. Supported only by imgproxy pro.watermark_opacity
— when set, imgproxy will put a watermark on the resulting image. See watermars guide for more info.watermark_position
,watermark_x_offset
,watermark_y_offset
,watermark_scale
— additional watermark options described in the watermars guide.watermark_url
— when set, imgproxy will use the image from the specified URL as a watermark. Supported only by imgproxy pro.style
— when set, imgproxy will prepend<style>
node with provided content to the<svg>
node of source SVG image. Supported only by imgproxy pro.preset
— array of names of presets that will be used by imgproxy. See presets guide for more info.cachebuster
— defines cache buster that doesn't affect image processing but it's changing allows to bypass CDN, proxy server and browser cache.format
— specifies the resulting image format (jpg
,png
,webp
).base64_encode_url
— encode the URL as a base64 string.escape_plain_url
— force escape plain URL.use_short_options
— per-call redefinition ofuse_short_options
config.
See imgproxy URL format guide for more info.
By default, Imgproxy.url_for
accepts only String
and URI
as the source URL, but you can extend that behavior by using URL adapters.
URL adapter is a simple class that implements applicable?
and url
methods. See the example below:
class MyItemAdapter
# `applicable?` checks if the adapter can extract
# source URL from the provided object
def applicable?(item)
item.is_a? MyItem
end
# `url` extracts source URL from the provided object
def url(item)
item.image_url
end
end
# ...
Imgproxy.configure do |config|
config.url_adapters.add MyItemAdapter.new
end
Note: Imgproxy
will use the first applicable URL adapter. If you need to add your adapter to the beginning of the list, use the prepend
method instead of add
.
Note: imgproxy.rb provides built-inadapters for Active Storage and Shrine that are automatically added by Imgproxy.extend_active_storage!
and Imgproxy.extend_shrine!
.
By default, the imgproxy server uses a full-length signature (32 bytes), but you can set signature length with IMGPROXY_SIGNATURE_SIZE
environment variable. If you have configured your imgproxy server to use truncated signatures, you need to configure the gem too:
# config/initializers/imgproxy.rb
Imgproxy.configure do |config|
config.signature_size = 5
end
By default, imgproxy gem uses short processing options names (rs
for resize
, g
for gravity
, etc), but it can be configured to use full names:
# config/initializers/imgproxy.rb
Imgproxy.configure do |config|
config.use_short_options = false
end
Bug reports and pull requests are welcome on GitHub at https://github.com/imgproxy/imgproxy.rb.
If you are having any problems with image processing of imgproxy itself, be sure to visit https://github.com/imgproxy/imgproxy first and check out the docs at https://github.com/imgproxy/imgproxy/blob/master/docs/.
The gem is available as open source under the terms of the MIT License.
To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.