Subheader

Lazy Programmer's Blog

Pages

Showing posts with label svg. Show all posts
Showing posts with label svg. Show all posts

Friday, July 22, 2016

Rails Paperclip and SVG files

Paperclip has unpleasant handling of SGV files, so it corrupts SVG XML file, and finally uploaded original file will have just header.

Temporary dirty solution is to replace original SVG file. Lets assume we need to store jpg/png/gif/svg image, which can have thumbnail.

Model
class Image < ActiveRecord::Base
  has_attached_file :file,  styles: { thumb: {processors: [:image_thumb]}}
  validates_attachment_content_type :file,
    content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif", "image/svg+xml"]

  attr_accessor :tmp_stage_file_name
    attr_accessor :tmp_stage_file_ext
    before_post_process :save_staged_file
    after_save :replace_original_file

  def save_staged_file
        if (path = file.staged_path)
            if (file.content_type == 'image/svg+xml')               
                @tmp_stage_file_name = File.join("/tmp", SecureRandom.uuid)
                @tmp_stage_file_ext = File.extname(path)
                FileUtils.cp(path, File.join("/tmp", "#{tmp_stage_file_name}#{tmp_stage_file_ext}"))
            end
        end
    end

    def replace_original_file
        if !file.blank? && !tmp_stage_file_name.blank?
            path = File.join("/tmp", "#{tmp_stage_file_name}#{tmp_stage_file_ext}")
            if File.exist? path
                FileUtils.cp path, file.path
                FileUtils.rm path, force: true
            end
        end
        @tmp_stage_file_name = nil
        @tmp_stage_file_ext = nil
    end
end
Image Processor
lib/paperclip_processors/image_thumb.rb

module Paperclip
    class ImageThumb < Processor
        HEIGHT = 320
        WIDTH = 320
        def initialize file, options = {}, attachment = nil
      super
      @file = file
      @instance = options[:instance]
      @current_format   = File.extname(@file.path)
      @whiny = options[:whiny].nil? ? true : options[:whiny]
      @basename = File.basename(file.path, File.extname(file.path))
            @geometry = options[:geometry]
    end

    def make
      geometry = Paperclip::Geometry.from_file(@file)
      filename = [@basename, @current_format || ''].join
      dst = TempfileFactory.new.generate(filename)

            begin
                cmd = file.content_type != 'image/svg+xml' ?
                    %Q(convert '#{file.path}' -resize '#{WIDTH}x#{HEIGHT}^' -gravity 'center' -crop '#{WIDTH}x#{HEIGHT}+0+0' +repage '#{dst.path}') :
                    %Q(rsvg-convert -a -w #{WIDTH} -h #{HEIGHT} -f svg '#{file.path}' -o '#{dst.path}')
                Paperclip.run(cmd)
            rescue
                raise Paperclip::Error, "There was an error processing the thumbnail for #{@basename}" if @whiny
            end
      dst
    end
    end
end

Monday, July 11, 2016

SVG support for Imagemagick in Ubuntu

Converting SVG to jpeg/png/gif via Imagemagick in command line you can get Unable to find rsvg-convert library exception. This means you have no support for SVG.

Type in your terminal
sudo apt get install rsvg-convert
in order to add support for scalable vector graphics.

In case if rsvg-convert wasn't found in your repositories you can perform
sudo apt get install librsvg2-bin

After that you will be able to perform conversion from SVG to one of the popular image formats