How to dynamically add text into base64 image - ruby-on-rails

I have a function that generates qr code png as base64 from a given URL.
When I put the data coming out of this function into an src It renders the image. I would like to add some text into this image as well so that it writes some description underneath the QR code.
Here is the function:
def generate_qr(model)
url = model_url(model)
require 'barby'
require 'barby/barcode'
require 'barby/barcode/qr_code'
require 'barby/outputter/png_outputter'
barcode = Barby::QrCode.new(url, level: :q, size: 10)
company_name = Base64.encode64("#{model.company.name} - #{model.name}")
qr_output = Base64.encode64(barcode.to_png({ xdim: 10 }))
"data:image/png;base64,#{qr_output}"
end
How can I append the company_name variable underneath my qrcode.png so that when they download the image text is also in the image?
This did not work.
qr_output = Base64.encode64(barcode.to_png({ xdim: 10 }) + company_name)
Neither this:
qr_output = Base64.encode64(barcode.to_png({ xdim: 10 }) + "#{model.company.name} - #{model.name}")

Related

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

Extracting text from a child node within an <a> tag through xpath

I have some data-scraping code intended to pull both the image url and the name of the image (located in the a tag). The code as its written looks like this:
BASE = 'http://antwrp.gsfc.nasa.gov/apod/'
f = open 'http://antwrp.gsfc.nasa.gov/apod/archivepix.html'
html_doc = Nokogiri::HTML(f.read)
html_doc.xpath('//b//a')[0..10].each do |element|
imgurl = BASE + element.attributes['href'].value
imgname = element.attributes['innerText']
puts imgname
doc = Nokogiri::HTML(open(imgurl).read)
doc.xpath('//p//a//img').each do |elem|
small_img = BASE + elem.attributes['src'].value
puts small_img
end
end
When I run that program I get this output:
http://antwrp.gsfc.nasa.gov/apod/image/1308/twolines_yen_960.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/perseids_vangaal_960.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/phas_jpl_960.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/m74_hubble_960.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/tafreshiIMG_4098Trail-s900.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/Albrechtsberg_Perseid2012-08-12_voltmer900.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/ngc3370_hst_900.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/auroraemeteors_boardman_1770.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/cone_noajgendler_960.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/ioplus_galileo_960.jpg
The lines in between the links is where I expect the name of the image to appear (for example: "Moonset from Taiwan" for the first image). I have a feeling the reason I cannot get the name to appear is because it is a child node and I am not accessing it. Does anyone know how I should alter the imgname variable to return the image name?
What about
html_doc.xpath('//b//a')[0..10].each do |element|
imgurl = BASE + element.attributes['href'].value
#imgname = element.attributes['innerText']
imgname = element.content
puts imgname
...
end
element.text or element.inner_text should provide the same output in your case

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!

How do I pull the correct image URL from this Wikipedia table?

I built a scraper to pull all the information out of a Wikipedia table and upload it to my database. All was good until I realized I was pulling the wrong URL on images, and I wanted the actual image URL "http://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Baconbutty.jpg" and not the "/wiki/File:Baconbutty.jpg" it was apt to give me. Here is my code so far:
def initialize
#url = "http://en.wikipedia.org/wiki/List_of_sandwiches"
#nodes = Nokogiri::HTML(open(#url))
end
def summary
sammich_data = #nodes
sammiches = sammich_data.css('div.mw-content-ltr table.wikitable tr')
sammich_data.search('sup').remove
sammich_hashes = sammiches.map {|x|
if content = x.css('td')[0]
name = content.text
end
if content = x.css('td a.image').map {|link| link ['href']}
image =content[0]
end
if content = x.css('td')[2]
origin = content.text
end
if content = x.css('td')[3]
description =content.text
end
My issue is with this line:
if content = x.css('td a.image').map {|link| link ['href']}
image =content[0]
If I go to td a.image img, it just gives me a null entry.
Any suggestions?
Here's how I'd do it (if I was to scrape Wikipedia, which I wouldn't because they do have an API for this stuff):
require 'nokogiri'
require 'open-uri'
require 'pp'
doc = Nokogiri::HTML(open("http://en.wikipedia.org/wiki/List_of_sandwiches"))
sammich_hashes = doc.css('table.wikitable tr').map { |tr|
name, image, origin, description = tr.css('td,th')
name, origin, description = [name, origin, description].map{ |n| n && n.text ? n.text : nil }
image = image.at('img')['src'] rescue nil
{
name: name,
origin: origin,
description: description,
image: image
}
}
pp sammich_hashes
Which outputs:
[
{:name=>"Name", :origin=>"Origin", :description=>"Description", :image=>nil},
{
:name=>"Bacon",
:origin=>"United Kingdom",
:description=>"Often served with ketchup or brown sauce",
:image=>"//upload.wikimedia.org/wikipedia/commons/thumb/3/38/Baconbutty.jpg/120px-Baconbutty.jpg"
},
... [lots removed] ...
{
:name=>"Zapiekanka",
:origin=>"Poland",
:description=>"A halved baguette or other bread usually topped with mushrooms and cheese, ham or other meats, and vegetables",
:image=>"//upload.wikimedia.org/wikipedia/commons/thumb/1/12/Zapiekanka_3..jpg/120px-Zapiekanka_3..jpg"
}
]
If an image isn't available, the field will be set to nil in the returned hashes.
You could use the srcset attribute of the imgelement, split it and keep one of the available resized images.
if content = x.at_css('td a.image img')
image =content['srcset'].split(' 1.5x,').first

Scrape image from YouTube video page

When I copy a YouTube link, like this one, for example (http://www.youtube.com/watch?v=_Ka2kpzTAL8), and paste it into a Facebook status update, Facebook somehow grabs a still of the video. I'd like to build a feature that does the same thing, but I don't really know how to find the image.
Can anyone point me in the right direction? I'm open to PHP, Python, Ruby or Perl.
Alright, found it !
Take this link: http://i4.ytimg.com/vi/something/hqdefault.jpg and replace something with the video's ID on Youtube. For a smaller image, just remove the hq part of the URL.
I can also confirm this implementation is the way two go. I have used it a Ruby screen scraper ( search application ) # http://stripsearch.me
# search10b Youtube crawl9
#search10a1 = search_array[1]
if search_array[1].present?
#results_9b = []
params_9b = search_array[1].split.map(&:downcase).join('+')
search_url_yt_9b = url_9b << params_9b
doc_9b = Nokogiri::HTML(open(search_url_yt_9b).read, nil, 'utf-8')
entries_9b = doc_9b.css('.yt-ui-ellipsis-2.spf-link')
if entries_9b.size != 0
entries_9b.each do |entry_9b|
title = entry_9b['title']
li = "https://www.youtube.com"
nk = entry_9b['href']
link = li << nk
img_src = entry_9b['href']
uid = img_src.split('=').last
precede_url = "http://i4.ytimg.com/vi/"
append_url = "/hqdefault.jpg"
img_url = precede_url << uid << append_url
precede_tag = "<img src="
append_tag = ">"
img = precede_tag << img_url << append_tag
#results_9b.push(title, link, img)
end
else
#error_9b = "no results found here for " + params_9b
end
end

Resources