Is it possible to add DataUrl Image in RBPDF? - ruby-on-rails

I am making pdf file from DataUrl Image in ruby on rails.
I have selected RBPDF to produce pdf file in server side.
But in this code I have following error
#pdf.Image(object["src"] , object["left"], object["top"], object["width"], object["height"])
Here object["src"] is DataUrl Image.
RuntimeError (RBPDF error: Missing image file:
data:image/jpeg;base64,/9j/4REORXhp...
Is it impossible to add RBPDF image from DataUrl image?
Adding files dynamically is not effective I think.

You may monkey patch the origin method.
I use the data_uri gem to parse the image data.
require 'data_uri'
require 'rmagick'
module Rbpdf
alias_method :old_getimagesize, :getimagesize
# #param [String] date_url
def getimagesize(date_url)
if date_url.start_with? 'data:'
uri = URI::Data.new date_url
image_from_blob = Magick::Image.from_blob(uri.data)
origin_process_image(image_from_blob[0])
else
old_getimagesize date_url
end
end
# this method is extracted without comments from the origin implementation of getimagesize
def origin_process_image(image)
out = Hash.new
out[0] = image.columns
out[1] = image.rows
case image.mime_type
when "image/gif"
out[2] = "GIF"
when "image/jpeg"
out[2] = "JPEG"
when "image/png"
out[2] = "PNG"
when " image/vnd.wap.wbmp"
out[2] = "WBMP"
when "image/x-xpixmap"
out[2] = "XPM"
end
out[3] = "height=\"#{image.rows}\" width=\"#{image.columns}\""
out['mime'] = image.mime_type
case image.colorspace.to_s.downcase
when 'cmykcolorspace'
out['channels'] = 4
when 'rgbcolorspace', 'srgbcolorspace' # Mac OS X : sRGBColorspace
if image.image_type.to_s == 'GrayscaleType' and image.class_type.to_s == 'PseudoClass'
out['channels'] = 0
else
out['channels'] = 3
end
when 'graycolorspace'
out['channels'] = 0
end
out['bits'] = image.channel_depth
out
end
end

Related

Access ActiveStorageBlob or ActiveStorageAttachment like it would be a native model

Would it be possible to access the ActiveStorageBlob or ActiveStorageAttachment like it would be a native model ?
E.g.
I want to do ActiveStorageBlob.first to access the first record of this model/table.
or. ActiveStorageAttachment.all.as_json to generate json formated print.
The background idea is to find a way how to dump the content of these ActiveStorage related tables as json formated files. Then change simething on these files, and load it back.
----Extending this text after got correct answer-----
Thank you very much Sarah Marie.
And I hope you know how to load the JSON data back into these tables ?
I have tried this :
dump_file_path = File.join(Rails.root, "backup", active_storage_blobs_file)
load_json = JSON.parse(File.read(dump_file_path))
load_json.each do |j|
ActiveStorage::Blob.create(j)
end
But thats not working.
ActiveModel::UnknownAttributeError (unknown attribute
'attachable_sgid' for ActiveStorage::Blob.)
ActiveStorage::Blob.first
ActiveStorage::Attachment.all.as_json
---- For second extended question ----
ActiveStorage::Blob.create_before_direct_upload!(
filename: j[:filename],
content_type: j[:content_type],
byte_size: j[:byte_size],
checksum: j[:checksum]
)
# or
ActiveStorage::Blob.create_before_direct_upload!(**j.symbolize_keys)
Reference: https://github.com/rails/rails/blob/5f3ff60084ab5d5921ca3499814e4697f8350ee7/activestorage/app/controllers/active_storage/direct_uploads_controller.rb#L8-L9
https://github.com/rails/rails/blob/098fd7f9b3d5c6f540911bc0c17207d6b48d5bb3/activestorage/app/models/active_storage/blob.rb#L113-L120
Now I have a complete solution, how to dump and load the ActiveStorage tables as JSON files.
...dump it
active_storage_blobs_file = "active_storage_blob.json"
active_storage_attachments_file = "active_storage_attachment.json"
puts("...dump active_storage_blob")
dump_file_path = File.join(Rails.root, "backup",active_storage_blobs_file)
dump_file = File.open(dump_file_path, "w")
dump_file.write(JSON.pretty_generate(ActiveStorage::Blob.all.as_json))
dump_file.close()
puts("...dump active_storage_attachment")
dump_file_path = File.join(Rails.root, "backup",
active_storage_attachments_file)
dump_file = File.open(dump_file_path, "w")
dump_file.write(JSON.pretty_generate(ActiveStorage::Attachment.all.as_json))
dump_file.close()
...load it back
puts("...load active_storage_blob")
dump_file_path = File.join(Rails.root, "backup", active_storage_blobs_file)
abort("File does not exist (" + dump_file_path + ") > abort <") unless File.exist?(dump_file_path)
load_json = JSON.parse(File.read(dump_file_path))
load_json.each do |j|
j = j.except("attachable_sgid")
result = ActiveStorage::Blob.create(j)
if (not result.errors.empty?)
puts(result.errors.full_messages.to_s)
puts(j.inspect)
exit(1)
end
end
puts("...load active_storage_attachment")
dump_file_path = File.join(Rails.root, "backup", active_storage_attachments_file)
abort("File does not exist (" + dump_file_path + ") > abort <") unless File.exist?(dump_file_path)
load_json = JSON.parse(File.read(dump_file_path))
load_json.each do |j|
result = ActiveStorage::Attachment.create(j)
if (not result.errors.empty?)
puts(result.errors.full_messages.to_s)
puts(j.inspect)
exit(1)
end
end

How to upload base64 image to s3 from rails controller?

I am making an ajax reject to my controller with some data and base64 image and now I want to upload this image to s3 and replace base64 with the image url. I am following this https://sebastiandobrincu.com/blog/how-to-upload-images-to-rails-api-using-s3
def split_base64(uri_str)
if uri_str.match(%r{^data:(.*?);(.*?),(.*)$})
uri = Hash.new
uri[:type] = $1 # "image/gif"
uri[:encoder] = $2 # "base64"
uri[:data] = $3 # data string
uri[:extension] = $1.split('/')[1] # "gif"
return uri
else
return nil
end
end
def convert_data_uri_to_upload(image_url)
image_data = split_base64(image_url)
image_data_string = image_data[:data]
image_data_binary = Base64.decode64(image_data_string)
temp_img_file = Tempfile.new("")
temp_img_file.binmode
temp_img_file << image_data_binary
temp_img_file.rewind
img_params = {:filename => "image.#{image_data[:extension]}", :type => image_data[:type], :tempfile => temp_img_file}
uploaded_file = ActionDispatch::Http::UploadedFile.new(img_params)
end
return uploaded_file
end
Now from my controller I am passing
convert_data_uri_to_upload(base64_image)
Now I don't know where to write the AWS credentials. According to the url I have to write the credentials in Fog.rb file but I don't have any such file. I have created one ImageUploader inside uploader folder which extends CarrierWave and wrote the configurations but it is also not working.
You can use dotenv ruby gem follow this : http://www.rubydoc.info/gems/dotenv-rails/2.1.1

Getting shared path in controller with Rails and Capistrano

I have an upload system that performs several conversion operations on uploaded files (needs the real file paths to do them) and then stores paths of the resulting files.
Those files will be accessed later to create a zip file (again real path needed)
The problem with Capistrano is obviously when I store the file path using Rails.root.join('public', 'uploads', 'designer_user_uploaded') and then try to create my zip file like 10 days later and the release has changed, the stored file path no longer points to the correct location.
My directory is in the linked dirs for Capistrano. So the files are not lost but they just can't be retrieved anymore.
I'm not sure how I should handle this. I think it would be easy to solve by just doing something like File.join(shared_path, 'public', 'uploads', 'designer_user_uploaded') but I can't find how to get the shared path from controllers. Also this might not work in development.
I'm on Rails 4.2.6
output_folder = Rails.root.join('public', 'uploads', 'designer_user_uploaded')
FileUtils.mkdir_p(output_folder) unless File.directory?(output_folder)
file_name = sanitize_filename(Time.now.to_s + "_" + SecureRandom.uuid)
original_file_path = output_folder.join(change_file_extension(file_name, ext))
designer_file_path = ext == '.ai' || ext == '.eps' ?
output_folder.join(change_file_extension(file_name, '.svg')) : output_folder.join(change_file_extension(file_name, ext))
if ext == '.ai' || ext == '.eps'
copy_file(file.path, original_file_path)
copy_file(svg_path, designer_file_path)
#response[:original_file_path] = original_file_path
#response[:designer_file_path] = designer_file_path
#response[:file_name] = file_name + '.svg'
#response[:file_type] = "svg"
#response[:colors] = get_image_colors(original_file_path)
# Store created file paths for future access
#up = UserUpload.create(designer_path: designer_file_path, original_path: original_file_path)
puts #up.id
#response[:file_id] = #up.id
else
copy_file(file.path, designer_file_path)
#response[:original_file_path] = nil
#response[:designer_file_path] = designer_file_path
#response[:file_name] = file_name + ext
#response[:file_type] = ext == '.svg' ? 'svg' : "image"
#response[:colors] = get_image_colors(designer_file_path)
# Store created file path for future access
#up = UserUpload.create(designer_path: designer_file_path)
puts #up.id
#response[:file_id] = #up.id
end
# Embroidery conversion
is_embroidery = params[:is_embroidery].to_s.downcase == 'true'
if is_embroidery && (ext == '.svg' || ext == '.ai' || ext == '.eps')
embroidery_file_name = "embroidery_#{file_name}.svg"
embroidery_path = output_folder.join(embroidery_file_name)
Embroidery::EmbroideryConversionJob.perform_async(original_file_path, embroidery_path, #up)
#response[:designer_file_path] = embroidery_path
#response[:file_name] = embroidery_file_name
#response[:file_type] = "embroidery"
end
#response[:output_url] = '/uploads/designer_user_uploaded/'
file.close(true)

Convert image into base64 using capybara

I'm currently using capybara to run some scrapping tasks as well as site testing. I have been having difficulties in downloading images/files using capybara. All the documentations I found only guides on simple buttons,forms, links interaction.
Would really appreciate it if someone knows how to download/convert images on a webpage into base64 format.
This example extracts an image from a web page with Capybara / Selenium :
require 'capybara'
JS_GET_IMAGE = "
var ele = arguments[0], callback = arguments[1], img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function(){
var cnv = document.createElement('CANVAS');
cnv.width = this.width;
cnv.height = this.height;
cnv.getContext('2d').drawImage(this, 0, 0);
var type = this.src.endsWith('png') ? 'png' : 'jpeg';
callback(cnv.toDataURL('image/' + type).substring(22));
};
var src = ele.src || window.getComputedStyle(ele).backgroundImage;
img.src = /https?:/.test(src) ? src.match(/https?:[^\"')]+/)[0] : callback(''); "
session = Capybara::Session.new(:selenium)
driver = session.driver.browser
driver.manage.timeouts.script_timeout = 5000
# navigate to google
session.visit "https://www.google.co.uk/"
# get the logo element
ele = session.find(:css, '#hplogo img:nth-child(1)')
# get the logo as base64 string
imgBase64 = driver.execute_async_script(JS_GET_IMAGE, ele.native)
# save to a file
file = File.new("C:\\temp\\image." + (imgBase64[0] == 'i' ? 'png' : 'jpg'), 'wb')
file.write(Base64.decode64(imgBase64))
file.close
Just looked through the capybara gem and found a .render_base64 and save_screenshot method which could save the image into png or jpg file and after that i could crop the part i wanted. Method can be found here: https://github.com/teampoltergeist/poltergeist

Nokogiri+Paperclip = XML parse with img from url

I need to parse some params to my DB and image from URL.
I use paperclip for image.
In Rails console I can add image to new post by this code:
image = Image.new
image.image_from_url "http://yug-avto.ru/files/image/tradein/hyundai/877_VOLKSWAGEN_FAETON_2011_2_1366379491.jpg"
image.watermark = true
image.save!
in my Image model I have
require "open-uri"
.......
def image_from_url(img_url)
self.image = open(img_url)
end
And all work done. But when I use Nokogiri, this code don't work.
rake aborted!
No such file or directory -
http://yug-avto.ru/files/image/tradein/peugeot/1027_Peugeot_308_2011_2_1370850441.jpg
My rake task for Nokogiri parse:
doc.xpath("//item").each do |ad|
img = ad.at("image").text
img1 = Image.new
img1.image = open("#{img}")
img1.watermark = true
img1.save!
end
In rake task for Nokogiri, I have require 'nokogiri' and require 'open-uri'.
How to be?:))))
This is a code snippet from my parser... I guess where you went wrong is using open(url) instead of parse(url).
picture = Picture.new(
realty_id: realty.id,
position: position,
hashcode: realty.hashcode
)
# picture.image = URI.parse(url), edit: added open() as this worked for Savroff
picture.image = open(URI.parse(url))
picture.save!
Additionally it would be a good idea to check if the image really exists
picture_array.each do |url|
# checks if the Link works
res = Net::HTTP.get_response(URI.parse(url))
# if so, it will add the Picture Link to the verified Array
if res.code.to_i >= 200 && res.code.to_i < 400 #good codes will be betweem 200 - 399
verified_array << url
end
end
Thanks TheChamp, you led me to the right thoughts.
First need to parse URL and after that open.
image = Image.new
ad_image_url = URI.parse("#{img}")
image.image = open(ad_image_url)
image.watermark = true
image.save!

Resources