Skip to content

Commit

Permalink
Merge pull request #2 from Dyaminigo/for-pr
Browse files Browse the repository at this point in the history
  • Loading branch information
alekssamos authored Jan 20, 2022
2 parents 4eea533 + 957c71a commit 965f4bd
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 148 deletions.
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
237 changes: 142 additions & 95 deletions cloudvis.go
Original file line number Diff line number Diff line change
@@ -1,98 +1,145 @@
package main
import "time"
import "fmt"
import "net/http"
import "encoding/json"
import "mime/multipart"
import "io/ioutil"
import "os"
import "log"
import "flag"
import "bytes"
var ApiUrl string = "https://visionbot.ru/apiv2"
func multipartuploadreq(url string, params map[string]string, filedata []byte) *http.Request {
rbody := new(bytes.Buffer)
writer := multipart.NewWriter(rbody)
filepart,_ := writer.CreateFormFile("file", "img")
filepart.Write(filedata)
for parname,parval := range params {
writer.WriteField(parname, parval)
}
err := writer.Close()
if err != nil {
log.Fatal(err)
}
req,_ := http.NewRequest("POST", "https://visionbot.ru/apiv2/in.php", rbody)
req.Header.Set("Content-Type", writer.FormDataContentType())
return req
}

import (
"bytes"
"context"
"flag"
"fmt"
"io/ioutil"
"log"
"mime/multipart"
"os"
"time"

requests "github.com/carlmjohnson/requests"
)

type UploadResponse struct {
Status string `json:"status"`
Id string `json:"id"`
}

type RecognitionResult struct {
UploadResponse
Text string `json:"text"`
QR string `json:"qr"`
}

func uploadImage(url string, params map[string]string, fileData []byte) (*UploadResponse, error) {
var upResponse UploadResponse

rbody := new(bytes.Buffer)
writer := multipart.NewWriter(rbody)
defer writer.Close()
filepart, _ := writer.CreateFormFile("file", "img")
filepart.Write(fileData)
for pname, pval := range params {
writer.WriteField(pname, pval)
}

err := requests.
URL(url).
BodyBytes(rbody.Bytes()).
ContentType(writer.FormDataContentType()).
ToJSON(&upResponse).
Fetch(context.Background())

return &upResponse, err
}

func getResult(url string, id string) (*RecognitionResult, error) {
var result RecognitionResult

err := requests.
URL(url).
Param("id", id).
ToJSON(&result).
Fetch(context.Background())

return &result, err
}

func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s [opts] [file] \n file is a image file name. png and jpg are officially supported. \n Opts can be one of:\n", os.Args[0])
flag.PrintDefaults()
}
usestdin := flag.Bool("stdin", false, "get image data from stdin, filename will be ignored")
lang := flag.String("l", "en", "set `language` name to use. language is formed as two letter code, like ru or en, default is en.")
target := flag.String("t", "all", "data `type` to recognize. can be 'text', 'image' or 'all'.")
flag.Parse()
var file *os.File
var err error
if *usestdin {
file = os.Stdin
} else {
file,err = os.Open(flag.Arg(0))
}
if err != nil {
log.Fatal(err)
}
filedata,err := ioutil.ReadAll(file)
if err != nil {
log.Fatal(err)
}
file.Close()
params := map[string]string{"lang": *lang, "target": *target}
req := multipartuploadreq(ApiUrl + "/in.php", params, filedata)
os.Stderr.WriteString("uploading image\n")
resp,err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
bodydata,err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
resp.Body.Close()
var bodyresult map[string]string
err = json.Unmarshal(bodydata, &bodyresult)
if err != nil {
log.Fatal(err)
}
if bodyresult["status"] != "ok" {
log.Fatal(fmt.Errorf("server error"))
}
id := bodyresult["id"]
os.Stderr.WriteString("waiting for result\n")
for {
time.Sleep(500 * time.Millisecond)
gresp,err := http.Get(ApiUrl + "/res.php?id=" + id)
if err != nil {
log.Fatal(err)
}
bodydata,err = ioutil.ReadAll(gresp.Body)
if err != nil {
log.Fatal(err)
}
bodyresult = nil
err = json.Unmarshal(bodydata, &bodyresult)
if err != nil {
log.Fatal(err)
}
if bodyresult["status"] == "error" {
log.Fatal(fmt.Errorf("server error"))
}
if bodyresult["status"] == "ok" {
fmt.Println(bodyresult["text"])
break
}
flag.Usage = func() {
fmt.Printf("Usage: %s [opts] [file] \n file is a image file name. png and jpg are officially supported. \n Opts can be one of:\n", os.Args[0])
flag.PrintDefaults()
}
useStdin := flag.Bool("stdin", false, "Get image data from stdin, filename will be ignored")
lang := flag.String("l", "en", "Set `language` name to use. Language is formed as two letter code, like ru or en")
target := flag.String("t", "all", "Data `type` to recognize. Can be 'text', 'image' or 'all'")
translate := flag.Bool("tr", false, "Translate recognition result")
qr := flag.Bool("qr", false, "Recognize QR/BAR codes")
flag.Parse()

var file *os.File
if *useStdin {
file = os.Stdin
} else {
var filename = flag.Arg(0)
if filename == "" {
log.Fatal("File name not specified")
}
if _, err := os.Stat(filename); os.IsNotExist(err) {
log.Fatalf("File %v does not exist", filename)
}
var err error
file, err = os.Open(filename)
if err != nil {
log.Fatal(err)
}
}

filedata, err := ioutil.ReadAll(file)
if err != nil {
log.Fatal(err)
}
defer file.Close()

const apiUrl = "https://visionbot.ru/apiv2"
params := map[string]string{
"lang": *lang,
"target": *target,
"qr": "0",
"translate": "0",
}

if *qr {
params["qr"] = "1"
}
if *translate {
params["translate"] = "1"
}
fmt.Println("Uploading image...")
resp, err := uploadImage(apiUrl+"/in.php", params, filedata)
if err != nil {
log.Fatal(err)
}

if resp.Status != "ok" {
log.Fatal("Server error. Try again later")
}

id := resp.Id
fmt.Println("Waiting for result...")
for {
res, err := getResult(apiUrl+"/res.php", id)
if err != nil {
log.Fatal(err)
}

if res.Status == "error" {
log.Fatal("Server error. Try again later")
} else if res.Status == "ok" {
if res.Text == "" {
fmt.Println("No text")
} else {
fmt.Println(res.Text)
}
if res.QR != "" {
fmt.Printf("\nQR:\n%v", res.QR)
}
break
}
time.Sleep(1 * time.Second)
}
}
}
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/alekssamos/cloudvis

go 1.17

require (
github.com/carlmjohnson/requests v0.22.1 // indirect
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/carlmjohnson/requests v0.22.1 h1:YoifpEbpJW4LPRX/+0dJe3vTLducEE9Ib10k6lElIUM=
github.com/carlmjohnson/requests v0.22.1/go.mod h1:Hw4fFOk3xDlHQbNRTGo4oc52TUTpVEq93sNy/H+mrQM=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
117 changes: 64 additions & 53 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,67 @@
sea english text below
# cloudvis
простой консольный клиент для сервиса CloudVision (https://visionbot.ru).
использование: `cloudvis опции файл`
`файл` - имя файла изображения в формате png или jpg.
поддерживаемые опции:
`-l language`
указывает, какой язык использовать, имя языка задаётся в виде двухбуквенного кода, например `ru` или `en`. поумолчанию `en`.
список поддерживаемых языков см. на сайте сервиса.
`-stdin`
читать изображение со stdin вместо файла.
`-t type`
указывает тип данных для распознавания. может быть `text`, `image` или `all`. поумолчанию `all`.
готовые исполняемые файлы для windows вы можете найти в разделе releasies репозитория.
## сборка
требования:
среда разработки [golang](https://golang.org)
тестировалось на go 1.14.1
дополнительные пакеты не требуются

затем
`go get github.com/alekssamos/cloudvis`

процесс распознавания осуществляется в облаке при использовании [этого](https://visionbot.ru) сервиса.
это приложение не осуществляет какую-либо обработку загружаемых изображений, поэтому обо всех ошибках, связанных с некорректным распознаванием, следует сообщать напрямую [разработчику](mailto:aleks-samos@yandex.ru) сервиса.
обратите также внимание, что хотя распознавание текста работает достаточно хорошо, не стоит полностью доверять результату в вопросе распознавания предметов.

в своей работе приложение использует следующий api:
https://visionbot.ru/apiv2
Простой консольный клиент для сервиса [VisionBot](https://visionbot.ru).
Использование: `cloudvis [опции] файл`
`Файл` - имя файла в формате png или jpg.

Поддерживаемые опции:
`-l language`
Указывает, какой язык использовать, язык задаётся в виде двухбуквенного кода (например `ru` или `en`). По умолчанию `en`.
Список поддерживаемых языков см. на сайте сервиса.
`-stdin`
Читать изображение с stdin вместо файла.
`-t type`
Указывает тип данных для распознавания. Может быть `text`, `image` или `all`. По умолчанию `all`.
`-tr`
Перевести результат распознавания. Если флаг установлен, результат будет переведён, иначе вернётся исходный текст. По умолчанию перевод отключён.
`-qr`
Распознать QR/BAR коды. Если флаг установлен, то сервис попытается распознать QR/BAR код с изображений. Если флаг не установлен, будет использоваться только стандартное распознавание. По умолчанию распознавание QR/BAR отключено.
## Сборка
Требования:
- Среда разработки [golang](https://golang.org)

Сборка тестировалась на Go 1.17.6.

Далее выполните такие команды:
`git clone https://github.com/alekssamos/cloudvis.git`
`cd cloudvis`
`go build cloudvis.go`

Распознавание осуществляется в облаке при использовании [этого](https://visionbot.ru) сервиса.
Данный консольный клиент не осуществляет какую-либо обработку загружаемых изображений, поэтому обо всех ошибках, связанных с некорректным распознаванием, следует сообщать напрямую [разработчику](mailto:aleks-samos@yandex.ru) сервиса.
Обратите внимание, что хоть распознавание текста работает достаточно хорошо, не стоит полностью доверять результату в вопросе распознавания предметов.

## english
simple console client for CloudVision service (https://visionbot.ru).
Usage: `cloudvis opts file`
`file` is a image file name. png and jpg are officially supported.
Opts can be one of:
`-l language`
set language name to use. language is formed as two letter code, like `ru` or `en`, default is `en`. (default `"en"`)
`-stdin`
get image data from stdin, filename will be ignored
`-t` type
data type to recognize. can be `'text'`, `'image'` or `'all'`. (default "all")
precompiled binaries for windows can be found in releases section
## build
requirements:
[golang](https://golang.org) build environment.
tested on go 1.14.1
no any additional packages required.

then
`go get github.com/alekssamos/cloudvis`

all recognition computations are made in the cloud by [this](https://visionbot.ru) service.
this app don't makes any preprocessing for images, so all wrong recognition issues should be passed to [service's [developer](mailto:aleks-samos@yandex.ru)

in it's work this app uses following api:
В своей работе приложение взаимодействует со следующей конечной точкой API:
https://visionbot.ru/apiv2

# English
Simple console client for [VisionBot](https://visionbot.ru) service.
Usage: `cloudvis [opts] file`
`file` is a image file name. png and jpg are officially supported.
Opts can be one of:
`-l language`
Set language name to use. Language is formed as two letter code, like ru or en (default "en")
`-stdin`
Get image data from stdin, filename will be ignored
`-t type`
Data type to recognize. Can be 'text', 'image' or 'all' (default "all")
`-tr`
Translate the recognition result. If the flag is set, the result will be translated, otherwise the original text will be returned. Translation is disabled by default
`-qr`
Recognize QR/BAR codes. If the flag is set, the service will try to recognize the QR/BAR code from the images. If the flag is not set, only standard recognition will be used. QR/BAR recognition is disabled by default
## Build
Requirements:
- Build environment [golang](https://golang.org)

Tested on Go 1.17.6.

Next, run the following commands:
`git clone https://github.com/alekssamos/cloudvis.git`
`cd cloudvis`
`go build cloudvis.go`

All recognition computations are made in the cloud by [this](https://visionbot.ru) service.
This console client does not perform any processing of uploaded images, so all errors related to incorrect recognition should be reported directly to [the developer](mailto:aleks-samos@yandex.ru) of the service.
Please note that although text recognition works quite well, you should not completely trust the result in the matter of recognizing objects.

In its work, the application interacts with the following API endpoint:
https://visionbot.ru/apiv2

0 comments on commit 965f4bd

Please sign in to comment.