Uma vez, em um dos projetos, uma impressora fiscal caiu em minhas mãos. Todos os dias encontramos esses dispositivos quando fazemos pagamentos nas lojas, mas poucas pessoas percebem o que realmente são. Não vou entrar em detalhes do trabalho deles, apenas direi que essas são as coisas que imprimem recibos com dados de compra em papel térmico especial (sim, quase todas as impressoras fiscais não têm tinta!).
Eu tive que descobrir como obter o estado de funcionamento da impressora fiscal e suas configurações internas. A tarefa já foi concluída e a impressora fiscal foi abandonada por um longo tempo no canto oposto ... Até que tive a ideia de recriar um pouco: D
Essas impressoras permitem imprimir imagens monocromáticas. Quando eu tinha impressões suficientes de selos, emblemas e fotografias de colegas, decidi acenar para a impressão de uma
longa tapeçaria baseada na série em que eles matavam constantemente alguém com as palavras “o inverno está próximo” .
A saída foi um vídeo:
Etapas detalhadas para imprimir uma tapeçaria em
python sob o gato abaixo.
Neste artigo, descreverei brevemente o procedimento com comentários detalhados, assumindo que o resultado será um artigo de treinamento com várias habilidades práticas úteis:
- baixe o vídeo de tapeçaria do youtube
- crie uma imagem longa de tapeçaria monocromática para impressão em uma impressora fiscal
- conectar à impressora fiscal
- imprimir uma tapeçaria em uma impressora fiscal
- montamos o videoclipe resultante para publicação nas redes sociais
Baixe o vídeo de tapeçaria do youtube
Isso é feito de forma muito simples, usando a biblioteca
pytube , você só precisa determinar o índice do fluxo de vídeo que deseja baixar.
Função para baixar vídeos do youtube:import time, pytube
Quando a linha
for stream in streams: print(stream)
é executada, vemos no console uma lista de todos os fluxos de vídeo contidos no vídeo:
<Stream: itag = "22" mime_type = "video / mp4" res = "720p" fps = "30fps" vcodec = "avc1.64001F" acodec = "mp4a.40.2">
<Stream: itag = "43" mime_type = "video / webm" res = "360p" fps = "30fps" vcodec = "vp8.0" acodec = "vorbis">
<Stream: itag = "18" mime_type = "video / mp4" res = "360p" fps = "30fps" vcodec = "avc1.42001E" acodec = "mp4a.40.2">
<Stream: itag = "137" mime_type = "video / mp4" res = "1080p" fps = "30fps" vcodec = "avc1.640028">
<Stream: itag = "248" mime_type = "video / webm" res = "1080p" fps = "30fps" vcodec = "vp9">
<Stream: itag = "136" mime_type = "video / mp4" res = "720p" fps = "30fps" vcodec = "avc1.4d401f">
<Stream: itag = "247" mime_type = "video / webm" res = "720p" fps = "30fps" vcodec = "vp9">
<Stream: itag = "135" mime_type = "video / mp4" res = "480p" fps = "30fps" vcodec = "avc1.4d401e">
<Stream: itag = "244" mime_type = "video / webm" res = "480p" fps = "30fps" vcodec = "vp9">
<Stream: itag = "134" mime_type = "video / mp4" res = "360p" fps = "30fps" vcodec = "avc1.4d401e">
<Stream: itag = "243" mime_type = "video / webm" res = "360p" fps = "30fps" vcodec = "vp9">
<Stream: itag = "133" mime_type = "video / mp4" res = "240p" fps = "30fps" vcodec = "avc1.4d4015">
<Stream: itag = "242" mime_type = "video / webm" res = "240p" fps = "30fps" vcodec = "vp9">
<Stream: itag = "160" mime_type = "video / mp4" res = "144p" fps = "30fps" vcodec = "avc1.4d400c">
<Stream: itag = "278" mime_type = "video / webm" res = "144p" fps = "30fps" vcodec = "vp9">
<Stream: itag = "140" mime_type = "audio / mp4" abr = "128kbps" acodec = "mp4a.40.2">
<Stream: itag = "249" mime_type = "audio / webm" abr = "50kbps" acodec = "opus">
<Stream: itag = "250" mime_type = "audio / webm" abr = "70kbps" acodec = "opus">
<Stream: itag = "251" mime_type = "audio / webm" abr = "160kbps" acodec = "opus">
Selecionei thread com o ID 18 porque é uma resolução pequena - ainda a imprimimos em uma fita adesiva e fazemos o download mais rápido))
Crie uma imagem longa de tapeçaria monocromática para impressão em uma impressora fiscal
Para o processamento de vídeo, precisamos da conhecida biblioteca
OpenCV e
Pillow (um fork moderno do PIL) (embora aqui, em vez do OpenCV, seja possível usar o utilitário
avconv da ferramenta
libav , mais sobre ele na última seção deste artigo). Muito obrigado ao autor por escrever python ou
python-opencv , que é uma roda python, instalada via PIP e não requer a instalação do próprio OpenCV (
hooray! ).
Uma impressora fiscal pode imprimir apenas imagens especiais - arquivos bmp monocromáticos com largura fixa de 528 pixels (mas com tamanho ilimitado, ho-ho-ho!). Além disso, a imagem da tapeçaria no videoclipe está em constante movimento; portanto, precisamos cortar cuidadosamente os quadros para obter uma imagem longa.
Tudo isso é feito pela seguinte função: import os, cv2, numpy as np from PIL import Image
Na saída, obtemos uma imagem longa com a imagem de toda a tapeçaria, apenas um fragmento é mostrado abaixo, a imagem original tem uma largura de 55.000 pixels e não passa de acordo com as regras de publicação:

Mas essa imagem é obtida após transformações monocromáticas, apenas sem rotação:

Imprimimos uma tapeçaria em uma impressora fiscal
Tenho uma impressora fiscal específica do modelo Atol fprint-22 à minha disposição, mas as regras gerais se aplicam a outros modelos de impressoras fiscais. Além disso, meu livro fiscal é bastante antigo e ainda não suporta os novos requisitos da FZ-54 (lembro-me de que, após a entrada em vigor desta lei, todos os fiscais foram obrigados a enviar dados através do OFD à administração fiscal, o que implicava dor e sofrimento - uma piscada em cada dispositivo).
Uma pequena digressão sobre impressoras fiscais. Eles se relacionam com dispositivos de ponto de venda - são todos os tipos de periféricos para as necessidades comerciais, que são conectados a um PC e integrados a um único sistema de contabilidade e pagamento. Desses dispositivos bem conhecidos, você definitivamente viu scanners de código de barras e terminais de pagamento com cartão de crédito. Para todos esses dispositivos, um protocolo de interação UnifiedPOS unificado foi inventado.
Em resumo, este é um tópico separado e um círculo muito restrito de especialistas envolvidos em dispositivos POS. A situação é complicada pelo fato de a maioria desses dispositivos serem projetados para operação exclusivamente no Windows por meio de objetos COM - arquivos dll com uma descrição documental muito pobre da funcionalidade. Embora tenha ouvido falar sobre os sistemas de caixa em funcionamento no FreeBSD, não vi nada parecido ao trabalhar com dispositivos POS, felizmente, não precisava de uma imersão detalhada no mundo dos processos de negócios de PDVs de varejo ...
Portanto, o procedimento para trabalhar com a maioria desses dispositivos é o seguinte:
- driver é instalado do fabricante
- a conexão ao dispositivo através do utilitário do fabricante está configurada
- procurando a chave de registro desejada com o dispositivo desejado
- procurando as configurações necessárias para conectar-se a ele
(a maioria trabalha na interface de software serial RS-232) - conectar ao dispositivo através do objeto COM do driver do fabricante
- trabalhando com o dispositivo através do objeto COM da API
- Objeto COM e porta física do dispositivo são liberados
( ponto importante )
Como tenho um livro fiscal antigo à minha disposição, o driver é usado especificamente para a 8ª versão. Agora, o fabricante adicionou um driver da 10ª versão, que simplifica bastante o trabalho com uma impressora fiscal por meio de um módulo wrapper python separado, o que é uma boa notícia.
O código a seguir demonstra uma função que se conecta a uma impressora fiscal usando o algoritmo descrito acima, produz um sinal sonoro e imprime a imagem monocromática de tapeçaria obtida anteriormente. Precisamos instalar o
pywin32 .
O código acabou sendo bastante longo e chato, então eu o coloquei sob o spoiler: import win32com.client from _winreg import HKEY_CURRENT_USER, OpenKey, EnumValue
O resultado foi um manuscrito, uma performance em "A Song of Ice and Fire":

No final, a impressora uivou completamente, imprimiu lenta e vagamente e depois finalizou completamente a impressão apenas da cena final - nenhuma impressora fiscal jamais viu essa carga: D
Resta preparar o vídeo e postar na rede social. Como uma
série de áudio
, encontrei uma
composição amadora na rede de
8 bits - o tema do título da série . A idéia era sobrepor-se sem usar um editor de vídeo, escreverei sobre isso mais adiante na parte final do artigo.
Montamos o videoclipe resultante para publicação nas redes sociais
Para esses propósitos, existe uma ferramenta de console muito útil e poderosa que substitui todo o editor de vídeo - libav . Inclui os utilitários avconf e ffmpeg para trabalhar com arquivos de vídeo e áudio. Honestamente, para mim essa ferramenta foi uma descoberta real, recomendo a todos!
A ideia básica de instalação:
- cortar a partir do vídeo gravado na parte do smartphone no início e parte no final
(para caber arquivo mp3 com música de 8 bits por 3 execuções) - gravar 3 perdas de arquivos de áudio em um arquivo
- sobrepor arquivo de vídeo e arquivo de áudio em um novo arquivo de vídeo
- converter arquivo de vídeo do formato mov para o formato mp4
(meu smartphone grava vídeos com a extensão mov)
Para esses propósitos, escrevi um script para rodar na linha de comando, que pode ser executada tanto no bash no linux quanto no bat in win (as diferenças são indicadas nos comentários do script): # avconv -ss 00:00:10 -i got_print.mov -t 00:06:00 -c:v copy got_print_tmp.mov # ( win) (echo file 'got_8bit.mp3' & echo file 'got_8bit.mp3' & echo file 'got_8bit.mp3') > list.txt # ( linux) # cat list.txt # file 'got_8bit.mp3' # file 'got_8bit.mp3' # file 'got_8bit.mp3' # 3 ffmpeg -f concat -i list.txt -acodec copy got_8bit_3.mp3 # avconv -i got_print_tmp.mov -i got_8bit_3.mp3 -c copy got_print_final.mov # mp4 avconv -i got_print_final.mov -c:v libx264 got_print_final.mp4 # (windows) del got_8bit_3.mp3 del got_print_tmp.mov # (linux) # rm got_8bit_3.mp3 # rm got_print_tmp.mov
Isso é tudo, o vídeo é criado:
PS: meu primeiro artigo sobre Habr, planejava escrever um pequeno artigo para começar, cortar o máximo que pude) Espero que a leitura tenha sido agradável e o resultado do meu trabalho - interessante)