Class: Pdf::Utility::ImageCreator
- Inherits:
-
Object
- Object
- Pdf::Utility::ImageCreator
- Defined in:
- app/services/pdf/utility/image_creator.rb
Overview
Service object: image creator.
Instance Method Summary collapse
Instance Method Details
#call(pdf_path:, name:, base_name: nil) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'app/services/pdf/utility/image_creator.rb', line 5 def call(pdf_path:, name:, base_name: nil) image = nil base_name ||= name.downcase.parameterize.tr('_', '-') begin # Normalize PDFs accidentally saved with raw HTTP response headers. Pdf::Utility::FileNormalizer.call(pdf_path) # Rails blocks libvips' in-process PDF loader for untrusted uploads. # Rasterize page 1 in the bounded pdftoppm subprocess, which rejects # oversized output before returning, then lazily load its trusted PNG. rasterized_page = Pdf::Utility::CliRasterizer.render_page(pdf_path, page: 0, dpi: 400) cover = Vips::Image.new_from_file(rasterized_page.path, access: :sequential) # Write it to a jpg temp file file = Tempfile.new([base_name, '.jpeg']) file_path = file.path cover.write_to_file(file_path) file&.flush file&.fsync # Now we will open the file just to make sure vips_image = Vips::Image.new_from_file(file_path) # Test that the vips_image is sound if vips_image.width&.positive? && vips_image.height.positive? new_filename = "#{base_name}-#{SecureRandom.base58(6).downcase}" image = Image.create!(new_filename:, title: "Cover for #{name}".first(134), new_image: file_path, skip_notify: true, tags: ['pdf-thumbnail']) else logger.error "Could not generate thumbnail for #{name} from #{pdf_path}, file is empty" end rescue StandardError => e ErrorReporting.error(e, { pdf_path:, name:, base_name: }) end image ensure rasterized_page&.close rasterized_page&.unlink file&.close file&.unlink end |