mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-04-27 03:00:12 -04:00
Image previews: smart crop down to 1:2 aspect ratio
Per request from the mobile team, image previews should be cropped down to a 1:2 width-to-height ratio as necessary.
This commit is contained in:
@@ -581,6 +581,7 @@ class LinkJsonTemplate(ThingJsonTemplate):
|
||||
)
|
||||
|
||||
PREVIEW_RESOLUTIONS = (108, 216, 320, 640, 960, 1080)
|
||||
PREVIEW_MAX_RATIO = 2
|
||||
|
||||
def __init__(self):
|
||||
super(LinkJsonTemplate, self).__init__()
|
||||
@@ -650,7 +651,7 @@ class LinkJsonTemplate(ThingJsonTemplate):
|
||||
continue
|
||||
|
||||
url = g.image_resizing_provider.resize_image(
|
||||
preview_object, w, censor_nsfw)
|
||||
preview_object, w, censor_nsfw, self.PREVIEW_MAX_RATIO)
|
||||
h = int(w * source_ratio)
|
||||
preview_resolutions.append({
|
||||
"url": url,
|
||||
|
||||
@@ -24,7 +24,7 @@ class ImageResizingProvider(object):
|
||||
"""Provider for generating resizable image urls.
|
||||
|
||||
"""
|
||||
def resize_image(self, image, width=None, censor_nsfw=False):
|
||||
def resize_image(self, image, width=None, censor_nsfw=False, max_ratio=None):
|
||||
"""Turn a url of an image in storage into one that will produce a
|
||||
resized image.
|
||||
|
||||
@@ -39,6 +39,10 @@ class ImageResizingProvider(object):
|
||||
`censor_nsfw` is a boolean indicating whether the resizer should
|
||||
attempt to censor the image (e.g. by blurring it) due to it being NSFW.
|
||||
|
||||
`max_ratio` is the maximum value of the height of the resultant image
|
||||
divided by the width; if not specified, the aspect ratio will be the
|
||||
same as the source image.
|
||||
|
||||
The return value should be an absolute URL with the `https` scheme if
|
||||
supported, but should also work if accessed with `http`.
|
||||
|
||||
|
||||
@@ -39,12 +39,19 @@ class ImgixImageResizingProvider(ImageResizingProvider):
|
||||
],
|
||||
}
|
||||
|
||||
def resize_image(self, image, width=None, censor_nsfw=False):
|
||||
def resize_image(self, image, width=None, censor_nsfw=False, max_ratio=None):
|
||||
url = UrlParser(image['url'])
|
||||
url.hostname = g.imgix_domain
|
||||
# Let's encourage HTTPS; it's cool, works just fine on HTTP pages, and
|
||||
# will prevent insecure content warnings on HTTPS pages.
|
||||
url.scheme = 'https'
|
||||
|
||||
if max_ratio:
|
||||
url.update_query(fit='crop')
|
||||
# http://www.imgix.com/docs/reference/size#param-crop
|
||||
url.update_query(crop='faces,entropy')
|
||||
url.update_query(arh=max_ratio)
|
||||
|
||||
if width:
|
||||
if width > image['width']:
|
||||
raise NotLargeEnough()
|
||||
|
||||
@@ -28,6 +28,6 @@ class NoOpImageResizingProvider(ImageResizingProvider):
|
||||
Combines well with the filesystem media provider for an entirely local
|
||||
setup.
|
||||
"""
|
||||
def resize_image(self, image, width=None, censor_nsfw=False):
|
||||
def resize_image(self, image, width=None, censor_nsfw=False, max_ratio=None):
|
||||
# The simplest solution: just pass it on through.
|
||||
return image['url']
|
||||
|
||||
@@ -28,7 +28,7 @@ class UnsplashitImageResizingProvider(ImageResizingProvider):
|
||||
Useful if you don't want the external dependencies of imgix, but need
|
||||
correctly-sized images for testing a UI.
|
||||
"""
|
||||
def resize_image(self, image, width=None, censor_nsfw=False):
|
||||
def resize_image(self, image, width=None, censor_nsfw=False, max_ratio=None):
|
||||
if width is None:
|
||||
width = image['width']
|
||||
height = width * 2
|
||||
|
||||
@@ -33,6 +33,9 @@ from r2.lib.providers.image_resizing.imgix import ImgixImageResizingProvider
|
||||
from r2.lib.utils import UrlParser
|
||||
|
||||
|
||||
URLENCODED_COMMA = '%2C'
|
||||
|
||||
|
||||
class TestImgixResizer(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@@ -66,7 +69,21 @@ class TestImgixResizer(unittest.TestCase):
|
||||
url = self.provider.resize_image(image, width)
|
||||
self.assertEqual(url, 'https://example.com/a.jpg?w=%d' % width)
|
||||
|
||||
# TODO: test acceptable aspect ratios per spec!
|
||||
def test_cropping(self):
|
||||
image = dict(url='http://s3.amazonaws.com/a.jpg', width=1200,
|
||||
height=800)
|
||||
max_ratio = 0.5
|
||||
url = self.provider.resize_image(image, max_ratio=max_ratio)
|
||||
crop = URLENCODED_COMMA.join(('faces', 'entropy'))
|
||||
self.assertEqual(url,
|
||||
('https://example.com/a.jpg?fit=crop&crop=%s&arh=%s'
|
||||
% (crop, max_ratio)))
|
||||
|
||||
width = 108
|
||||
url = self.provider.resize_image(image, width, max_ratio=max_ratio)
|
||||
self.assertEqual(url,
|
||||
('https://example.com/a.jpg?fit=crop&crop=%s&arh=%s&w=%s'
|
||||
% (crop, max_ratio, width)))
|
||||
|
||||
def test_sign_url(self):
|
||||
u = UrlParser('http://examples.imgix.net/frog.jpg?w=100')
|
||||
|
||||
Reference in New Issue
Block a user