16 12 2015
Como escanear documentos com o C#? (digitalização de documentos)
Em alguns tipos de aplicativos, o escaneamento (ou digitalização) de documentos é um pilar importantíssimo do processo de negócio. Muitas vezes a cópia de algum documento vital à aplicação precisa ser armazenado no banco de dados para que uma comprovação possa ser feita no futuro, caso necessária.
O .NET Framework, por ser uma biblioteca mais “geral“, não tem suporte nativo à digitalização de documentos. Dessa forma, precisamos recorrer a bibliotecas externas para alcançar esse resultado. No artigo de hoje, veremos como escanear documentos com o C# utilizando bibliotecas externas.
Quando falamos de digitalização de documentos, os drivers dos scanners normalmente são compatíveis com duas tecnologias (ou, nesse caso, APIs): WIA e TWAIN. Entre essas duas tecnologias, a TWAIN é a mais antiga (a primeira versão é de 1992) e mais portável (é compatível com vários sistemas operacionais). Já a WIA surgiu lá pela época do Windows 98 e, como o próprio nome diz (Windows Image Acquisition), só é compatível com o Windows.
Os scanners antigos normalmente vinham com drivers TWAIN. Eu me lembro claramente que os disquetes (!!) de instalação do primeiro scanner que eu tive há um bom tempo atrás (na época do Windows 95) mencionavam algo relacionado ao TWAIN.
Hoje em dia, praticamente todos os scanners são distribuídos com drivers compatíveis tanto com o WIA quanto com o TWAIN. Portanto, normalmente você pode escolher qualquer uma dessas duas APIs sem problema algum. Não foi o caso do meu scanner (que não funcionou com o TWAIN), mas, acredito que funcione com a grande maioria dos scanners disponíveis no mercado.
Para testarmos as duas alternativas, vamos criar um projeto do tipo “Windows Forms Application” e vamos ajustar o formulário para que ele fique parecido com a imagem a seguir:
Como você pode perceber, o formulário de testes é extremamente simples: contém apenas dois botões (chamados “wiaButton” e “twainButton“) que utilizaremos para chamar cada uma das alternativas de escaneamento.
Opção 1: WIA
A primeira opção de digitalização de documentos que iremos conferir faz uso da API WIA. Como mencionado anteriormente, essa API está disponível desde o Windows 98 e, hoje em dia, praticamente todos os scanners têm compatibilidade com ela. A dll utilizada nesse caso é a “wiaaut.dll“, localizada dentro do diretório “C:\Windows\System32“. Precisamos adicionar uma referência a essa dll no nosso projeto:
Agora, um problema que 100% dos artigos sobre WIA que eu conferi não explicam é que você tem que fazer um pequeno ajuste nessa referência. Essa dll utiliza Interop e, caso não fizermos essa alteração, não conseguiremos utilizar os tipos existentes dentro dessa dll de forma razoável (teríamos que fazer um monte de gambiarra para conseguir utilizar os tipos). Dessa forma, para conseguirmos utilizar por completo as classes dessa dll, temos que alterar a propriedade “Embed Interop Types” para false na referência à WIA:
Sabe o que acontece se não alterarmos essa propriedade na referência? Ao tentarmos executar o projeto (após termos implementado o exemplo que vou demonstrar a seguir), receberemos estes erros de compilação:
The type ‘WIA.CommonDialogClass’ has no constructors defined
Agora que já alteramos essa propriedade na referência, temos tudo o que precisamos para começar a utilizar essa API no nosso projeto de exemplo. Para isso, dê um duplo clique no botão “WIA” e adicione o seguinte código:
private void wiaButton_Click(object sender, EventArgs e) { try { var dialog = new WIA.CommonDialogClass(); var scannedImage = dialog.ShowAcquireImage(WIA.WiaDeviceType.ScannerDeviceType) as WIA.ImageFile; if (scannedImage != null) { if (System.IO.File.Exists("scanwia.png")) System.IO.File.Delete("scanwia.png"); scannedImage.SaveFile("scanwia.png"); } } catch { MessageBox.Show("Erro na digitalização do documento.", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Simples, não? Basicamente temos que criar uma nova instância da classe de diálogo WIA e chamar o método “ShowAcquireImage” passando “ScannerDeviceType” como tipo de dispositivo. O retorno será um ImageFile do WIA, que podemos utilizar para salvar o arquivo em disco. Caso você tenha somente um scanner conectado ao computador (o que eu acredito ser aproximadamente uns 95% dos casos), ao executar a aplicação e clicar no botão “WIA“, a seguinte janela será exibida:
Nessa janela você pode configurar todas as opções de digitalização do documento, fazer um preview e digitalização final. Ao clicar em “Scan“, a área selecionada será escaneada e a imagem será retornada ao aplicativo. Já no caso de o usuário clicar em “Cancel“, a imagem não será retornada e o aplicativo não fará nada, obviamente.
Mas, e se tivermos o azar de cairmos nos 5% dos usuários que têm mais de um scanner instalado no computador? Nesse caso, ao chamarmos o método “ShowAcquireImage“, o Windows exibirá um diálogo para selecionarmos o dispositivo. No exemplo abaixo só tenho um dispositivo, mas, de qualquer forma, o diálogo seria este:
Além do método “ShowAcquireImage“, note que o diálogo WIA tem diversas outras opções:
Vamos ver o que cada uma dessas outras opções faz.
ShowAcquisitionWizard:
O método “ShowAcquisitionWizard” exibe o mesmo wizard de digitalização que é exibido pelo Windows ao escanearmos algum documento pelo painel de controle:
Esse método espera um “WIA.Device” por parâmetro, que pode ser escolhido através do método “ShowSelectDevice” (mais detalhes sobre esse método logo a seguir):
WIA.Device scanner = dialog.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType, true, false); dialog.ShowAcquisitionWizard(scanner);
Apesar desse wizard ser completamente flexível, o grande problema dele é que o usuário pode escolher salvar a imagem aonde ele quiser. E, como o método não retorna nada (retorna um objeto nulo), não é possível sabermos aonde o usuário salvou o documento escaneado (ou até mesmo se ele cancelou a digitalização no meio).
ShowDeviceProperties:
Mostra a janela de propriedades do Windows para o dispositivo especificado:
WIA.Device scanner = dialog.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType, true, false); dialog.ShowDeviceProperties(scanner);
ShowItemProperties:
Mostra as propriedades de escaneamento de um dispositivo especificado:
WIA.Device scanner = dialog.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType, true, false); dialog.ShowItemProperties(scanner.Items[1]);
ShowPhotoPrintingWizard:
Não tem nada a ver com escaneamento de documentos, mas sim, com impressão de imagens. Portanto, não detalharei este método neste artigo.
ShowSelectDevice:
Exibe a janela para selecionarmos um dispositivo. É exatamente a mesma janela que mostrei alguns passos acima, que a própria API do WIA mostra automaticamente ao chamar o método “ShowAcquireImage” quando mais de um scanner está instalado no computador. O retorno desse método é um “WIA.Device” que pode ser utilizado na chamada a outros métodos (como o “ShowTransfer” – mais detalhes abaixo).
ShowSelectItems:
Não consegui entender o que esse método faz, uma vez que ele mostra a mesma janela do método “ShowAcquireImage“.
ShowTransfer:
Esse método inicializa a digitalização da página toda (ou do que tiver sido configurado anteriormente de forma manual). O legal desse método é que, como o “ShowAcquireImage“, ele também retorna um “WIA.ImageFile” apontando para a imagem escaneada. Dessa forma, podemos salvá-la aonde quisermos utilizando a mesma sistemática apresentada anteriormente neste artigo:
WIA.Device scanner = dialog.ShowSelectDevice(WIA.WiaDeviceType.ScannerDeviceType, true, false); var scannedImage = dialog.ShowTransfer(scanner.Items[1], WIA.FormatID.wiaFormatPNG) as WIA.ImageFile;
Alguns outros exemplos
Antes de partir para a explicação da API do TWAIN, eu gostaria de deixar alguns links extras para outros artigos relacionados à API do WIA. Alguns desses links foram disponibilizados por um dos inscritos da minha newsletter, o Marcello Marques (obrigado Marcello!):
– Scanning an image with C#
– An intro to WIA (Windows Image Acquisition) in C#
– Playing with the Scanner with WIA and C#
– CodeProject: WIA Scanner in C# Windows Forms (artigo muito interessante caso o seu scanner suporte a digitalização de múltiplas páginas)
– Integrate image scanning within a C# application
– WIA Scripting and .NET
Além disso, caso você precise escanear documentos no Windows Server, você precisa ativar a feature chamada “Desktop Experience“, uma vez que o WIA não é ativado por padrão no Windows Server. Essa feature também é necessária para alguns drivers do TWAIN. Confira como ativá-la neste tutorial:
Opção 2: TWAIN
A segunda API que podemos utilizar para escanearmos documentos com o C# é a TWAIN. Como mencionado anteriormente, essa API é mais antiga que a WIA e oferece suporte em outras plataformas além do Windows.
Durante as minhas pesquisas, eu encontrei diversos exemplos que utilizavam o TWAIN para digitalizar documentos com o C#:
TwainDotNet
A biblioteca TwainDotNet está disponível no GitHub e também no NuGet ao procurarmos pelo seu nome. Porém, não consegui fazer funcionar no meu computador. Só apresentava este erro:
Unable to load DLL ‘twain_32.dll’: A dynamic link library (DLL) initialization routine failed.
.NET TWAIN image scanner
O próximo exemplo que eu tentei fazer funcionar com a API do TWAIN foi este artigo do CodeProject. Curiosamente, o exemplo já compilado disponibilizado neste artigo funcionou corretamente. Consegui fazer a digitalização sem problema algum com o meu scanner. Porém, ao baixar o projeto, compilar e tentar executar, ele não funcionou mais.
NTwain
Finalmente, depois de algum tempo procurando, encontrei a biblioteca que me pareceu mais promissora para fazer digitalizações com o TWAIN em aplicativos do .NET Framework, a NTwain. Podemos adicioná-la ao nosso projeto utilizando o NuGet (procurando por “ntwain“).
Depois de instalar a biblioteca no nosso projeto, podemos dar um duplo clique no nosso botão “TWAIN” para implementar o segundo tipo de metodologia de digitalização. A inicialização da biblioteca NTwain é bem esquisita, veja só:
private void twainButton_Click(object sender, EventArgs e) { var appId = NTwain.Data.TWIdentity.CreateFromAssembly(NTwain.Data.DataGroups.Image, System.Reflection.Assembly.GetEntryAssembly()); var twain = new NTwain.TwainSession(appId); twain.Open(); var scanner = twain.FirstOrDefault(s => string.Equals(s.Name, "HP LaserJet M1130 MFP TWAIN")); scanner.Open(); }
Como você pode perceber, primeiramente temos que criar um TWIdentity, que é basicamente um “ID” de cada aplicação que está utilizando a biblioteca. Segundo a documentação, esse ID é utilizado para manter uma comunicação consistente entre as entidades da biblioteca.
Logo em seguida, criamos uma instância de TwainSession passando o ID criado no passo anterior. Com a instância de TwainSession criada, chamamos o método “Open” e encontramos o scanner desejado utilizando o método “FirstOrDefault” buscando pelo nome do scanner. Poderíamos também listar os scanners TWAIN instalados em um ComboBox (mostrarei como fazer isso num próximo passo). Encontrado o scanner, chamamos novamente o método “Open” (só que dessa vez na instância do scanner).
Com isso, estamos prontos para fazer a digitalização do nosso documento. Porém, antes disso, um detalhe importante: o resultado da digitalização ficará disponível através do evento “DataTransferred” da TwainSession. Dessa forma, antes de começarmos a escanear, temos que criar um hook para esse evento, onde faremos o processamento dos dados retornados pelo scanner e salvaremos a imagem escaneada no diretório da aplicação:
private void twain_DataTransferred(object sender, NTwain.DataTransferredEventArgs e) { Image img = null; if (e.NativeData != IntPtr.Zero) { var stream = e.GetNativeImageStream(); if (stream != null) { img = Image.FromStream(stream); } } else if (!string.IsNullOrEmpty(e.FileDataPath)) { img = new Bitmap(e.FileDataPath); } img.Save("scantwain.png", System.Drawing.Imaging.ImageFormat.Png); }
Note no código acima que a imagem é retornada através de informações disponíveis no “DataTransferredEventArgs“. A única coisa que tivemos que fazer foi processar essa imagem (que é retornada através de uma Stream ou através de um arquivo – depende do driver do scanner) e salvá-la no mesmo diretório da aplicação utilizando o nome “scantwain.png“.
Feito isso, podemos voltar ao código anterior (do clique no botão “TWAIN“) e adicionarmos três linhas: uma para fazer a ligação com esse event handler que criamos, outra chamando o método “Enable” no scanner para iniciar a digitalização e, finalmente, outra chamando o método “Close” do scanner (para liberar o scanner para outras digitalizações):
private void twainButton_Click(object sender, EventArgs e) { var appId = NTwain.Data.TWIdentity.CreateFromAssembly(NTwain.Data.DataGroups.Image, System.Reflection.Assembly.GetEntryAssembly()); var twain = new NTwain.TwainSession(appId); twain.Open(); var scanner = twain.FirstOrDefault(s => string.Equals(s.Name, "HP LaserJet M1130 MFP TWAIN")); scanner.Open(); twain.DataTransferred += twain_DataTransferred; scanner.Enable(NTwain.SourceEnableMode.NoUI, true, this.Handle); scanner.Close(); }
Repare que, na chamada do método “Enable“, temos algumas opções no enum “SourceEnableMode“:
NoUI: faz o processo de digitalização da página toda (ou do que estiver configurado na variável “scanner“) sem mostrar a interface do driver do scanner (mostra somente a barra de progresso da digitalização)
ShowUI: mostra a janela de digitalização do driver do scanner, onde você pode fazer um preview e a digitalização final (ou cancelar a operação)
ShowUIOnly: mostra a janela de digitalização do driver, só que sem as opções de digitalização (a ideia é que essa opção possibilita a configuração das opções da digitalização, aí você poderia chamar novamente o método “Enable” com a opção “NoUI” para fazer a digitalização final)
Para você ter uma ideia melhor do que estou falando, esta é a barra de progresso mostrada quando escolhemos a opção “NoUI“:
E esta é a tela de aquisição que é exibida quando escolhemos a opção “ShowUI” (essa é a tela do driver do meu scanner – com o seu scanner pode ser que a tela seja um pouco diferente):
Ao executarmos a aplicação e clicarmos no botão “TWAIN“, o scanner deve realizar a digitalização. Ao finalizar o escaneamento, o evento “DataTransferred” será disparado e a imagem será salva em disco. Isso é, se a biblioteca realmente funcionar com o driver do seu scanner. Como eu disse anteriormente, ela não funcionou com o meu scanner (se você quiser acompanhar, eu reportei o bug na página da biblioteca), portanto, antes de utilizar em produção, eu sugiro que você teste extensivamente essa opção.
Finalmente, antes de compararmos as duas bibliotecas, vou mostrar como podemos adicionar um ComboBox para selecionarmos o scanner com a opção “TWAIN“. Primeiramente, adicione um ComboBox do lado do botão “TWAIN” (com o nome de “scannerTwainComboBox“):
Feito isso, vamos voltar ao code-behind do formulário e vamos extrair o código de inicialização do scanner em um método chamado “InicializarTwain“. Fazemos isso porque não sabemos ao certo quando teremos que inicializar o TWAIN (no momento em que o usuário abrir o ComboBox ou no momento que ele clicar em “TWAIN“, caso não tenha escolhido nenhum scanner especificamente):
NTwain.Data.TWIdentity appId = null; NTwain.TwainSession twain = null; bool twainJaFoiInicializado = false; private void InicializarTwain() { appId = NTwain.Data.TWIdentity.CreateFromAssembly(NTwain.Data.DataGroups.Image, System.Reflection.Assembly.GetEntryAssembly()); twain = new NTwain.TwainSession(appId); twain.Open(); twain.DataTransferred += twain_DataTransferred; twainJaFoiInicializado = true; }
Em seguida, vamos adicionar um handler para o evento “DropDown” do “scannerTwainComboBox“. Esse é o evento que é disparado quando o usuário abre o ComboBox. Nesse ponto, caso o usuário esteja abrindo o ComboBox pela primeira vez, temos que carregá-lo com os scanners disponíveis:
private void scannerTwainComboBox_DropDown(object sender, EventArgs e) { if (!twainJaFoiInicializado) { InicializarTwain(); foreach (var scanner in twain) { scannerTwainComboBox.Items.Add(scanner.Name); } } }
Finalmente, a única coisa que falta é ajustarmos o handler do clique do botão “TWAIN” para considerar o scanner que foi selecionado no ComboBox. Caso o usuário não tenha selecionado nenhum scanner, vamos considerar o primeiro scanner disponível:
private void twainButton_Click(object sender, EventArgs e) { if (!twainJaFoiInicializado) InicializarTwain(); NTwain.DataSource scanner; if (scannerTwainComboBox.SelectedItem != null && !string.IsNullOrWhiteSpace(scannerTwainComboBox.SelectedItem.ToString())) scanner = twain.FirstOrDefault(s => string.Equals(s.Name, scannerTwainComboBox.SelectedItem)); else scanner = twain.FirstOrDefault(); scanner.Open(); scanner.Enable(NTwain.SourceEnableMode.NoUI, true, this.Handle); scanner.Close(); }
Pronto! Execute a aplicação e veja que é possível selecionarmos no ComboBox o scanner que queremos utilizar para fazer a digitalização:
Somente um último detalhe: para utilizar o TWAIN, sua aplicação precisa ser compilada em x86 (e não Any CPU). Caso contrário, você provavelmente receberá este erro:
An unhandled exception of type ‘System.BadImageFormatException’ occurred in NTwain.dll – Additional information: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
Portanto, não esqueça de alterar a arquitetura de compilação para x86 no seu projeto:
Qual é a melhor opção?
Agora que você já viu como funcionam as duas opções de digitalização de documentos com o C#, você deve estar se perguntando: qual é a melhor opção?
Na minha opinião, entre essas duas APIs, a mais fácil de ser utilizada é a WIA. Os métodos expostos por essa API são bem mais claros que a metodologia utilizada pelo TWAIN. Por outro lado, a API do TWAIN possibilita uma maior customização da digitalização e configurações do scanner, além de teoricamente ser suportada em outras arquiteturas além do Windows.
Dessa forma, a minha sugestão é que, caso você simplesmente queira fazer uma simples digitalização no seu aplicativo, utilize WIA. Porém, se você tiver que fazer várias customizações nas configurações do seu scanner, ou se você tiver que se aventurar em outra plataforma que não seja o Windows (como, por exemplo, no Linux com o Mono), talvez o TWAIN seja a melhor opção para você. Só confira se o driver do seu scanner realmente funciona com as bibliotecas disponíveis (porque, como eu comentei anteriormente, o driver do meu scanner não funcionou).
Concluindo
Neste artigo você aprendeu a escanear documentos com o C# através das APIs WIA e TWAIN. Precisamos utilizar bibliotecas externas para ambas as opções, uma vez que o .NET Framework não possui suporte nativo à digitalização de documentos.
Por fim, você conferiu a minha opinião sobre qual das opções utilizar em cada situação. Agora lanço uma pergunta: você já precisou escanear documentos nos seus aplicativos desenvolvidos com o .NET Framework? Se sim, qual API você utilizou? WIA, TWAIN ou alguma outra API que eu não encontrei nas minhas pesquisas? E, se você ainda não precisou digitalizar documentos nos seus aplicativos, será que não seria interessante implementar essa funcionalidade? Deixe a sua resposta nos comentários!
Antes de me despedir, convido você a inscrever-se na minha newsletter. Ao fazer isso, você receberá um e-mail toda semana sobre o artigo publicado, ficará sabendo em primeira mão sobre o artigo da próxima semana e receberá também dicas “bônus” que eu só compartilho por e-mail. Além disso, você já deve ter percebido que eu recebo muitas sugestões de temas e eu costumo dar prioridade às sugestões vindas de inscritos da minha newsletter. Inscreva-se utilizando o formulário logo abaixo.
Até a próxima!
André Lima
Image by Pete used under Creative Commons
https://www.flickr.com/photos/comedynose/10044151066
Dica rápida: Avaliando parâmetros de saída com PrivateObject Nos vemos em 2016!
Se puder ampliar o artigo nas multiplas folhas e frente e verso ficaria perfeito, no demais muito bom
Olá Saulo!
Obrigado pelo comentário! Vou colocar sua sugestão na minha lista de tópicos para o futuro..
Abraço!
André Lima
Também tenho interesse em ver como funciona com múltiplas folhas!
Valeu!
Beleza, Nelson! Anotei aqui também..
Abraço!
André Lima
Muito bom o artigo, vlw por passar seu conhecimento.
Olá Luiz Filipe, obrigado pelo comentário!
Caso fique com alguma dúvida durante o processo, entre em contato..
Abraço!
André Lima
Tô quase dominando rsrsrs. Como eu poderia fazer para capturar a imagem do dialog e mandar para direto para um picturebox na minha aplicação?
Olá Marcelo, obrigado pelo comentário!
Pelo que vi, ambas as APIs só possibilitam que o arquivo seja salvo em algum lugar.. Ou seja, não consegui encontrar nenhum método que retornasse uma Stream que eu pudesse utilizar sem salvar o arquivo em disco..
Nesse caso, eu sugiro que você salve a imagem temporariamente no diretório temporário do Windows e delete-a assim que tiver terminado de processá-la (ou assim que tiver armazenado ela em uma Stream ou no banco)..
Abraço!
André Lima
Muito bom André! Nunca precisei implementar um aplicativo de scan e é bom saber aonde encontrar uma referência. Obrigado e abraços!
Olá Guilherme, obrigado pelo comentário!
Fico feliz que você tenha gostado do artigo..
Abraço!
André Lima
Olá André,
estou usando seu código como exemplo, porém não consigo executar o evento twain_DataTransferred, mesmo colocando break point, o sistema não passa por esse evento, estaria faltando alguma coisa?
twain.DataTransferred += twain_DataTransferred;
Olá, tudo tranquilo?
Eu também tive o mesmo problema.. Até mencionei no artigo que com o meu scanner o TWAIN não funcionou 100%.. Foi justamente o mesmo erro que aconteceu comigo.. Aparentemente é um problema no driver TWAIN do meu scanner (e do seu também?).. Eu abri um “issue” no site da biblioteca, mas, ninguém conseguiu me ajudar.. Talvez se você “ressuscitar” a thread lá no site da biblioteca alguém consiga nos ajudar com esse problema:
NTwain – Scanning gets stuck at “Busy…”
Abraço!
André Lima
humm.. que coisa!
eu utilizo o drive twain em uma aplicação, mas ele ocorre um erro quando sanneio mts páginas, por isso estou tentando outra solução, e vi seu post que usava essa biblioteca..
Olá!
Hmm, entendi.. Você já pensou em utilizar o WIA ao invés do TWAIN? O seu scanner suporta WIA? Ele é bem mais fácil de trabalhar do que o TWAIN..
Abraço!
André Lima
Ola, tem como utilizar em WebForm? É o mesmo conceito?
Olá Ulisses!
Utilizando essas mesmas bibliotecas, com certeza não dá.. Você teria que procurar alguma alternativa para escanear documentos via HTML5 ou Javascript.. Pesquisei rapidamente aqui e só encontrei bibliotecas comerciais, como estas aqui (que, a propósito, são o olho da cara):
Leadtools HTML5 TWAIN Scanning SDK Technology
Scanner.js
Dynamic Web TWAIN HTML5 Scanner SDK
Algo que eu analisaria é se realmente faz sentido a sua aplicação toda ser web forms.. Ter o requisito de acessar o scanner é um alto indicativo que a sua aplicação não deveria ser 100% web.. Mas, aí só analisando o projeto mesmo para ter certeza..
Abraço!
André Lima
Ótimo artigo, simplesmente demais!
acredito ter seguido corretamente os passos, inclusive consigo acionar o scanner e iniciar o scaneamento. Porém não consigo salvar esta imagem, ja coloquei até um caminho especifico…
debugando percebi que ele não aciona o evento twain_DataTransferred.
o que pode ser? estou sem idéias
Olá Henrique, obrigado pelo comentário!
Como eu mencionei no meio do artigo, esse problema aconteceu comigo e eu até reportei ele no site da biblioteca:
Aparentemente alguns scanners não implementam o TWAIN 100% corretamente, aí temos esse problema com a biblioteca.. Nesse caso, eu sugeriria que você utilizasse o WIA ao invés do TWAIN, se for possível..
Abraço!
André Lima
Ops, desculpe na correria não me atentei…
parti para o WIA mesmo, porém segui diversos tutoriais e ainda não consegui refinar meu prototipo.
se eu utilizo “ShowAcquireImage” tenho obrigatoriamente que clicar no botão vizualizar na interface antes de digitalizar. Como se eu tivesse que inicializar as propriedades do WIA ou algo assim, e o vizualizar acaba resolvendo, mas fica bem feio rs.
aconteceu com você ?
a outra coisa é que se utilizo o “ShowTransfer” pra controlar eu mesmo, ele me da algum erro indicando que o scanner talvez possa estar ocupado…
acredito que possa ser o mesmo caso de precisar “inicializar” de alguma forma. realmente não sei o que fazer.
se tiver alguma luz, ou um exemplo funcional me ajudaria muito!
estou sem tempo, mas com certeza adiante pretendo construir uma API Como a do NTwain e compartilho com todos vocÊs.
Olá Henrique!
Aqui não tive problema.. Com o ShowAcquireImage, se eu clico direto no “Scan” (sem clicar no “Preview”), ele funciona normal.. E com o ShowTransfer também funcionou sem problema algum, escaneando a página toda.. Qual é exatamente a mensagem de erro que você está recebendo ao utilizar o “ShowTransfer”?
Abraço!
André Lima
Bom dia!
Com o ShowAcquireImage, se vou direto em Scan/Digitalizar
obtenho a seguinte mensagem:
“erro ao definir as propriedades do scanner. se outro programa estiver digitalizando, aguarde a conclusão e tente novamente.”
Já o ShowTransfer,abre a tela pra escolher o scaner e após escolher escapa do try e exibe a mensagem de erro do exemplo.
cheguei a pegar a exceção do try/catch:
“Error: O valor não recai no intervalo esperado.”
poderia me enviar o exemplo de teste que fez ai? c.mendesoliveira@icloud.com
to empacado aqui =/
Muito obrigado pelo breve retorno!
Olá Henrique! Que estranho.. Aqui com o meu scanner funcionou 100% utilizando exatamente o código que eu apresentei no artigo.. Vai entender..
Abraço!
André Lima
Amigo, ta tranquilo. Consegui resolver de outra forma.
Se precisar usar o Twain, ele é mais bonito e tem um exemplo bem completo funcionando aqui:
https://sourceforge.net/projects/twainforcsharp/
Obrigado por compartilhar seu conhecimento.
Olá novamente Henrique! Muito obrigado pela indicação! Vou dar uma olhada nessa biblioteca depois e, assim que possível, faço uma edição no artigo complementando com essa opção também..
Abraço!
André Lima
A API WIA também funciona para webcam?
Olá Felipe!
Sim, a API do WIA também funciona para tirar fotos com a webcam.. Esse é um assunto que está na minha lista para escrever um artigo mais pra frente.. Veja os links que eu encontrei quando pesquisei sobre isso:
WebCam Fast Image Capture Service using WIA
Catch a Snapshot via your webcam using C#
Take a picture automatically using a webcam in C# using WIA
Abraço!
André Lima
olá, usando o NTwain, se tiverem o problema que eu tive que foi pra identificar o nome da impressora, eu consegui ver o nome que o sistema pega usando esse comando:
var listarScanner = twain.ToList();
//antes da linha
var scanner = twain.FirstOrDefault(s => string.Equals(s.Name, “WIA-HP-ASSISTENCIA (HP LaserJet P”));
Olá Deivid!
Muito obrigado pela dica.. Com certeza vai ajudar outras pessoas que passarem por essa dificuldade..
Abraço!
André Lima