Baixar arquivos da Web com C#

Este exemplo mostra como baixar arquivos a partir de qualquer website para o disco local. Uma maneira simples para efetuar o download do arquivo é usar a classe WebClient e seu método DownloadFile. Este método tem dois parâmetros, primeiro é a url do arquivo que você deseja fazer o download e o segundo parâmetro é o caminho para o disco local para o qual deseja salvar o arquivo.

De forma síncrona

O código a seguir mostra como fazer o download de arquivos de forma síncrona. Este método bloqueia a thread principal até que o arquivo é baixado ou ocorrer um erro (neste caso, o WebException é lançada).


using System.Net;

WebClient webClient = new WebClient();
webClient.DownloadFile("http://localhost/arquivo.txt", @"c:\temp\arquivo.txt");

De forma assíncrona

Para baixar um arquivo sem bloquear o segmento principal uso DownloadFileAsync método assíncrono. Você também pode definir manipuladores de eventos para mostrar o progresso e para detectar que o arquivo é baixado. Faça o exemplo abaixo com uma aplicação Windows Forms.


private void btnDownload_Click(object sender, EventArgs e)
{
 WebClient webClient = new WebClient();
 webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completo);
 webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressoFeito);
 webClient.DownloadFileAsync(new Uri("http://localhost/arquivo.txt"), @"c:\temp\arquivo.txt");
}

private void ProgressoFeito(object sender, DownloadProgressChangedEventArgs e)
{
 progressBar.Value = e.ProgressPercentage;
}

private void Completo(object sender, AsyncCompletedEventArgs e)
{
 MessageBox.Show("Download efetuado!");
}

Até a próxima.

Anúncios

Encurtador de URL’s

Essa semana, aproveitei para colocar um pequeno projeto para funcionar, arquitetei e montei um Encurtador de URL’s que faz utilização do Dot Net Framework 4, SQL Server 2008, C#, integração com Web Services.

Da forma como foi feito encurtará apenas um pouco mais de 6 milhões de URL’s, mas está muito fácil para alterar o algorítimo para ter 5 caracteres ao invés de 4 na chave da URL.

A idéia é evoluir esse software e se aumentar muito a quantidade de acessos utilizar um banco de dados como o Apache Cassandra.

O Encurtador de URL’s está disponível no link http://devd.im, e o código fonte está em http://sourceforge.net/projects/devdim.

http://devd.im/

Formatar XML com XSL usando Dot Net

Nesse artigo utilizei Visual C# 2010 Express, Framework 4.0 e para o aplicativo teste fiz um console application.

Com o advento de integração, SOA, Web Services, cada dia mais temos que adaptar o conteúdo de nossos dados com agilidade, no meu caso eu atuo em uma empresa na qual temos vários parceiros comerciais que consomem nosso catálogo de produtos, e a forma de integração que temos é com o uso de XML, bom para acelerar o desenvolvimento do XML para cada parceiro, nós criávamos um XML para cada um, só que isso não era feito de forma automática, a codificação de cada XML era feita individualmente, os objetos eram reutilizados, mas ai tivemos problemas com performance, pois a consulta era feita em tempo real, ou seja, os parceiros concorriam com os clientes que navegavam no site, o XML demorava para ser carregado, quando era necessário efetuar algum filtro por categoria, gênero, marca etc, isso era feito na aplicação, ou seja, o catalogo era carregado inteiro e filtrado através de um delegate, quando eram poucos parceiros, poucos clientes, tudo bem, mas 1 ano depois com muito mais acessos o negócio ficou ruim, e é isso que vou mostrar como fazer aqui, como esse problema foi resolvido, os passos foram:

  1. Não acessar mais o banco diretamente, mas sim um XML base;
  2. Efetuar a formatação dos dados baseado em um XSL e não mais fazer isso na codificação;
  3. Colocar os critérios dentro do XSL ao invés de fazer na aplicação ou em query.

O que é um arquivo XSL e para que serve

Segundo a Wikpedia “XSL Transformations, ou XSLT (eXtensible Stylesheet Language for Transformation – linguagem extensível para folhas de estilo de transformações), é uma linguagem de marcação XML usada para criar documentos XSL que, por sua vez, definem a apresentação dos documentos XML nos browsers e outros aplicativos que a suportem.” ou seja, serve para formatar a saída de dados do XML

Fonte: http://pt.wikipedia.org/wiki/XSLT

Agora que estamos alinhados com o cenário vamos começar.

XML Base

Isso é algo muito tranquilo, foi criado um JOB que gera um XML em uma pasta visível pela aplicação com todo catálogo de produtos, para esse estudo vamos usar o exemplo abaixo:

<?xml version="1.0"
encoding="utf-8" ?>
<catalogo>
  <item>
    <Sku>500135</Sku>
<Descricao><![CDATA[Bola de Tênis Wilson Championship ]]></Descricao>
<CodigoCategoria>102</CodigoCategoria>
    <Categoria>RACKET</Categoria>
<CodigoMarca>15</CodigoMarca>
<Marca>WILSON</Marca>
 </item>
 <item>
    <Sku>500139</Sku>
<Descricao><![CDATA[Haltere Ferro Centauro MeioKg]]></Descricao>
<CodigoCategoria>107</CodigoCategoria>
    <Categoria>BODY               </Categoria>
<CodigoMarca>999</CodigoMarca>
<Marca>FORTE</Marca>
  </item>
  <item>
    <Sku>500140</Sku>
<Descricao><![CDATA[Halteres Ferro Centauro 1 Kg]]></Descricao>
<CodigoCategoria>107</CodigoCategoria>
    <Categoria>BODY               </Categoria>
<CodigoMarca>999</CodigoMarca>
<Marca>FORTE</Marca>
  </item>
  <item>
    <Sku>500141</Sku>
<Descricao><![CDATA[Halteres Ferro Centauro 2Kg]]></Descricao>
<CodigoCategoria>107</CodigoCategoria>
    <Categoria>BODY               </Categoria>
<CodSubGrupo>34</CodSubGrupo>
<Marca>FORTE</Marca>
  </item>
  <item>
    <Sku>500142</Sku>
<Descricao><![CDATA[Halteres Ferro Centauro 3kg]]></Descricao>
<CodigoCategoria>107</CodigoCategoria>
    <Categoria>BODY               </Categoria>
<CodigoMarca>999</CodigoMarca>
<Marca>FORTE</Marca>
  </item>
  <item>
    <Sku>500143</Sku>
<Descricao><![CDATA[Halteres Ferro Centauro 4Kg]]></Descricao>
<CodigoCategoria>107</CodigoCategoria>
    <Categoria>BODY
               </Categoria>
<CodigoMarca>999</CodigoMarca>
<Marca>FORTE</Marca>
  </item>
</catalogo>

XSL’s

Bom, o XSL pode ficar ao gosto de cada um, eu vou colocar dois exemplos aqui, o primeiro nos dará a seguinte saída do XML Base:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method='xml' indent='yes' version='1.0' encoding='UTF-8' standalone='yes' cdata-section-elements='NOME'/>
<xsl:template match="/">
<produtos>
<xsl:for-each select="catalogo/item[CodigoCategoria='102' and CodigoMarca='999']">
<PRODUTO>
<SKU>
<xsl:value-of select="Sku"/>
</SKU>
<NOME>
<xsl:value-of select="Descricao"/>
</NOME>
<CATEGORIA>
<xsl:value-of select="Categoria"/>
</CATEGORIA>
</PRODUTO>
</xsl:for-each>
</produtos>
</xsl:template>
</xsl:stylesheet>

O segundo nos dará a saída abaixo:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method='xml' indent='yes' version='1.0' encoding='UTF-8' standalone='yes' cdata-section-elements='NOME'/>
<xsl:template match="/">
<produtos>
<xsl:for-each select="catalogo/item[CodigoCategoria='102']">
<ITEM>
<CODIGO>
<xsl:value-of select="Sku"/>
</CODIGO>
<DESCRICAO>
<xsl:value-of select="Descricao"/>
</DESCRICAO>
</ITEM>
</xsl:for-each>
</produtos>
</xsl:template>
</xsl:stylesheet>

Esses arquivos devem ser criados em um local que a aplicação posso lê-los.

Agora vamos entender algumas tag’s do XSL:

Aqui é feita a declaração do XSL, a versão e qual namespace (xmlns) é utilizado, a tag deve ser fechada

<xsl:stylesheet version="1.0" xmlns:xsl="<a href="http://www.w3.org/1999/XSL/Transform">http://www.w3.org/1999/XSL/Transform</a>">

A saída do arquivo é definida aqui, o método/formato (method), a versão do formato (version), a codificação (encoding) e as tags que terão a saída com CDATA (cdata-section-elements).

<xsl:output method='xml' version='1.0' encoding='UTF-8' cdata-section-elements='NOME'/>

Nesse momento o nó raiz é escolhido para trabalhar, a tag deve ser fechada.

<xsl:template match="/">

Tudo o que não estiver usando o prefixo xsl será escrito da mesma forma como estiver no XSL. Vamos ver o loop agora

Aqui é o começo do loop

<xsl:for-each select="catalogo/item">

E aqui é o seu final

</xsl:for-each>

Tudo o que estiver entre essas tag’s será repetido até que todos os nós tenha sido lidos.

Para escrever os valores que estão no XML basta usar a tag value-of e no atributo select colocar o campo que deseja conforme o exemplo

<xsl:value-of select="Sku"/>

Adicionando critérios no XSL

Assim como em uma query é possível adicionar critérios em XSL, basta adicioná-los conforme o código abaixo na tag for-each, no primeiro exemplo o XSL trará apenas os produtos com o campo CodigoCategoria igual a 102, no segundo exemplo, todos com CodigoCategoria igual a 102 e o CodigoMarca igual 999.

<xsl:for-each select="catalogo/item[CodigoCategoria='102']">
<xsl:for-each select="catalogo/item[CodigoCategoria='102' and CodigoMarca='999']">

Usando XSL para formatar o XML

O Dot Net Framework nos dá suporte para trabalhar com arquivos XML através do Namespace System.Xml e para trabalhar com XSL com o Namespace System.Xml.Xsl

Vamos utilizar a classe XslCompiledTransform para formatar o XML com nosso XSL, essa classe é um processador de XSL e XSLT, ela é a sucessora da classe XslTransform, e segundo a MSDN oferece ganhos de performance com relação a classe antiga (e obsoleta na versão 4.0 do Dot Net Framework)

Uma das sobrecargas do construtor do XslCompiledTransform recebe um XmlReader, então carreguei o XSL dentro de um XmlReader e criei o objeto do XslCompiledTransform, o método Transform de nosso objeto XslCompiledTransform tem uma sobrecarga que recebe o xml base, uma lista de argumentos de Xslt que será passado como nulo e um objeto que terá o resultado da transformação, nesse caso é passado um StringWriter, pronto, agora o objeto StringWriter tem o XML carregado conforme as definições do XSL, tudo bem simples,

Código

Aqui está todo o código utilizado para a aplicação funcionar corretamente.

using System;
using System.Xml;
using System.Xml.Xsl;
using System.IO;
namespace GeradorXmlParceiro
{
class Program
{
static string caminhoXmlBase = @"C:\XmlBase\XmlBase.xml";
static string caminhoXsl = @"C:\Xsl\Xsl1.xsl";
static string caminhoXmlFormatado = @"C:\XmlTransformado\XmlTransformado.xml";
static void Main(string[] args)
{
CriarXmlComXsl();
}

static void CriarXmlComXsl()
{
XmlDocument xml = new XmlDocument();
xml = FormartarXmlBaseParaFormatoComXsl(caminhoXsl);
xml.Save(caminhoXmlFormatado);
}

static XmlDocument FormartarXmlBaseParaFormatoComXsl(string caminhoXsl)
{
XmlDocument xml = new XmlDocument();
XslCompiledTransform xsl = new XslCompiledTransform();
XmlDocument xmlBase = ObterXmlBase();
try
{
XmlReader reader = XmlReader.Create(caminhoXsl);
xsl.Load(reader);
StringWriter writer = new StringWriter();
xsl.Transform(xmlBase, null, writer);
xml.LoadXml(writer.ToString());
}
catch (Exception ex)
{
throw new Exception("Ocorreu um erro ao efetuar a transformação do XML.", ex.InnerException);
}
return xml;
}

static XmlDocument ObterXmlBase()
{
XmlDocument xml = new XmlDocument();
try
{
xml.Load(caminhoXmlBase);
}
catch (Exception ex)
{
throw new Exception("Ocorreu um erro ao carregar o XML.", ex.InnerException);
}
return xml;
}
}
}

É isso ai! Espero que esse artigo posso contribuir para o crescimento da comunidade! Até a próxima!

Referências

http://www.w3schools.com/xsl/

http://www.w3schools.com/xml/

http://msdn.microsoft.com/en-us/library/system.xml.xsl.xslcompiledtransform.aspx

Redimensionando imagens com Dot Net

Com o uso das bibliotecas System.Drawing e System.Drawing.Imaging podemos redimensionar imagens há um tamanho bem menor sem praticar perder a qualidade.

Primeiro pegue uma imagem grande e de boa resolução, no meu caso vou usar uma imagem de 900×900 e vou redimensioná-la para os tamanhos 400×400, 250×2500, 120×120 e 48×48.

Criei um novo projeto do tipo Console Application no Visual Studio 2010, adicionei referência à biblioteca System.Drawing e no método Main adicionei o seguinte código:

List<string> enderecosDeImagens = new List<string>();

enderecosDeImagens = Imagem.ObterImagensNaoRedimensionadas();

List<Resolucao> resolucoes = new List<Resolucao>();

resolucoes.Add(Resolucao._400x400);
resolucoes.Add(Resolucao._250x250);
resolucoes.Add(Resolucao._120x120);
resolucoes.Add(Resolucao._48x48);

Imagem.RedimensionarArquivos(enderecosDeImagens, resolucoes);

Nesse código foi criada uma lista de string’s que conterá os endereços das imagens não redimensionadas, uma lista do tipo resolução, e depois passamos por paramêtro os endereços das imanges e as resoluções que queremos ter. Apreveite para criar o Enum Resolucao

public enum Resolucao
{
_48x48 = 48,
_120x120 = 120,
_250x250 = 250,
_400x400 = 400
}

Crie uma classe static chamada Imagem, adicione o método ObterImagensNaoRedimensionadas que retornorá uma lista de string, o método RedimensionarArquivos que será void, o método CriarPastas que será void, o método RedimensionarArquivo que será booleano, o método SalvarImagem que será void eo método ObterInformacaoDeCodificacao que retornará um ImageCodecInfo.

ObterImagensNaoRedimensionadas

List<string> imagensNaoRedimensionadas = new List<string>();

imagensNaoRedimensionadas = System.IO.Directory.GetFiles(@”D:\Artigos\Images\img\900×900″).ToList();

return imagensNaoRedimensionadas;

RedimensionarArquivos

CriarPastas(resolucoes);

Dictionary<string, bool> arquivosRedimensionados = new Dictionary<string, bool>();

foreach (string enderecoDoArquivo in enderecosDosArquivos)
{
foreach (Resolucao resolucao in resolucoes)
{
if (RedimensionarArquivo(enderecoDoArquivo, resolucao))
{
arquivosRedimensionados.Add(string.Format(“{0} – {1}”, enderecoDoArquivo, resolucao), true);
}
else
{
arquivosRedimensionados.Add(string.Format(“{0} – {1}”, enderecoDoArquivo, resolucao), true);
}
}
}

CriarPastas

foreach (Resolucao resolucao in resolucoes)
{
string pasta = string.Format(@”D:\Artigos\Images\img\{0}x{0}”, (int)resolucao);

if (System.IO.Directory.Exists(pasta) == false)
{
System.IO.Directory.CreateDirectory(pasta);
}
}

RedimensionarArquivo

bool resultado = true;

try
{
Bitmap imagemAtual = new System.Drawing.Bitmap(enderecoArquivo);

Bitmap ImagemRedimensionada = new System.Drawing.Bitmap((int)resolucao, (int)resolucao);

using (Graphics g = Graphics.FromImage((Image)ImagemRedimensionada))
{
g.DrawImage(imagemAtual, 0, 0, (int)resolucao, (int)resolucao);
}

System.IO.FileInfo fi = new System.IO.FileInfo(enderecoArquivo);

string destino = string.Format(@”D:\Artigos\Images\img\{0}x{0}\{1}”, (int)resolucao, fi.Name);

Imagem.SalvarImagem(destino, ImagemRedimensionada, 85L);
}
catch (Exception ex)
{
throw ex;
}

return resultado;

SalvarImagem

// Encoder parameter for image quality
EncoderParameter qualidade =
new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

// Jpeg image codec
ImageCodecInfo jpegCodec = ObterInformacaoDeCodificacao(“image/jpeg”);

if (jpegCodec == null)
return;

EncoderParameters parametrosDeCodificacao = new EncoderParameters(1);
parametrosDeCodificacao.Param[0] = qualidade;

img.Save(path, jpegCodec, parametrosDeCodificacao);

ObterInformacaoDeCodificacao

// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
{
if (codecs[i].MimeType == mimeType)
{
return codecs[i];
}
}

return null;

 

Repeater dentro de Repeater (DataList dentro de DataList ou GridView dentro de GridView)

Imagine a seguinte situação: você tem uma lista de um determinado objeto e cada objeto dessa lista tem uma propriedade. Essa propriedade é uma lista de um determinado objeto e você precisa popular um Repeater.

Vamos dar nomes aos objetos: suponha que você tenha uma lista de professores e cada professor tem seus alunos, bem, alguns irão dizer que é fácil, cada vez que o Repeater fizer um ItemDataBound basta fazer um busca novamente no banco de dados e listar o resultado. Como sempre me deparo com essa situação e vira e mexe algum me pergunta se essa é a melhor maneira de fazer resolvi escrever um artigo.

É muito simples, se a sua coleção já vem populada, basta você passar essa lista de objetos para o outro controle dentro do seu Repater (nesse caso outro Repeater), e isso será feito a cada ItemDataBound.

Classes

Temos as seguintes classes:

/// <summary> /// Classe mãe /// </summary> public abstract class Pessoa { private string _nome = string.Empty; public string Nome { get { return _nome; } set { _nome = value; } } public Pessoa() { } } /// <summary> /// Professor implementa Pessoa /// </summary> public class Professor : Pessoa { private string _materia = string.Empty; public string Materia { get { return _materia; } set { _materia = value; } } /// <summary> /// Um professor tem uma lista de alunos /// </summary> private System.Collections.Generic.List<Aluno> alunos = new System.Collections.Generic.List<Aluno>(); public System.Collections.Generic.List<Aluno> Alunos { get { return alunos; } set { alunos = value; } } public Professor(string nome, string materia, System.Collections.Generic.List<Aluno> alunos) { Nome = nome; Materia = materia; Alunos = alunos; } } /// <summary> /// Aluno implementa Pessoa /// </summary> public class Aluno : Pessoa { private string _turma = string.Empty; public string Turma { get { return _turma; } set { _turma = value; } } public Aluno(string nome, string turma) { Nome = nome; Turma = turma; } }

WebForm

Agora que já conhecemos nossas classes vamos para a implementação disso em uma página. Primeiro vamos criar um Repeater na página e, dentro dele, criaremos um segundo repeater, como no exemplo abaixo:

<asp:Repeater ID="ProfessorRepeater" runat="server" OnItemDataBound="ProfessorRepeater_ItemDataBound"> <ItemTemplate> Professor: <%# Eval("Nome") %> <br /> Matéria: <%# Eval("Materia") %> <br /> Alunos: <asp:Repeater ID="AlunoRepeater" runat="server"> <HeaderTemplate> <table> <tr style="font-weight: bold"> <td> Nome</td> <td> Curso</td> </tr> </HeaderTemplate> <FooterTemplate> </table> </FooterTemplate> <ItemTemplate> <tr style="background-color: Gray"> <td> <%# Eval("Nome") %> </td> <td> <%# Eval("Turma")%> </td> </tr> </ItemTemplate> <AlternatingItemTemplate> <tr style="background-color: Silver"> <td> <%# Eval("Nome") %> </td> <td> <%# Eval("Turma") %> </td> </tr> </AlternatingItemTemplate> </asp:Repeater> </ItemTemplate> <SeparatorTemplate> <hr /> </SeparatorTemplate> </asp:Repeater>

Atente para o detalhe que o repeater AlunoRepater está escrevendo as propriedades Nome (que vem de Pessoa) e turma (que é da classe Aluno).

Bom, mas isso não irá funcionar dessa maneira. Vejamos no code behind da página como é a implementação disso.

Code Behind

No PageLoad os objetos são criados e populados.

protected void Page_Load(object sender, EventArgs e) { Page.Title = "Repeater dentro de Repeater (DataList dentro de DataLista ou GridView dentro de GridView)"; // lista de alunos que será atribuída aos professores List<Aluno> alunosEpaminondas = new List<Aluno>(); alunosEpaminondas.Add(new Aluno("Alan", "Sistemas da Informação")); alunosEpaminondas.Add(new Aluno("Fabio", "Ciência da Computação")); alunosEpaminondas.Add(new Aluno("Marcelo", "Desenvolvimento de Sistemas Web")); // Só para não falar que os professores tem os mesmos alunos List<Aluno> alunosAdolfo = new List<Aluno>(); alunosAdolfo.Clear(); alunosAdolfo.Add(new Aluno("Carol", "Análise de Sistemas")); alunosAdolfo.Add(new Aluno("Bruno", "Banco de Dados")); // lista de professores List<Professor> professores = new List<Professor>(); professores.Add(new Professor("Epaminondas", "Gestão de Projetos", alunosEpaminondas)); professores.Add(new Professor("Adolfo", "Programação Orientação a Objetos", alunosAdolfo)); ProfessorRepeater.DataSource = professores; // define o DataSource do repeater como a lista de objetos professores ProfessorRepeater.DataBind(); }

No controle ProfessorRepeater, no evento ItemDataBound que o controle AlunoRepeater é populado, veja como é simples fazer a conversão do item do repeater que é passado.

protected void ProfessorRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) { // verifica se o item é do tipo ItemType ou AlternatingItem, se não for retorna e não continua o processamento if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; // verifica se o objeto AlunoRepeater existe dentro do item if (e.Item.Controls.Contains((Repeater)e.Item.FindControl("AlunoRepeater"))) { // cria um objeto Repeater e define-o como o objeto AlunoRepeater do item Repeater alunoRepeater = (Repeater)e.Item.FindControl("AlunoRepeater"); // converte o item (linha do repeater) para um professor e define a propriedade Alunos como DataSource do repeater alunoRepeater.DataSource = ((Professor)e.Item.DataItem).Alunos; alunoRepeater.DataBind(); } }

Super simples e tranqüilo, não há segredos nisso. A grande sacada é não ter que conectar ao banco novamente apenas obter os outros objetos. É possível utilizar isso também na criação de menus, para exibir a notas fiscais e seus itens, pedidos e seus itens etc. Aí vai depender da necessidade de cada projeto.

Até a próxima!

Upload de imagem com recorte usando Jquery e asp.net

Quem nunca quis disponibilizar, em sua aplicação, a possibilidade de o usuário subir uma imagem e recortá-la, como vários sites já fazem? Dei uma pesquisada, estudei sobre o System.Drawing,  jquery e resolvi compartilhar aqui o que consegui. Veja só.

Bibliotecas

A primeira coisa a ser feita aqui é baixar alguns arquivos, faça o download do jquery e dojcrop.

Namespaces

Inclua os seguintes namespaces em sua página:

  • System.IO
  • System.Drawing
  • System.Drawing.Imaging
  • System.Drawing.Drawing2D

O namespace System.Drawing sera utilizado com apelido SD

Formulário

Adicione três controles do tipo Panel no formulário, conforme a tabela abaixo:

ID Visible
UploadPanel True
ImagemOriginalPanel False
ImagemRecortadaPanel False

Dentro do UploadPanel adicione os controles dessa forma:

Tipo ID Text Visible
FileUpload ArquivoFileUpload N/A True
Button UploadButton Upload True
Label ErroLabel “” False

Dentro do ImagemOriginalPanel adicione os controles como mostrado:

Tipo ID Text
Image OriginalImage N/A
Button RecortarButton Recortar
HiddenField XHiddenField N/A
HiddenField YHiddenField N/A
HiddenField WHiddenField N/A
HiddenField HHiddenField N/A

Dentro do ImagemRecortadaPanel adicione o seguinte controle:

Tipo ID Text
Image ImagemRecortadaImage N/A

O código da sua página deve estar bem parecido com este:

    <form id="form1" runat="server">         <asp:Panel ID="UploadPanel" runat="server">             <asp:FileUpload ID="ArquivoFileUpload" runat="server"/>             <asp:Button ID="UploadButton" runat="server" Text="Upload" />         </asp:Panel>         <asp:Panel ID="ImagemOriginalPanel" runat="server" Visible="false">             <asp:Image ID="OriginalImage" runat="server" />             <asp:Button ID="RecortarButton" runat="server" Text="Recortar" />             <asp:HiddenField ID="XHiddenField" runat="server" />             <asp:HiddenField ID="YHiddenField" runat="server" />             <asp:HiddenField ID="WHiddenField" runat="server" />             <asp:HiddenField ID="HHiddenField" runat="server" />         </asp:Panel>         <asp:Panel ID="ImagemRecortadaPanel" runat="server" Visible="false">             <asp:Image ID="ImagemRecortadaImage" runat="server" />         </asp:Panel>

Estrutura do site

Adicione uma pasta com o nome imagens ao site.

Arquivos das bibliotecas

Adicione os seguintes arquivos no site:

  • jquery.min.js
  • jquery.Jcrop.js
  • jquery.Jcrop.css

HTML

Inclua as referências para os arquivos na sua página.

<script src="jquery.min.js" /></script> <script src="jquery.Jcrop.js" /></script> <link rel="stylesheet" href="jquery.Jcrop.css" type="text/css" />

Aplicando o Jcrop

Inclua as seguintes funções na sua página:

        jQuery(document).ready(function(){             jQuery('#OriginalImage').Jcrop({                 onSelect: marcaPontos             });         });         function marcaPontos(c) {             jQuery('#XHiddenField').val(c.x);             jQuery('#YHiddenField').val(c.y);             jQuery('#WHiddenField').val(c.w);             jQuery('#HHiddenField').val(c.h);         };               

É realmente muito simples. Jcrop foi aplicado ao controle OriginalImage que está dentro de ImagemOriginalPanel, e um handler foi adicionado ao evento de selecionar a imagem. Isso acontecerá quando o usuário tiver acabado de selecionar a área da imagem que deseja manter. O handler chamada a função marcaPontos, que define os valores dos campos XHiddenField, HiddenField, WHiddenField e HHiddenField passando as coordenadas.

Code Behind

O código abaixo irá pegar o caminho físico da pasta imagens e guardá-lo na variável pasta, declare-o no começo da classe da página.

string pasta = HttpContext.Current.Request.PhysicalApplicationPath + "imagens\\";

No evento click do botão upload adicione o seguinte código:

    protected void UploadButton_Click(object sender, EventArgs e) { bool extensaoPermitida = false; bool arquivoGravado = false; if (ArquivoFileUpload.HasFile) { string extensaoArquivo = Path.GetExtension(ArquivoFileUpload.FileName); string[] extensoesPermitidas = { ".png", ".jpg", ".gif", ".jpeg" }; for (int i = 0; i < extensoesPermitidas.Length; i++) if (extensoesPermitidas[i] == extensaoArquivo) extensaoPermitida = true; if (extensaoPermitida) { try { ArquivoFileUpload.PostedFile.SaveAs(pasta + ArquivoFileUpload.FileName); arquivoGravado = true; } catch (Exception ex) { ErroLabel.Text = "Ocorreu um problema na tentativa de salvar o arquivo." + ex.ToString(); ErroLabel.Visible = true; arquivoGravado = false; } } else { ErroLabel.Text = string.Format("Tipo de arquivo inválido. Tipo aceitos {0}.", extensoesPermitidas.ToString()); ErroLabel.Visible = true; } if (arquivoGravado) { ImagemOriginalPanel.Visible = true; OriginalImage.ImageUrl = "imagens/" + ArquivoFileUpload.FileName; Session["arquivo"] = ArquivoFileUpload.FileName; } } }

No evento click do botão recortar adicione o seguinte código:

   protected void RecortarButton_Click(object sender, EventArgs e) { string nomeArquivo = Session["arquivo"].ToString(); int eixoX = Convert.ToInt32(XHiddenField.Value); int eixoY = Convert.ToInt32(YHiddenField.Value); int largura = Convert.ToInt32(WHiddenField.Value); int altura = Convert.ToInt32(HHiddenField.Value); byte[] recorte = Recortar(pasta + nomeArquivo, largura, altura, eixoX, eixoY); using (MemoryStream ms = new MemoryStream(recorte, 0, recorte.Length)) { ms.Write(recorte, 0, recorte.Length); using (SD.Image imagemRecortada = SD.Image.FromStream(ms, true)) { string salvarEm = pasta + "crop" + nomeArquivo; imagemRecortada.Save(salvarEm, imagemRecortada.RawFormat); ImagemOriginalPanel.Visible = false; ImagemRecortadaPanel.Visible = true; ImagemRecortadaImage.ImageUrl = "imagens/crop" + nomeArquivo; } } }

Crie um método do tipo void conforme abaixo.

  private byte[] Recortar(string nomeAbsolutoArquivo, int largura, int altura, int eixoX, int eixoY) { try { using (SD.Image imagemOriginal = SD.Image.FromFile(nomeAbsolutoArquivo)) { using (SD.Bitmap bitmap = new System.Drawing.Bitmap(largura, altura)) { bitmap.SetResolution(imagemOriginal.HorizontalResolution, imagemOriginal.VerticalResolution); using (SD.Graphics grafico = SD.Graphics.FromImage(bitmap)) { grafico.SmoothingMode = SmoothingMode.AntiAlias; grafico.InterpolationMode = InterpolationMode.HighQualityBicubic; grafico.PixelOffsetMode = PixelOffsetMode.HighQuality; grafico.DrawImage(imagemOriginal, new System.Drawing.Rectangle(0, 0, largura, altura), eixoX, eixoY, largura, altura, SD.GraphicsUnit.Pixel); MemoryStream ms = new MemoryStream(); bitmap.Save(ms, imagemOriginal.RawFormat); return ms.GetBuffer(); } } } } catch (Exception ex) { throw ex; } }

Agora é só colocar tudo para rodar. Não é um bicho de sete cabeças, a questão é juntar tudo.

Referências

 

Espero que esse artigo sirva para agregar conhecimento à comunidade. Até a próxima.

Reproduzindo mp3 no .NET com C#

Este é meu primeiro artigo. É um artigo simples com intenção de demonstrar como reproduzir MP3 no .NET com C# utilizando um componente pronto.

Os links para baixar os arquivos e as referências estão no fim do artigo.

Nessa aplicação, foram utilizados Visual Studio 2008 (pode ser Visual Studio 2005 ou compátivel e Framework .Net 2.0.

1º Registre o componente mp3p.ocx

No Prompt do MS-DOS com o comando regsvr32.exe mp3p.ocx.

2º Adicione as seguintes refêrencias ao projeto

  • AxInterop.MP3PLib.dll
  • Interop.MP3PLib.dll
  • XAUDIO.dll

3º Adicione o controle “MP3P Control” à barra de ferramentas

Clique na barra de ferramentas com o botão direito, clique em “Choose Items” na caixa de dialogo “Choose Toolbox Items”, clique em “Browse…”, selecione o arquivo mp3p.ocx (que já deve ter sido registrado no seu computador) e clique em “OK”.

4º Adicione o componente para o formulário

5º Adicione 3 botões ao formulário: Abrir, Tocar e Parar

No code behind do formulário. No botão Abrir, implemente o seguinte código:

private void AbrirButton_Click(object sender, EventArgs e)
{
axMp3P1.OutputClose();
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Arquivos WAV(*.wav) | Arquivps MP3(*.mp3)";
if (openFileDialog.ShowDialog() == DialogResult.OK)
axMp3P1.InputOpen(openFileDialog.FileName);
}
No botão Tocar implemente o seguinte código
private void TocarButton_Click(object sender, EventArgs e)
{
axMp3P1.Play();
}
No botão Parar implemente o seguinte código
private void ParaButton_Click(object sender, EventArgs e)
{
axMp3P1.Stop();
}

Referências

http://www.codeproject.com/KB/audio-video/cswavplay.aspx?df=100&forumid=13779&exp=0&fr=26&select=736865

http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/3dbfb9a3-4e14-41d1-afbb-1790420706fe

http://www.dlldll.com/xaudio.dll_download.html 

http://www.c-sharpcorner.com/UploadFile/electricfarm/PlayMP311172006160247PM/PlayMP3.aspx