Просмотр исходного кода

Resize images by area instead of fixed dimensions (#8083)

To improve the way super tall or super ride images are treated, the
numbers remain the same, 1280x1280 and 400x400, but if an image
is less in one dimension than the other, the other can become larger

Thanks to @WAHa_06x36@mastodon.social for the tip
master
Eugen Rochko 5 лет назад
committed by GitHub
Родитель
Сommit
0fb0037ca7
Не найден GPG ключ соответствующий данной подписи Идентификатор GPG ключа: 4AEE18F83AFDEB23
4 измененных файлов: 20 добавлений и 23 удалений
  1. +4
    -14
      app/javascript/mastodon/utils/resize_image.js
  2. +3
    -3
      app/models/media_attachment.rb
  3. +10
    -3
      lib/paperclip/lazy_thumbnail.rb
  4. +3
    -3
      spec/models/media_attachment_spec.rb

+ 4
- 14
app/javascript/mastodon/utils/resize_image.js Просмотреть файл

@@ -1,6 +1,6 @@
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) {
@@ -73,18 +73,8 @@ const processImage = (img, { width, height, orientation, type = 'image/png' }) =
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, {
@@ -104,7 +94,7 @@ export default inputFile => new Promise((resolve, reject) => {
}

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;
}


+ 3
- 3
app/models/media_attachment.rb Просмотреть файл

@@ -32,12 +32,12 @@ class MediaAttachment < ApplicationRecord

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
@@ -152,7 +152,7 @@ class MediaAttachment < ApplicationRecord
elsif VIDEO_MIME_TYPES.include? f.file_content_type
[:video_transcoder]
else
[:thumbnail]
[:lazy_thumbnail]
end
end
end


+ 10
- 3
lib/paperclip/lazy_thumbnail.rb Просмотреть файл

@@ -5,8 +5,14 @@ module Paperclip
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
@@ -18,7 +24,8 @@ module Paperclip
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?


+ 3
- 3
spec/models/media_attachment_spec.rb Просмотреть файл

@@ -129,9 +129,9 @@ RSpec.describe MediaAttachment, type: :model do
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



Загрузка…
Отмена
Сохранить