Skip to content

Commit

Permalink
クラスの修正とそれに伴うテストの修正
Browse files Browse the repository at this point in the history
  • Loading branch information
wata00913 committed Oct 30, 2023
1 parent 9966398 commit 68f2ced
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 90 deletions.
5 changes: 4 additions & 1 deletion app/controllers/articles_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ def notice_message(article)
end

def fit_to_size_for_ogp
Ogp::ImageProcessor.fit_to_size(@article.thumbnail) if @article.thumbnail.attached?
return unless @article.thumbnail.attached?

image_resizer = ImageResizer.new(@article.thumbnail)
image_resizer.fit_to!(*ImageResizer::OGP_SIZE)
end
end
37 changes: 37 additions & 0 deletions app/models/image_resizer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

class ImageResizer
OGP_SIZE = [1200, 630].freeze

def initialize(attached_one)
@attached_one = attached_one
@transformation = ImageResizerTransformation.new
end

def fit_to!(width, height)
return nil if just_fit_to_size?(width, height)

original_width, original_height = original_size

fitted = @attached_one.variant(**@transformation.fit_to(original_width, original_height, width, height))
.processed
.image.blob

# 変形前の画像関連データの削除にpurge、purge_laterは不要。
# データの削除はattachで担える
@attached_one.attach(fitted)
end

def just_fit_to_size?(width, height)
original_width, original_height = original_size
width == original_width && height == original_height
end

private

def original_size
blob = @attached_one.blob
blob.analyze unless blob.analyzed?
[blob.metadata[:width], blob.metadata[:height]]
end
end
31 changes: 31 additions & 0 deletions app/models/image_resizer_transformation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

class ImageResizerTransformation
def fit_to(original_width, original_height, width, height)
# ハッシュを返すが処理順(リサイズ->切り抜き)にオプションを記述
{}.merge(resize(original_width, original_height, width, height),
center_crop(width, height))
end

# 縦横比を維持しながら、リサイズ後の縦をx、横をyとしたときに
# いずれかの条件を満たすようにリサイズする
# x = widht かつ y >= height
# x >= width かつ y = height
def resize(original_width, original_height, width, height)
ratio_w = width.to_f / original_width
ratio_h = height.to_f / original_height

if ratio_w > ratio_h
{ resize: "#{width}x" }
else
{ resize: "x#{height}" }
end
end

def center_crop(width, height)
{ gravity: :center,
# 仮想キャンバスのメタデータをリセットするために!を末尾につける
# +repageは指定できないため、+repage相当の動作をする!を採用
crop: "#{width}x#{height}+0+0!" }
end
end
54 changes: 0 additions & 54 deletions app/models/ogp/image_processor.rb

This file was deleted.

27 changes: 27 additions & 0 deletions test/models/image_resizer_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

require 'test_helper'

class ImageResizerTest < ActiveSupport::TestCase
test '.fit_to!' do
article = articles(:article4)

ImageResizer.new(article.thumbnail).fit_to!(*ImageResizer::OGP_SIZE)

article.thumbnail.blob.analyze unless article.thumbnail.blob.analyzed?
assert_equal({ width: 1200, height: 630 },
article.thumbnail.blob.metadata.slice(:width, :height).symbolize_keys)
end

test '.just_fit_to_size?' do
article = articles(:article4)

image_resizer = ImageResizer.new(article.thumbnail)
width, height = ImageResizer::OGP_SIZE
image_resizer.fit_to!(width, height)

assert image_resizer.just_fit_to_size?(width, height)
assert_not image_resizer.just_fit_to_size?(width + 1, height)
assert_not image_resizer.just_fit_to_size?(width, height + 1)
end
end
33 changes: 33 additions & 0 deletions test/models/image_resizer_transformation_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require 'test_helper'

class ImageResizerTransformationTest < ActiveSupport::TestCase
setup do
@image_resizer_transformation = ImageResizerTransformation.new
@width = 1200
@height = 630
end

test '.fit_to' do
assert_equal({ resize: "#{@width}x", gravity: :center, crop: "#{@width}x#{@height}+0+0!" },
@image_resizer_transformation.fit_to(500, 500, @width, @height))
end

test '.resize return 1200x when width magnification is grater than height magnification' do
assert_equal({ resize: "#{@width}x" }, @image_resizer_transformation.resize(500, 500, @width, @height))
assert_equal({ resize: "#{@width}x" }, @image_resizer_transformation.resize(500, 630, @width, @height))
assert_equal({ resize: "#{@width}x" }, @image_resizer_transformation.resize(1500, 1500, @width, @height))
end

test '.resize return x630 when height magnification is grater than width magnification' do
assert_equal({ resize: "x#{@height}" }, @image_resizer_transformation.resize(1000, 500, @width, @height))
assert_equal({ resize: "x#{@height}" }, @image_resizer_transformation.resize(1200, 500, @width, @height))
assert_equal({ resize: "x#{@height}" }, @image_resizer_transformation.resize(1500, 700, @width, @height))
end

test '.center_crop' do
assert_equal({ gravity: :center, crop: "#{@width}x#{@height}+0+0!" },
@image_resizer_transformation.center_crop(@width, @height))
end
end
35 changes: 0 additions & 35 deletions test/models/ogp/image_processor_test.rb

This file was deleted.

0 comments on commit 68f2ced

Please sign in to comment.