Имя: Пароль:
1C
 
Как сканировать программно QR-Код 1С
Ø (Волшебник 07.08.2024 17:57)
,
0 SpLorT
 
07.08.24
19:17
Тема такая: Пользователь отправляет в чат-бот телеграм фото QR-кода. 1С на сервере формирует из телеграма фото на сервер. Как мне получить данные QR-кода с картинки, которую 1С создает на сервере?
1 Ненавижу 1С
 
гуру
07.08.24
08:46
(0) просто интересно - откуда пользователь берет фото qr-кода
2 CepeLLlka
 
07.08.24
09:03
Вероятно нужна либо библиотека которая сможет это сделать, либо нужно воспользоваться каким-нибудь сторонним сервисом.
Попробуйте погуглить.
Вот по первой ссылке такой сервис мне попался https://dewiar.com/publication/107
3 maxab72
 
07.08.24
09:05
(0) есть приложения, разной степени бесплатности, для расшифровки qr-кодов из картинок. вот в него и скидывать эту картинку.
4 SpLorT
 
07.08.24
19:17
(1) я ведь указал из 1С при печати документа формируется QR-код
5 SpLorT
 
07.08.24
19:16
(3) А как скинуть и какие приложения? дайте пример, пожалуйста
6 SpLorT
 
07.08.24
19:16
(2) Весь интернет перерыл, пришёл сюда писать, может кто знает
7 SpLorT
 
07.08.24
19:16
(2) за ссылку спасибо, попробую
8 Builder
 
07.08.24
10:24
(4) Интересно, QR-код формируется в той-же базе 1С или все-таки нет?
9 maxab72
 
07.08.24
10:47
(5) Во втором ответе как пример. по запросу "api для разбора qr-кодов" ссылок сразу несколько вылазит.
10 alex73
 
07.08.24
11:09
У нас была похожая задача с чеками самозанятых. Решили ее по-другому - стали запрашивать у контрагента на QR-код, а сразу ссылку на чек на сайте ФНС, которую QR-код в нашем случае содержал. А если разбирать именно сам QR-код - выше правильно написали про стороннее приложение. Довольно много (с полдюжины) статей по этой теме на ИС.
11 Garykom
 
гуру
07.08.24
13:03
(0)
Примерно так
package main

import (
	"fmt"
	"image"
	"image/png"
	"io"
	"os"
	"path/filepath"

	"github.com/h2non/filetype"
	"github.com/makiuchi-d/gozxing"
	"github.com/makiuchi-d/gozxing/qrcode"
	"github.com/sunshineplan/imgconv"
	"github.com/sunshineplan/pdf"
)

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func getParams() (inFile, outFile string) {
	params := os.Args[1:]
	if len(params) != 2 {
		fmt.Println("Требутся два параметра!\r Входной файл (картинка) и выходной файл (данные QR).")
		panic("Не хватает параметров!")
		//params = append(params, "qrcode.pdf")
		//params = append(params, "qrcode.jpg")
		//params = append(params, "qrcode.png")
		//params = append(params, "qrcode.txt")
	}
	inFile = params[0]
	outFile = params[1]
	return
}

func matchFileType(inFile string) string {
	buf, _ := os.ReadFile(inFile)
	kind, _ := filetype.Match(buf)
	if kind == filetype.Unknown {
		fmt.Println("Unknown file type")
		//return kind.Extension
	}
	//fmt.Printf("File type: %s. MIME: %s\n", kind.Extension, kind.MIME.Value)
	return kind.Extension
}

func decodeQR(file io.Reader) string {
	img, imgType, err := image.Decode(file)
	check(err)
	fmt.Print("Image type = ")
	fmt.Println(imgType)
	bmp, err := gozxing.NewBinaryBitmapFromImage(img)
	check(err)
	qrReader := qrcode.NewQRCodeReader()
	result, err := qrReader.Decode(bmp, nil)
	check(err)
	return result.String()
}

func decodeQRBySting(inFile string) string {
	file, err := os.Open(inFile)
	check(err)
	result := decodeQR(file)
	return result
}

func convertImageFileToPNG(inFile string, outFile string) {
	src, err := imgconv.Open(inFile)
	check(err)
	err = imgconv.Save(outFile, src, &imgconv.FormatOption{Format: imgconv.PNG})
	check(err)
	fmt.Print("Convert \"")
	fmt.Print(inFile)
	fmt.Print("\" to \"")
	fmt.Println(outFile)
}

func convertPDFtoPNG(inFile string) (fileNames []string) {

	file, err := os.Open(inFile)
	check(err)
	imgs, err := pdf.DecodeAll(file)
	check(err)

	tmpDir, err := os.MkdirTemp(os.TempDir(), "fitz_")
	check(err)

	for n, img := range imgs {
		f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.png", n)))
		check(err)
		err = png.Encode(f, img)
		check(err)

		fmt.Println(f.Name())
		fileNames = append(fileNames, f.Name())
	}

	return
}

func main() {
	inFile, outFile := getParams()

	f, err := os.Create(outFile)
	check(err)
	defer f.Close()

	var fileNames []string

	mimeType := matchFileType(inFile)
	if mimeType == "png" {
		fileNames = append(fileNames, inFile)
	} else if mimeType == "pdf" {
		fileNames = convertPDFtoPNG(inFile)
	} else {
		tempFile, err := os.CreateTemp("", "img_*.png")
		check(err)
		convertImageFileToPNG(inFile, tempFile.Name())
		fileNames = append(fileNames, tempFile.Name())
	}

	qrcode := ""

	for _, fileName := range fileNames {
		qrcode = decodeQRBySting(fileName)
		fmt.Print("QR = ")
		fmt.Println(qrcode)
		if qrcode != "" {
			break
		}
	}

	_, err = f.WriteString(qrcode)
	check(err)

	for _, fileName := range fileNames {
		os.Remove(fileName)
	}
}

Использование из 1С выглядит так
&НаСервере
Функция РаспознатьQRИзКартинкиНаСервере(ИмяФайлаКартинки)
	
	ИмяВременногоКаталога = ПолучитьИмяВременногоФайла();
	Попытка
		СоздатьКаталог(ИмяВременногоКаталога);
	Исключение
		
	КонецПопытки;
	
	ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
	ДвоичныеДанные = ОбработкаОбъект.ПолучитьМакет("gozxing");
	
	ИмяФайлаПриложения = ИмяВременногоКаталога + "\gozxing.exe";
	Попытка
		ДвоичныеДанные.Записать(ИмяФайлаПриложения);
	Исключение
		
	КонецПопытки;
	
	ИмяФайлаШтрихкода = ПолучитьИмяВременногоФайла("txt");
	
	ШаблонКоманды = "%1 %2 %3";
	СтрокаКоманды = СтрШаблон(ШаблонКоманды, ИмяФайлаПриложения, ИмяФайлаКартинки, ИмяФайлаШтрихкода);
	ТекущийКаталог = ИмяВременногоКаталога;
	ДождатьсяЗавершения = Истина;
	КодВозврата = "";
	Попытка
		ЗапуститьПриложение(СтрокаКоманды, ТекущийКаталог, ДождатьсяЗавершения, КодВозврата);
	Исключение
		
	КонецПопытки;
	
	ЧтениеТекста = Новый ЧтениеТекста(ИмяФайлаШтрихкода, КодировкаТекста.UTF8);
	Штрихкод = СокрЛП(ЧтениеТекста.Прочитать());
	ЧтениеТекста.Закрыть();
	ЧтениеТекста = Неопределено;
	
	Попытка
		УдалитьФайлы(ИмяФайлаКартинки);
	Исключение
	КонецПопытки;
	
	Попытка
		УдалитьФайлы(ИмяФайлаПриложения);
	Исключение
	КонецПопытки;
	
	Попытка
		УдалитьФайлы(ИмяВременногоКаталога);
	Исключение
	КонецПопытки;
	
	Попытка
		УдалитьФайлы(ИмяФайлаШтрихкода);
	Исключение
	КонецПопытки;
	
	Возврат Штрихкод;
	
КонецФункции
12 SpLorT
 
07.08.24
13:08
Спасибо огромное вам:) (11)
13 SpLorT
 
07.08.24
19:16
Подскажите? а что за макет gozxing у вас? я могу ведь сам макет прописать?
14 Garykom
 
гуру
07.08.24
13:30
(13) макет gozxing - это скомпилированный бинарник на Golang, исходный код которого выше
фактически это просто консольное приложение, которое запускается с двумя параметрами ИмяФайлаКартинки и ИмяТекстовогоФайлаРезультатаРаспознанногоQR

как скомпилировать
https://proglib.io/p/samouchitel-po-go-dlya-nachinayushchih-chast-3-organizaciya-koda-pakety-importy-moduli-vvod-vyvod-teksta-2023-12-07
15 SpLorT
 
07.08.24
19:16
Мне нужно что-то скачивать для этого? (13)
16 Garykom
 
гуру
07.08.24
14:12
(15) Да нужно
https://go.dev/doc/install

ну и go get скачает нужные либы с github.com

Но это только для компиляции в .exe, потом в макет прицепил .exe и больше ничего не надо
17 Garykom
 
гуру
07.08.24
14:14
На ИС есть другие примеры использования ZXing
Но там еще сложней и хуже
18 SpLorT
 
07.08.24
19:16
Понял, спасибо
Основная теорема систематики: Новые системы плодят новые проблемы.