Module: AttachmentSaver::Processors::GdkPixbuf

Includes:
Image
Defined in:
lib/processors/gdk_pixbuf.rb

Defined Under Namespace

Modules: Operations

Constant Summary

Constants included from Image

Image::DEFAULT_VALID_IMAGE_TYPES

Instance Method Summary collapse

Methods included from Image

#before_validate_attachment, #build_derived, #derived_image?, from_geometry_string, #image?, #process_attachment, #process_attachment?, #update_derived, #valid_image_type, #want_format?

Instance Method Details

#examine_imageObject



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/processors/gdk_pixbuf.rb', line 29

def examine_image
  fileinfo, width, height = ::GdkPixbuf::Pixbuf.get_file_info(uploaded_file_path)
  raise GdkPixbufProcessorError, "Not an image" if fileinfo.nil?

  self.width = width if respond_to?(:width)
  self.height = height if respond_to?(:height)
  self.content_type = fileinfo.mime_types.first unless self.class.attachment_options[:keep_content_type] || fileinfo.mime_types.empty?
  self.file_extension = normalize_extension(fileinfo.extensions.first) unless self.class.attachment_options[:keep_file_extension] || fileinfo.extensions.empty?
rescue AttachmentSaverError
  raise
rescue Exception => ex
  raise GdkPixbufProcessorError, "#{ex.class}: #{ex.message}", ex.backtrace
end

#normalize_extension(extension) ⇒ Object



43
44
45
46
47
48
# File 'lib/processors/gdk_pixbuf.rb', line 43

def normalize_extension(extension)
  case extension
  when 'jpeg' then 'jpg'
  else extension
  end
end

#process_image(original_image, derived_format_name, resize_format) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/processors/gdk_pixbuf.rb', line 50

def process_image(original_image, derived_format_name, resize_format)
  resize_format = Image.from_geometry_string(resize_format) if resize_format.is_a?(String)

  result = original_image.send(*resize_format) do |derived_image|
    return nil unless want_format?(derived_format_name, derived_image.width, derived_image.height)

    # both original_filename and content_type must be defined for parents when using image processing
    # - but apps can just define them using attr_accessor if they don't want them persisted to db
    derived_content_type = content_type
    derived_extension = derived_image.file_extension

    # we leverage tempfiles as discussed in the uploaded_file method
    temp = ExtendedTempfile.new("asgtemp", tempfile_directory, derived_extension)
    temp.binmode
    temp.close
    derived_image.save(temp.path, original_image.format)
    temp.open # we close & reopen so we see the file the processor wrote to, even if it created a new file rather than writing into our tempfile

    { :format_name => derived_format_name.to_s,
      :width => derived_image.width,
      :height => derived_image.height,
      :content_type => derived_content_type,
      :file_extension => derived_extension,
      :uploaded_data => temp }
  end

  result
end

#with_image(filename, &block) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/processors/gdk_pixbuf.rb', line 12

def with_image(filename, &block)
  # we use GdkPixbuf::PixbufLoader rather than GdkPixbuf::Pixbuf.new(filename) so that we can learn the format of the
  # image, which process_image wants to know so that it can save the derived images in the same format.
  loader = ::GdkPixbuf::PixbufLoader.new
  File.open(filename, "rb") do |file|
    while buf = file.read(65536)
      loader.write(buf)
    end
  end
  loader.close
  image = loader.pixbuf
  image.extend(Operations)
  image.format = loader.format.name
  image.file_extension = normalize_extension(loader.format.extensions.first)
  block.call(image)
end