-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
サムネイル画像をOGP画像用のサイズに合わせる #6483
Open
wata00913
wants to merge
12
commits into
main
Choose a base branch
from
feature/fit-to-size-for-ogp-thumbnails
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
サムネイル画像をOGP画像用のサイズに合わせる #6483
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
0d50739
アップロード画像をOGP用に加工する処理とテストコードを作成
wata00913 7a27887
URL取得時に画像変形処理が不要になったので、変形処理と定数を削除
wata00913 2b814f0
画像が未アップロードの場合を考慮
wata00913 144445c
画像アップロードの機能追加に伴い説明文を修正
wata00913 bbcea0d
テストデータを修正
wata00913 cad5c22
メソッド名の修正
wata00913 4adc374
テストコードを修正
wata00913 ff320ad
テストコード内で定義した定数か、モジュールで定義した定数か判断しづらいのでハードコーディングに戻した
wata00913 a570cdc
モジュールからクラスへの変更とモジュールを削除しクラスにまとめた
wata00913 8febb61
名前空間のネストが深いので浅くするのとクラス名を変更
wata00913 9966398
同じ処理なので共通化
wata00913 68f2ced
クラスの修正とそれに伴うテストの修正
wata00913 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
実装の都合ではなく、オブジェクト指向でのクラス名・メソッド名の設計を考えた時にちょっと意味がわからない感じがします。
ImageResizerの外部(使う)人が必要なのは、
この部分だけだと思います。
外部から
OGP_SIZE
というクラス内部のものを外側から注入する必要があるのもおかしいと思います。実装的に内部を別のクラスにするとしても、現状だと単純にもう一つクラスが必要だから用意した感じで、同じ意味なので、メソッド名も含めて、privateから単純に別のクラスに移動するのではなく、
クラス(名詞)#メソッド(動詞)
という原則を思い出してそれらの組み合わせて設計してみてください。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OGP_SIZE
は、ImageResizer
クラス自身持つのがおかしいこと理解しました。リサイズのサイズ決めをするのは、
ImageResizer
を呼び出すArticle
モデルなのでArticle
にOGP_SIZE
を定義する方針で問題ないでしょうか?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bootcamp/app/models/image_resizer_transformation.rb
Line 3 in 68f2ced
こちらのクラスは、画像をリサイズするのに必要なオプション(
variant
メソッドの引数)を作成する役割を持つため、以下のように設計してみましたがいかがでしょうか?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wata00913 仕様的にどうなってるのかによりそうです。
例えば「サイト全体でOGP画像のサイズはこうしよう」と決めているのであればサイト全体の設定ファイル的なところにサイズがあるのが適切だと思います。
そうではなく、「Article(ブログ記事)のOGP画像のサイズはこうしよう」と決めていて他とサイズが違うという感じであればArticleに定数を持つのがいいと思います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wata00913 いい感じだと思います。
しかし、ImageResizerとImageRezsizeでほとんど重複しているのでクラス名のプリフィックスで表現するより
ImageResizer::OptionBuilder
の方がいいと思います。