Convert Binary Data to Torch Tensor in Lua - lua

I have Lua code that downloads an image from a url using a luasocket:
local http = require('socket.http')
local image = require('image')
image_url = 'https://www.somedomain.com/someimage.jpg'
local body, code = http.request(image_url) -- body has jpg binary data
if not body then error(code) end -- check for errors
In order to read this image into a Torch tensor, I save it in a jpg file and read it using image.load:
-- open a file in binary mode to store the image
local f = assert(io.open('./temp.jpg', 'wb'))
f:write(body)
f:close()
tensor = image.load('temp.jpg')
Is there a way to convert the binary jpg data to a torch tensor directly without doing a write-to-and-read-from the hard-drive? Something like:
tensor = CovertBinaryDataToTorchTensor(body)
Thank you!

See image.decompressJPG.
You just have to pack your body string inside a ByteTensor first. This can be done by constructing this tensor with a storage which can set his contents with string(str).

One potential solution is to use graphicsmagick.
local gm = require 'graphicsmagick'
local img = gm.Image()
local ok = pcall(img.fromString, img, body)
img = img:toTensor('float', 'RGB', 'DHW')
I found this example in https://github.com/clementfarabet/graphicsmagick/blob/master/test/corrupt.lua and I know that
local body, code = http.request(image_url)
will return body as a string. And, obviously if pcall returns false, the image was corrupt.

Related

How to convert Unit8List to Files in flutter

I have used opencv to enhance the image in flutter which returns a Unit8List as a dynamic result i have used to display the image.
Image newImage = Image.memory(res);
How to convert that image it to file, or how to write Unit8List as a file. I have tried this but its printing ���� as the file path
File imageNeww = File.fromRawPath(res);
print(imageNeww.path);
Use the file class
File f = File('desired/path/to/file.png');
await f.writeAsBytes(bytes);
here bytes are your Uint8List

How to get a bitmap image in ruby?

The google vision API requires a bitmap sent as an argument. I am trying to convert a png from a URL to a bitmap to pass to the google api:
require "google/cloud/vision"
PROJECT_ID = Rails.application.secrets["project_id"]
KEY_FILE = "#{Rails.root}/#{Rails.application.secrets["key_file"]}"
google_vision = Google::Cloud::Vision.new project: PROJECT_ID, keyfile: KEY_FILE
img = open("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png").read
image = google_vision.image img
ArgumentError: string contains null byte
This is the source code processing of the gem:
def self.from_source source, vision = nil
if source.respond_to?(:read) && source.respond_to?(:rewind)
return from_io(source, vision)
end
# Convert Storage::File objects to the URL
source = source.to_gs_url if source.respond_to? :to_gs_url
# Everything should be a string from now on
source = String source
# Create an Image from a HTTP/HTTPS URL or Google Storage URL.
return from_url(source, vision) if url? source
# Create an image from a file on the filesystem
if File.file? source
unless File.readable? source
fail ArgumentError, "Cannot read #{source}"
end
return from_io(File.open(source, "rb"), vision)
end
fail ArgumentError, "Unable to convert #{source} to an Image"
end
https://github.com/GoogleCloudPlatform/google-cloud-ruby
Why is it telling me string contains null byte? How can I get a bitmap in ruby?
According to the documentation (which, to be fair, is not exactly easy to find without digging into the source code), Google::Cloud::Vision#image doesn't want the raw image bytes, it wants a path or URL of some sort:
Use Vision::Project#image to create images for the Cloud Vision service.
You can provide a file path:
[...]
Or any publicly-accessible image HTTP/HTTPS URL:
[...]
Or, you can initialize the image with a Google Cloud Storage URI:
So you'd want to say something like:
image = google_vision.image "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
instead of reading the image data yourself.
Instead of using write you want to use IO.copy_stream as it streams the download straight to the file system instead of reading the whole file into memory and then writing it:
require 'open-uri'
require 'tempfile'
uri = URI("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png")
tmp_img = Tempfile.new(uri.path.split('/').last)
IO.copy_stream(open(uri), tmp_img)
Note that you don't need to set the 'r:BINARY' flag as the bytes are just streamed without actually reading the file.
You can then use the file by:
require "google/cloud/vision"
# Use fetch as it raises an error if the key is not present
PROJECT_ID = Rails.application.secrets.fetch("project_id")
# Rails.root is a Pathname object so use `.join` to construct paths
KEY_FILE = Rails.root.join(Rails.application.secrets.fetch("key_file"))
google_vision = Google::Cloud::Vision.new(
project: PROJECT_ID,
keyfile: KEY_FILE
)
image = google_vision.image(File.absolute_path(tmp_img))
When you are done you clean up by calling tmp_img.unlink.
Remember to read things in binary format:
open("https://www.google.com/..._272x92dp.png",'r:BINARY').read
If you forget this it might try and open it as UTF-8 textual data which would cause lots of problems.

Download file by url in lua

Lua beginner here. :)
I am trying to load a file by url and somehow I am just too stupid to get all the code samples here on SO to work for me.
How to download a file in Lua, but write to a local file as it works
downloading and storing files from given url to given path in lua
socket = require("socket")
http = require("socket.http")
ltn12 = require("ltn12")
local file = ltn12.sink.file(io.open('test.jpg', 'w'))
http.request {
url = 'http://pbs.twimg.com/media/CCROQ8vUEAEgFke.jpg',
sink = file,
}
my program runs for 20 - 30s and afterwards nothing is saved. There is a created test.jpg but it is empty.
I also tried to add w+b to the io.open() second parameter but did not work.
The following works:
-- retrieve the content of a URL
local http = require("socket.http")
local body, code = http.request("http://pbs.twimg.com/media/CCROQ8vUEAEgFke.jpg")
if not body then error(code) end
-- save the content to a file
local f = assert(io.open('test.jpg', 'wb')) -- open in "binary" mode
f:write(body)
f:close()
The script you have works for me as well; the file may be empty if the URL can't be accessed (the script I posted will return an error in this case).

Strange bug involving string comparison in Lua

I am trying to create a program that scrapes images from the web in Lua. A minor problem is that images sometimes have no extension or incorrect extensions. See this animated "jpeg" for example: http://i.imgur.com/Imvmy6C.jpg
So I created a function to detect the filetype of an image. It's pretty simple, just compare the first few characters of the returned image. Png files begin with PNG, Gifs with GIF, and JPGs with the strange symbol "╪".
It's a bit hacky since images aren't supposed to be represented as strings, but it worked fine. Except when I actually ran the code.
When I enter the code into the command line it works fine. But when I run a file with the code in it, it doesn't work. Weirder, it only fails on jpegs. It still correctly recognizes PNGs and GIFs.
Here is the minimal code necessary to reproduce the bug:
http = require "socket.http"
function detectImageType(image)
local imageType = "unknown"
if string.sub(image, 2, 2) == "╪" then imageType = "jpg" end
return imageType
end
image = http.request("http://i.imgur.com/T4xRtBh.jpg")
print(detectImageType(image))
Copy and pasting this into the command line returns "jpg" correctly. Running this as a file returns "unknown".
I am using Lua 5.1.4 from the Lua for Windows package, through powershell, on Windows 8.1.
EDIT:
Found the problem string.byte("╪") returns 216 on the command line and 226 when run as a file. I have no idea why, maybe different encodings for lua and powershell?
This line solves the problem:
if string.byte(string.sub(image, 2, 2)) == 216 then imageType = "jpg" end
I think it's because when you're saving your file you're saving it as a different encoding so the ╪ character may be translated to another character. It's more robust to convert it to the byte code:
http = require "socket.http"
function detectImageType(image)
local imageType = "unknown"
if string.byte(image, 2) == 216 then imageType = "jpg" end
return imageType
end
image = http.request("http://i.imgur.com/T4xRtBh.jpg")
print(detectImageType(image))

How to parse JSON Data in Corona SDK [duplicate]

I'm trying to make an app where I will gather information from a json api http://pool-x.eu/api, and print information easly bo choosing parameter.
What is the easiest way to print each of the informations?
Was thinking something in the way of making the information a string, and then request each of the parameters that way, but I don't know if that's the way to do it.
here's a sample code to decode the json data i just happen to make a json text file out if the link you gave and decode it hope it helps
local json = require "json"
local txt
local path = system.pathForFile( "json.txt", system.ResourceDirectory )
local file = io.open( path, "r" )
for line in file:lines() do
txt = line
end
print(txt)
local t = json.decode( txt )
print(t["pool_name"])
print(t["hashrate"])
print(t["workers"])
print(t["share_this_round"])
print(t["last_block"])
print(t["network_hashrate"])

Resources