jr-paperclip 8.0.1 → 8.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/NEWS +5 -0
- data/lib/paperclip/thumbnail.rb +18 -15
- data/lib/paperclip/version.rb +1 -1
- data/spec/paperclip/thumbnail_spec.rb +28 -0
- data/spec/support/fixtures/big_image.jpg +0 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 832b95743f1be2588ee95b5739e548c630a0c522f579da2234d083b58d82d708
|
|
4
|
+
data.tar.gz: 0034d60bdc931cb92fcd9a338bb2126419a183a9017344e2b036eb553e01ad8a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e2828741e3347c89141a90baef60b1a9dd96482a29687a2ca146f663477d7e15f8dade773ff4b5f7e5d092c54ebf4fb7ed301baaa9c823286b5dceb6bfd08781
|
|
7
|
+
data.tar.gz: fd6704473b2934cbc999a82d986e144ce10e266b070d67b38802fe73daa07d650dbd5b1e47aeb112caa3bd0f889fd841315b5f740d3158c7341d1a9cafcdbbd0
|
data/NEWS
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
8.0.2 (2026-01-19)
|
|
2
|
+
|
|
3
|
+
* Performance: Optimized image thumbnail processing pipeline to handle EXIF orientation more efficiently when using vips backend.
|
|
4
|
+
* Bugix: Vips backend now uses copy_memory for operations that need random access.
|
|
5
|
+
|
|
1
6
|
8.0.1 (2026-01-19)
|
|
2
7
|
|
|
3
8
|
* Performance: Vips backend now uses sequential access by default for better memory efficiency.
|
data/lib/paperclip/thumbnail.rb
CHANGED
|
@@ -183,6 +183,15 @@ module Paperclip
|
|
|
183
183
|
def build_pipeline(source_path)
|
|
184
184
|
pipeline = image_processing_module.source(source_path)
|
|
185
185
|
|
|
186
|
+
# Auto-orient based on EXIF data
|
|
187
|
+
if auto_orient
|
|
188
|
+
if backend == :vips
|
|
189
|
+
pipeline = pipeline.loader(autorotate: true)
|
|
190
|
+
elsif backend == :image_magick
|
|
191
|
+
pipeline = pipeline.auto_orient
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
186
195
|
# For vips backend, default to sequential access for better memory efficiency.
|
|
187
196
|
# Sequential access streams the image from top to bottom, keeping only a few
|
|
188
197
|
# scanlines in memory. Users can override via source_file_options: { access: :random }
|
|
@@ -217,15 +226,6 @@ module Paperclip
|
|
|
217
226
|
end
|
|
218
227
|
end
|
|
219
228
|
|
|
220
|
-
# Auto-orient based on EXIF data
|
|
221
|
-
if auto_orient
|
|
222
|
-
pipeline = if backend == :vips
|
|
223
|
-
pipeline.autorot
|
|
224
|
-
else
|
|
225
|
-
pipeline.auto_orient
|
|
226
|
-
end
|
|
227
|
-
end
|
|
228
|
-
|
|
229
229
|
# Apply resize operation
|
|
230
230
|
if target_geometry
|
|
231
231
|
pipeline = apply_resize(pipeline)
|
|
@@ -474,13 +474,15 @@ module Paperclip
|
|
|
474
474
|
# Vips rotate via similarity for arbitrary angles
|
|
475
475
|
if value
|
|
476
476
|
angle = value.to_f
|
|
477
|
-
|
|
477
|
+
# Similarity requires random access (or memory copy) for non-trivial angles
|
|
478
|
+
pipeline.custom { |img| img.copy_memory.similarity(angle: angle) }
|
|
478
479
|
else
|
|
479
480
|
pipeline
|
|
480
481
|
end
|
|
481
482
|
when "flip"
|
|
482
483
|
# Vips uses flip with direction
|
|
483
|
-
|
|
484
|
+
# Vertical flip requires random access (needs full image)
|
|
485
|
+
pipeline.custom { |img| img.copy_memory.flipver }
|
|
484
486
|
when "flop"
|
|
485
487
|
pipeline.custom(&:fliphor)
|
|
486
488
|
when "blur", "gaussian_blur", "gaussblur"
|
|
@@ -511,14 +513,15 @@ module Paperclip
|
|
|
511
513
|
when "median"
|
|
512
514
|
value ? pipeline.median(value.to_i) : pipeline
|
|
513
515
|
when "rot90"
|
|
514
|
-
|
|
516
|
+
# Rotations change scanline order, requiring random access
|
|
517
|
+
pipeline.custom { |img| img.copy_memory.rot90 }
|
|
515
518
|
when "rot180"
|
|
516
|
-
pipeline.rot180
|
|
519
|
+
pipeline.custom { |img| img.copy_memory.rot180 }
|
|
517
520
|
when "rot270"
|
|
518
|
-
pipeline.rot270
|
|
521
|
+
pipeline.custom { |img| img.copy_memory.rot270 }
|
|
519
522
|
when "similarity"
|
|
520
523
|
# similarity for arbitrary rotation/scale
|
|
521
|
-
value ? pipeline.custom { |img| img.similarity(angle: value.to_f) } : pipeline
|
|
524
|
+
value ? pipeline.custom { |img| img.copy_memory.similarity(angle: value.to_f) } : pipeline
|
|
522
525
|
# Edge detection filters (no arguments)
|
|
523
526
|
when "canny"
|
|
524
527
|
pipeline.canny
|
data/lib/paperclip/version.rb
CHANGED
|
@@ -830,6 +830,34 @@ describe Paperclip::Thumbnail do
|
|
|
830
830
|
end
|
|
831
831
|
end
|
|
832
832
|
|
|
833
|
+
describe "-rot90" do
|
|
834
|
+
it "rotates the image 90 degrees" do
|
|
835
|
+
result = make_vips_thumb_with_options(@file, "-rot90")
|
|
836
|
+
expect(File.exist?(result.path)).to be true
|
|
837
|
+
|
|
838
|
+
dimensions = `identify -format "%wx%h" "#{result.path}"`.strip
|
|
839
|
+
# Resized to 100x15, then rotated 90 -> 15x100
|
|
840
|
+
expect(dimensions).to eq("15x100")
|
|
841
|
+
end
|
|
842
|
+
end
|
|
843
|
+
|
|
844
|
+
describe "-rot180" do
|
|
845
|
+
it "rotates the image 180 degrees" do
|
|
846
|
+
File.open(fixture_file("big_image.jpg"), "rb") do |file|
|
|
847
|
+
thumb = Paperclip::Thumbnail.new(file, {
|
|
848
|
+
geometry: "2000x2000",
|
|
849
|
+
convert_options: "-rot180",
|
|
850
|
+
backend: :vips,
|
|
851
|
+
}, attachment)
|
|
852
|
+
result = thumb.make
|
|
853
|
+
expect(File.exist?(result.path)).to be true
|
|
854
|
+
|
|
855
|
+
dimensions = `identify -format "%wx%h" "#{result.path}"`.strip
|
|
856
|
+
expect(dimensions).to eq("2000x1581")
|
|
857
|
+
end
|
|
858
|
+
end
|
|
859
|
+
end
|
|
860
|
+
|
|
833
861
|
describe "-flip" do
|
|
834
862
|
it "flips the image vertically" do
|
|
835
863
|
result = make_vips_thumb_with_options(@file, "-flip")
|
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jr-paperclip
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.0.
|
|
4
|
+
version: 8.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jukka Rautanen
|
|
@@ -571,6 +571,7 @@ files:
|
|
|
571
571
|
- spec/support/fixtures/animated.unknown
|
|
572
572
|
- spec/support/fixtures/aws_s3.yml
|
|
573
573
|
- spec/support/fixtures/bad.png
|
|
574
|
+
- spec/support/fixtures/big_image.jpg
|
|
574
575
|
- spec/support/fixtures/empty.html
|
|
575
576
|
- spec/support/fixtures/empty.xlsx
|
|
576
577
|
- spec/support/fixtures/fog.yml
|
|
@@ -712,6 +713,7 @@ test_files:
|
|
|
712
713
|
- spec/support/fixtures/animated.unknown
|
|
713
714
|
- spec/support/fixtures/aws_s3.yml
|
|
714
715
|
- spec/support/fixtures/bad.png
|
|
716
|
+
- spec/support/fixtures/big_image.jpg
|
|
715
717
|
- spec/support/fixtures/empty.html
|
|
716
718
|
- spec/support/fixtures/empty.xlsx
|
|
717
719
|
- spec/support/fixtures/fog.yml
|