I have an Attachment model, which is using Paperclip to handle uploaded files. The file can be anything an image, a txt, doc, pdf, rar, zip, tar etc.
I want to create thumbnails only if the file uploaded is an image.
How to create thumbnails in Paperclip conditionally based upon file content_type
This is a nice solution:
before_post_process :image?
def image?
!(data_content_type =~ /^image.*/).nil?
end
You can also use the image? method in your views to either render an image_tag, or something else...
Related
I am working on a project and I want to show two links to download same file but with different extensions, first link download the file with actual extension and another link download the file with changed extension. Like I have a 1.txt file first link is to download 1.txt file and I want another link to download 1.docx file using ruby on rails.
First link works properly which downloads actual file and I have created a method for second link.
def downloaddocxfile
require 'fileutils'
Dir.glob(params[:file]).each do |f|
if File.extname(f) != '.docx'
FileUtils.cp f, "#{File.dirname(f)}/#{File.basename(f,'.*')}.docx"
send_file "#{File.dirname(f)}/#{File.basename(f,'.*')}.docx"
# system("rm -rf #{File.dirname(f)}/#{File.basename(f,'.*')}.docx")
else
send_file "#{params[:file]}"
end
end
end
This method create a copy of original file and change the extension to .docx.
I don't want to show two files with different extensions in the list of files. So I want to remove that file which is created with .docx extension once it is downloaded. So, How can I do that?
send_file allows you to specify a filename via the :filename option.
Assuming that there's a file x.foo on your server, then:
send_file('x.foo', filename: 'y.bar')
would send the file x.foo under the name y.bar to the browser.
It's up to the browser to use the suggested name, but most browsers will save the file as y.bar.
In my Rails app, I have a form that allows users to upload images. My app is supposed to resize the images with the following controller method. (POST to this method, params[:file] contains the ActionDispatch::Http::UploadedFile that was uploaded:
def resize_and_store
file = params[:file]
# resize image
Magick::Image.read(file.tempfile).first
newimg = image.resize(100,100)
#etc... Store newimg
end
I get the following error, on the line that says Image.read:
Magick::ImageMagickError (no decode delegate for this image format `0xb9f6052c>' # error/constitute.c/ReadImage/544):
Testing this with an uploaded PNG file, it seems RMagick doesn't pick up that the temporary file is a PNG file. The code above does work if I read a locally stored PNG file, so it can't be that I'm missing the PNG decoder. How can I fix this and why does this happen?
You can do from_blob on a ActionDispatch::Http::UploadedFile param (this is how a file comes in):
images = Magick::Image.from_blob(params[:file].read)
Storing the file temporarily will solve the problem:
open('temp.png', 'wb') do |file|
file << uploaded.tempfile.read
end
images=Magick::Image.read('temp.png')
Probably wise to check input size as well.
Alternatively, parse the image from a blob.
Using the answer by #joost (or similar approach) really helped to point me in the right direction but it didn't work on the second attempt with the same temp file - my use case was creating multiple image types from the tempfile source. This is what I've used, wrapping in a File.open block so we don't leak the file descriptor:
File.open(tempfile, "rb") do |f|
img = Magick::Image::from_blob(f.read).first
resized = img.resize_to_fit(w, h)
resized.write(dest)
resized.destroy!
img.destroy!
end
Maybe there's something wrong with the form? You can consult with Rails Guide here:
Rails Guides: Uploading Files
I think that you may have multipart: true missing in your form declaration.
Also, I would strongly advise to use Carrierwave to handle file uploads. Among several things, it will help you to organize your file transformations (putting logic out of the controllers). Here's a railscast about it:
RailsCasts: CarrierWave File Uploads.
Good luck!
I would like to add a dynamically generated text. Is there a way to watermark an existing PDF in Ruby?
This will do it:
PDF::Reader to count the number of pages in the file.
Prawn to create a new PDF document using each page of the input pdf as a template.
require 'prawn'
require 'pdf-reader'
input_filename = 'input.pdf'
output_filename = 'output.pdf'
page_count = PDF::Reader.new(input_filename).page_count
Prawn::Document.generate(output_filename, :skip_page_creation => true) do |pdf|
page_count.times do |num|
pdf.start_new_page(:template => input_filename, :template_page => num+1)
pdf.text('WATERMARK')
end
end
However, in my testing the output file size was huge with the latest Gem version of Prawn (0.12), but after pointing my Gemfile at the master branch on github, all worked fine.
Another option is to use PDFTK. It can be used to add a watermark and create a new PDF. Maybe prawn will do the same thing with it's templating.
pdftk in.pdf background arecibo.pdf output wmark1.pdf
Some more info: http://rhodesmill.org/brandon/2009/pdf-watermark-margins/
There is a ruby wrapper gem called active_pdftk which supports backgrounding, so you don't have to do the shell commands yourself.
Prawn doesn't support templates anymore...
Try the combine_pdf gem.
You can combine, watermark, page-number and add simple text to existing PDF files (including the creation of a simple table of contents without PDF links).
It's a very simple and basic PDF library, written in pure Ruby with no dependencies.
This example can fit your situation (it's from the readme file):
# load the logo as a pdf page
company_logo = CombinePDF.load("company_logo.pdf").pages[0]
# load the content file
pdf = CombinePDF.load "content_file.pdf"
# inject the logo to each page in the content
pdf.pages.each {|page| page << company_logo}
# save to a new file, with the logo.
pdf.save "content_with_logo.pdf"
Check out Prawn(http://github.com/sandal/prawn) for just ruby and Prawnto(http://github.com/thorny-sun/prawnto) for Ruby on Rails.
You are probably going to want to either use the image embedding functionality or the background image functionality.
Here's an example of using a background image http://cracklabs.com/prawnto/code/prawn_demos/source/general/background
Use Ruport.
1st result for Googling ruby pdf watermark.
I'm using paperclip to upload a pdf. Once the file is uploaded I need to split every page into a png. This is the command I think I need to use
convert -size 640x300 fileName.pdf slide.png
Now if I run that command from terminal it works fine, but I need a way of getting each slides name so I can add it into a model.
What's the best way to achieve this?
You should be able to have Paperclip do this conversion for you at the time of the upload, like this:
has_attached_file :pdfupload, :styles => { :pinged => ["640x300", :png] }
Then you can show the PNG version like so:
<%= image_tag #mymodel.pdfupload.url(:pinged) %>
(Obviously the name of the model and file will need to be changed to match yours.)
use `command` to execute system commads
(`-quotes)
`convert -size 640x300 fileName.pdf slide.png`
When I using "file_field" to upload a file:
The file name can be obtained in the controller:
params[:upload]['datafile'].original_filename
but how can I obtain the size and type of the file?
Use the content_type and size helper functions
params[:upload]['datafile'].content_type
Not sure why you'd want to do that in a controller, but any validation needs to be moved inside your model. Also try using a plugin like Paperclip or SWFUpload to handle uploads, for greater flexibility.
Try these links for a examples Paperclip, Attachment_fu, SWFUpload