Mostrando postagens com marcador componentes. Mostrar todas as postagens
Mostrando postagens com marcador componentes. Mostrar todas as postagens

Converter PDF em Imagem em C# com GhostScript

Esse é um artigo bem old, mas que muita gente me enviou e-mails pedindo como fazer isso. Então criei um artigo bem resumido baseado no de Lord TaGoH. Primeiramente, você precisa ter a DLL do GhostScript em seu projeto: ou você instala ou pega de alguém que já tenha instalado. O arquivo que me refiro é o gsdll32.dll. Obs: a conversão só funciona para as versões mais recentes então pegue alguma a partir da versão 9 como garantia.

Lembra do meu último post de scaneamento? Adicionei um botão de anexar um PDF e converter em imagem, então irei aproveitar a mesma aplicação adicionando essa funcionalidade. Copie a DLL para seu projeto e, em Propriedades, deixe configurado o atributo Copiar sempre para quando for compilá-la caso seja um Windows Form. Se for um Web Form, adicione em algum local onde a classe conversora possa encontrá-la.


Na página do CodeProject dispõe de uma classe (binária) já pronta para uso uso da DLL chamada de PdfToImage. Então você podem baixar de  ou aqui. Baixado a DLL, você pode adicionar como referência ao seu projeto/página. Agora é só código...

using PdfToImage;

// Objeto de conversão
PDFConvert converter = new PDFConvert();

// Arquivo PDF selecionado de um OpenFileDialog
string arquivo = FileUploadSelect.FileName;

// Local de saída do arquivo convertido
string output = _directoryForImages + "LJ_" + _loja + "_Scan_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".jpg";

// Configurações de conversão
converter.OutputToMultipleFile = false;
converter.TextAlphaBit = 4;
converter.FirstPageToConvert = 1;
converter.LastPageToConvert = 1;
converter.FitPage = false;
converter.JPEGQuality = 10;
converter.OutputFormat = "png16m";

// Faz a conversão e retorna true se estiver tudo OK
bool resultado = converter.Convert(arquivo, output);

Pronto! Mais fácil do que isso impossível. Fique atento às configurações de conversão, senão não funciona.

Scanear um documento com C#

Um dos melhores componentes de scaneamento que já utilizei é o da VintaSoft. Ele não é free, mas pode ser utilizado normalmente. O único empecilho é que, para cada scan que fizer, ele irá solicitar que clique em Evaluate. Quem comprar, vale a pena pois é muito bom e seu suporte sempre está a disposição. Chega de elogios e vamos ao que interessa.

O componente permite tanto utilizar em Windows Form quando Web Form e no site há todos os exemplos necessários. Baixe o componente e instale. Para nosso exemplo, trabalharemos com um Windows Form. Fiz uma pequena aplicação de scanear nota fiscal.


Vá na pasta de instalação do componente, copie o arquivo Vintasoft.Twain.dll para sua aplicação e adicione como referência. No Code-Behind do formulário a ser trabalhado, adicione o seguinte código para inicializar o componente:

using Vintasoft.Twain;


// Carrega o gerenciador de dispositivo
DeviceManager _deviceManager = new DeviceManager();
Device _device;


// Avalia se é um dispositivo útil
if (!_deviceManager.IsTwainAvailable)
{
           MessageBox.Show("Não é um dispositivo TWAIN!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
           return;
}


try
{
           // Abre o gerenciador de dispositivo
           _deviceManager.Open();
           // Seta o dispositivo corrente
           _device = _deviceManager.Devices.Current;
           lblDipositivo.Text = _deviceManager.Devices.Current.Info.ProductName;
}
catch (TwainDeviceManagerException ex)
{
           MessageBox.Show(ex.Message, "Gerenciador de Dispositivos");
           return;
}


Agora, ao clicar no botão Scannear, adicionamos o seguinte método:

private void btnScanear_Click(object sender, EventArgs e)
        {
            try
            {
                // Seta as configurações
                _device.TransferMode = TransferMode.File;
                try
                {
                    _device.ShowUI = false;
                    _device.ShowIndicators = false;
                    _device.DisableAfterAcquire = true;
                }
                catch { }


                // Abre o dispositivo
                _device.Open();


                // Propriedades do scaneamento
                try
                {
                    _device.UnitOfMeasure = UnitOfMeasure.Inches;
                    _device.Resolution = new Resolution(float.Parse(resolucaoX.SelectedItem.ToString()), float.Parse(resolucaoY.SelectedItem.ToString()));
                }
                catch { }


                // Informação sobre o arquivo
                _arquivo = "LJ_" + _loja + "_Scan_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".jpg";
                _device.FileName = _directoryForImages + _arquivo;
                //_device.FileFormat = TwainImageFileFormat.Jpeg;


                // Captura a imagem
                AcquireModalState acquireModalState = AcquireModalState.None;
                do
                {
                    acquireModalState = _device.AcquireModal();
                    switch (acquireModalState)
                    {
                        case AcquireModalState.ImageAcquired:


                            _device.FileName = _directoryForImages + _arquivo;
                            //_device.FileFormat = TwainImageFileFormat.Jpeg;
                            break;


                        case AcquireModalState.ScanCompleted:


                            CloseDevice();


                            break;


                        case AcquireModalState.ScanCanceled:


                            CloseDevice();


                            break;


                        case AcquireModalState.ScanFailed:


                            CloseDevice();


                            break;


                        case AcquireModalState.UserInterfaceClosed:


                            CloseDevice();


                            break;
                    }
                }
                while (acquireModalState != AcquireModalState.None);
            }
            catch (TwainException ex)
            {
                MessageBox.Show(ex.Message + " - " + ex.StackTrace, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }


E outros métodos são necessários adicionar ao form, como:



        /// Fecha o dispositivo e a gerência

        private void CloseDeviceAndDeviceManager()
        {
            // Verifica de há dispositivo
            if (_device != null)
            {
                if (_device.State != DeviceState.Closed)
                    _device.Close();
            }


            // Fecha a gerência
            if (_deviceManager.State != DeviceManagerState.Closed)
                _deviceManager.Close();
        }




        /// Fecha o dispositivo

        private void CloseDevice()
        {
            // Desabilita o serviço
            if (_device.State == DeviceState.Enabled)
            {
                if (!_device.ShowUI)
                    _device.Disable();
            }


            // Fecha
            if (_device.State == DeviceState.Opened)
                _device.Close();
        }




        /// Ao fechar o formulário, libera o uso

        private void Scan_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_device != null)
            {
                // Verifica se está em uso
                if (_device.State == DeviceState.Transferring ||
                    _device.State == DeviceState.TransferReady)
                {
                    // Envia a solicitação de cancelamento
                    _device.CancelTransfer();
                    // Aguarda finalizar
                    e.Cancel = true;
                    MessageBox.Show("O dispositivo está em uso! Aguarde alguns instantes enquanto é solicitado a liberação do scanner.", "Informação");
                    return;
                }
            }


            // Fecha o dispositivo e a gerência
            CloseDeviceAndDeviceManager();
        }

Pronto! O scaneamento é realizado e é gerado um arquivo JPG. Reparem que está comentado o atributo _device.FileFormat porque nem todo scanner dá a possibilidade de configuração. Alguns aceitam e outros não. Se utilizar alguma configuração que o scanner não suporta, deve aparecer a mensagem: "Failed to get/get to capability". Então você precisa deixar apenas as configurações que o scanner suporte.
Bons scans!

Recortando uma Imagem em Tempo de Execução (Image Crop) em C#

Lembram do post de Redimensionar Imagem? Esse post será bem similar e explicarei em poucas palavras o que ele faz. O que é Crop? Segundo a WikipediaCrop (Recorte) refere-se à remoção da parte exterior de uma imagem para melhorar o seu enquadramento. Um exemplo mais entendível: temos uma galeria de fotos nas quais todas as imagens possuem largura e altura diferentes que não são proporcionais; o redimensionamento de imagem para gerar um thumb não irá funcionar pois o produto final ou ficará distorcido ou não ficarão com tamanhos iguais. É aí que o recorte entra...

Veja o exemplo abaixo (retirado da Wikipedia):
No caso em questão era desejado obter um thumb quadrado da imagem. O enquadramento desejado não é proporcional à image original, logo é feito o recorte.

Dessa vez não irei colocar o código pois é um pouco grandinho, mas, como disse, é bem similar ao código do post de Redimensionar Imagem bem como seu uso (em forma de handler.ashx). Esse código é bem velhinho e não é meu. Ele está aí na net a muito tempo e já o vi em vários blogs e artigos. A última vez que o vi estava no subversion de Assembla.

Logo, baixem aqui e usem-o como desejar.

Utilizando mensagem de confirmação e executando código de acordo com o que foi clicado na mesma página

Não sei se o título ficou claro com o que eu queria dizer, mas vejamos a seguinte situação:
"Quero colocar uma mensagem de confirmação via code-behind onde irá ser emitida para o usuário e a depender do que ele escolher irá ser processado um certo trecho de código ou outro. Tipo o confirm do JavaScript, só que é executado pelo ASP.NET."

No Code Project tem várias formas de implementação e umas delas me chamou a atenção: o de Yavuz Kucukpetek. Usando AJAX é possível transformar um Panel nessa janela flutuante usando o ModalPopupExtender. Dei uma simplificada no código dele (já informei que não fiz, apenas ajustei) e você podem baixar o controle modificado aqui.

Depois que baixarem o controle, adicione no seu projeto. Vamos lá! Na página que deseja utilizar o controle, registre-o e coloque-o da seguinte forma:

<%@ Register Src="~/inc_ConfirmMessage.ascx" TagName="ConfirmacaoBox" TagPrefix="Thiago" %>


<Thiago:ConfirmacaoBox ID="ConfirmacaoBox" runat="server"></Thiago:ConfirmacaoBox>

No code-behind deverá ficar o seguinte:


    protected void Page_Load(object sender, EventArgs e)
    {
        ConfirmacaoBox.MsgBoxAnswered += Mensagem_Resposta;
    }



    public void Mensagem_Resposta(object sender, inc_ConfirmMessage.MsgBoxEventArgs e)
    {
        if (e.Answer == inc_ConfirmMessage.enmAnswer.OK)
        {
            // Se clicou em OK processa o que deseja
        }
        else
        {
            // Senão processa outra coisa
        }
    }



    protected void ExecutaProcesso_Click(object sender, EventArgs e)
    {
        ConfirmacaoBox.AddMessage("Deseja continuar o cálculo do processo na mesma página?", inc_ConfirmMessage.enmMessageType.Attention, true, true, "");
    }

Pronto! Apenas isso... Vamos às explicações. No Page_Load precisamos informar o método que irá gerenciar as decisões do usuário, por isso informamos o Mensagem_Resposta. Dentro dele irá conter os processos que irão ser executados a depender da escolha. O ExecutaProcesso_Click é o método executado quando clicamos no botão que irá disparar a pergunta.

"Ah Thiago, mas aí é só apenas uma confirmação. E se eu quiser várias interações?"

Simples, basta adicionar outra Caixa de Confirmação para a segunda etapa de decisões chamando-a dentro do processo de decisão da primeira e assim por diante.

Convertendo HTML em PDF

Nesse artigo veremos como converter um HTML em PDF. O HTML pode vir de uma página externa quanto ser criado em tempo de execução. Não haverá muito o que explicar pois o código em si, você encontra a rodo pela net. Usaremos o componente iTextSharp.

Baixe o binário e adicione em seu aplicativo (pasta Bin). Utilize o código abaixo para fazer o processo de conversão e exibição do PDF na tela:


using System;
using System.Web;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html.simpleparser;


            // Captura ou atribui o HTML a ser convertido - no caso estou baixando de uma URL
            string html = new System.Net.WebClient().DownloadString("http://thiagomarcal.blogspot.com/");
            //string html = "Convertendo o HTML em PDF - Thiago Marçal";
            // Cria o documento aplicando o tamanho e margens
            Document documento = new Document(PageSize.A4, 80, 50, 30, 65);
            // Memory Stream para ser usado na conversão e emissão
            MemoryStream ms = new MemoryStream();
            // Inicializa o gravador
            PdfWriter writer = PdfWriter.GetInstance(documento, ms);
            // Lê o HTML e atribui
            StringReader conteudo = new StringReader(html);
            // Objeto de conversão do HTML
            HTMLWorker objeto = new HTMLWorker(documento);
            // Abre o documento
            documento.Open();
            // Aplica o parser para análise de conversão
            // Geralmente aqui ocasiona muitos erros - irei explicar no post
            objeto.Parse(conteudo);
            // Fecha o documento
            documento.Close();
            // Força o download do PDF gerado - se desejável você pode salvar em disco também
            Response.Clear();
            Response.AddHeader("content-disposition", "attachment; filename=Documento_HTML.pdf");
            Response.ContentType = "application/pdf";
            Response.Buffer = true;
            Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
            Response.OutputStream.Flush();
            Response.End();


Veja que a variável html eu atribuo o HTML que desejo converter. O seu conteúdo pode vir externamente ou posso atribuir um valor desejado.

Vamos aos problemas! Muitos vão encontrar erro quando o objeto estiver fazendo o parser do HTML e muitos irão falhar. Acontece que, devido à complexidade do HTML que estiver trabalhando, o componente não consegue converter para o formato adequado ao que ele usa internamente. Por exemplo, o TABLE do HTML que usamos é "meio" diferente do TABLE que o componente usa. Esse é um dos exemplos... Então prepara-se para fazer um tratamento adequado antes de fazer o parser. Eu sugiro o seguinte:
  1. Use expressão regular para validar seu HTML;
  2. Use expressão regular e/ou o HtmlAgilityPack para remover os JavaScripts;
  3. O conteúdo a ser convertido deve ser apenas o que está dentro do body;
  4. Imagens, CSS e links devem conter o caminho completo (exemplo: http://thiagomarcal.blogspot.com/imgs/logo.png ao invés de ../imgs/logo.png), etc.
Ou seja, quanto mais simplificado for seu HTML mais rápido e fácil será convertido em PDF. Uma observação bem clara é: nem sempre ficará 100% que o esperado.

Uma dica que pode ser usada (e um armengue, claro!) é fazer o seguinte:
  1. Gere um thumb (imagem) do HTML que deseja converter (saiba como gerar um thumb de um HTML nesse post) e salve em disco;
  2. Atribua a variável html com o conteúdo "<img src="http://thiagomarcal.blogspot.com/imgs/thumb.png" />";
  3. Coloque o width e height na tag IMG o tamanho desejado (pode ser até o tamanho do papel).
Pronto! O parser irá identificar apenas uma imagem no HTML e gerará o PDF com ela. Mole-mole...

Boleto Bancário em ASP.NET

Para quem quer implementar boleto bancário em ASP.NET e não quer perder tempo fazendo tudo, há um componente que é mão na roda: Boleto.Net. Segue abaixo descritivo retirado do site:


"Boleto.Net é um componente desenvolvido em C# e ASP.Net e contempla as seguintes funcionalidades:
Emissão e Impressão de Boletos Bancários
Geração de Arquivo de Remessa (CNAB 240 e 400)
Leitura do Arquivo de Retorno (CNAB 240 e 400)
Atualmente estamos implementando mais alguns bancos e toda colaboração será importante. Nosso objetivo é implementar todos os bancos brasileiros.
A versão 2.0 está disponível. Nessa versão contempla leitura e remessa de arquivos CNAB 400/240."


Uma boa iniciativa por parte do pessoal. Todo apoio é importante! Na página do site deles há toda informação que precisa para desenvolver: tanto o componente quanto exemplo. Os bancos homologados são: Banco do Brasil, Bradesco, Santander, Itaú e BRB. Já ajuda bastante...

URL Rewriter - Escreva URL Amigáveis em ASP.NET

A URL Rewriter permite mascarar o endereço original por um novo endereço mais seguro e amigável. Se temos o endereço:

http://thiagomarcal.blogspot.com/noticas.aspx?id_noticia=123

Podemos re-escrevê-la da seguinte forma:

http://thiagomarcal.blogspot.com/noticias/123

Ou de outras formas conforme o mascaramento desejado. Para fazer o mascaramento é preciso do componente URL Rewriter instalado no IIS. Ele é gratuito e é instalado facilmente. Para cada web-site é configurado um mascaramento de endereços que automaticamente ele faz a conversão logo que requisitado.
Não vou entrar em detalhes do processo de instalação e configuração aqui pois no site oficial tem um vídeo (logo na Home), bastando seguir o passo-a-passo, que irá conseguir deixar conforme deseja. Também há disponível vários tutoriais que auxiliam no processo bem como funções avançadas. Clique aqui para visitar o site da Micrososft URL Rewriter.