import EXIF from 'exif-js';
-const MAX_IMAGE_DIMENSION = 1280;
+const MAX_IMAGE_PIXELS = 1638400; // 1280x1280px
const getImageUrl = inputFile => new Promise((resolve, reject) => {
if (window.URL && URL.createObjectURL) {
const resizeImage = (img, type = 'image/png') => new Promise((resolve, reject) => {
const { width, height } = img;
- let newWidth, newHeight;
-
- if (width > height) {
- newHeight = height * MAX_IMAGE_DIMENSION / width;
- newWidth = MAX_IMAGE_DIMENSION;
- } else if (height > width) {
- newWidth = width * MAX_IMAGE_DIMENSION / height;
- newHeight = MAX_IMAGE_DIMENSION;
- } else {
- newWidth = MAX_IMAGE_DIMENSION;
- newHeight = MAX_IMAGE_DIMENSION;
- }
+ const newWidth = Math.round(Math.sqrt(MAX_IMAGE_PIXELS * (width / height)));
+ const newHeight = Math.round(Math.sqrt(MAX_IMAGE_PIXELS * (height / width)));
getOrientation(img, type)
.then(orientation => processImage(img, {
}
loadImage(inputFile).then(img => {
- if (img.width < MAX_IMAGE_DIMENSION && img.height < MAX_IMAGE_DIMENSION) {
+ if (img.width * img.height < MAX_IMAGE_PIXELS) {
resolve(inputFile);
return;
}
IMAGE_STYLES = {
original: {
- geometry: '1280x1280>',
+ pixels: 1_638_400, # 1280x1280px
file_geometry_parser: FastGeometryParser,
},
small: {
- geometry: '400x400>',
+ pixels: 160_000, # 400x400px
file_geometry_parser: FastGeometryParser,
},
}.freeze
elsif VIDEO_MIME_TYPES.include? f.file_content_type
[:video_transcoder]
else
- [:thumbnail]
+ [:lazy_thumbnail]
end
end
end
def make
return File.open(@file.path) unless needs_convert?
- min_side = [@current_geometry.width, @current_geometry.height].min
- options[:geometry] = "#{min_side.to_i}x#{min_side.to_i}#" if @target_geometry.square? && min_side < @target_geometry.width
+ if options[:geometry]
+ min_side = [@current_geometry.width, @current_geometry.height].min.to_i
+ options[:geometry] = "#{min_side}x#{min_side}#" if @target_geometry.square? && min_side < @target_geometry.width
+ elsif options[:pixels]
+ width = Math.sqrt(options[:pixels] * (@current_geometry.width.to_f / @current_geometry.height.to_f)).round.to_i
+ height = Math.sqrt(options[:pixels] * (@current_geometry.height.to_f / @current_geometry.width.to_f)).round.to_i
+ options[:geometry] = "#{width}x#{height}>"
+ end
Paperclip::Thumbnail.make(file, options, attachment)
end
end
def needs_different_geometry?
- !@target_geometry.nil? && @current_geometry.width != @target_geometry.width && @current_geometry.height != @target_geometry.height
+ (options[:geometry] && @current_geometry.width != @target_geometry.width && @current_geometry.height != @target_geometry.height) ||
+ (options[:pixels] && @current_geometry.width * @current_geometry.height > options[:pixels])
end
def needs_different_format?
expect(media.file.meta["original"]["width"]).to eq 600
expect(media.file.meta["original"]["height"]).to eq 400
expect(media.file.meta["original"]["aspect"]).to eq 1.5
- expect(media.file.meta["small"]["width"]).to eq 400
- expect(media.file.meta["small"]["height"]).to eq 267
- expect(media.file.meta["small"]["aspect"]).to eq 400.0/267
+ expect(media.file.meta["small"]["width"]).to eq 490
+ expect(media.file.meta["small"]["height"]).to eq 327
+ expect(media.file.meta["small"]["aspect"]).to eq 490.0/327
end
end