Mostrando las entradas con la etiqueta Imagenes. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Imagenes. Mostrar todas las entradas

martes, febrero 20, 2007

¿Como almacenar una imagen JPG dentro de una Base de Datos con ASPX y C#?

Hace algunos meses escribí un pequeño artículo sobre como leer una imagen que se encuentra guardada en una base de datos, para desplegarla en una página web ASPX. Ahora, si nos hacemos la pregunta ¿como fue grabada esa imagen? Bueno, despues de un buen tiempo, aqui subo la respuesta:


¿como guardar una imagen en una base de datos?







public void btnSave_Click(object sender, System.EventArgs e)
{
Int32 iFileLength = System.Convert.ToInt32(fileUpload.PostedFile.InputStream.Length);
string sContentType = fileUpload.PostedFile.ContentType;
string sFileName = fileUpload.PostedFile.FileName.Substring(fileUpload.PostedFile.FileName.LastIndexOf("\\") + 1);
byte[] bFileDataBuffer = new byte[iFileLength + 1];
fileUpload.PostedFile.InputStream.Read(bFileDataBuffer, 0, iFileLength);

SqlTransaction trans=null;

con.Open();

try
{
trans = con.BeginTransaction();

spUploadInsertNew.Transaction = trans;
spUploadInsertNew.Parameters["@DocumentID"].Value = iDocumentID;
spUploadInsertNew.Parameters["@UserID"].Value = txtAuthor.Text;
spUploadInsertNew.Parameters["@Title"].Value = txtTitle.Text;
spUploadInsertNew.Parameters["@FileName"].Value = sFileName;
spUploadInsertNew.Parameters["@FileData"].Value = bFileDataBuffer;
spUploadInsertNew.Parameters["@ContentType"].Value = sContentType;
spUploadInsertNew.Parameters["@DatePosted"].Value = txtDatePosted.SelectedDate;
spUploadInsertNew.Parameters["@FileLength"].Value = iFileLength;

spUploadInsertNew.ExecuteNonQuery();

trans.Commit();

}
catch (Exception ex)
{
System.Console.WriteLine(ex.ToString());
trans.Rollback();
}
finally
{
con.Close();
}
}

Necesitamos un Stored Procedure como el siguiente:




/****** Object: Stored Procedure dbo.Uploads_I Script Date: 14/11/2006 03:49:32 p.m. ******/
CREATE PROCEDURE dbo.Uploads_I(
@DocumentID Integer,
@UserID CHAR(15),
@Title VARCHAR(45),
@FileName VARCHAR(85),
@FileData Image,
@ContentType VARCHAR(50),
@DatePosted DateTime,
@FileLength Integer)
AS
BEGIN
DECLARE @UploadID Integer

SELECT @UploadID = ISNULL(MAX(UploadID),0) + 1 FROM Uploads

INSERT INTO Uploads
([UploadID] ,[DocumentID] ,[UserID] ,[Title] ,[FileName] ,[FileData] ,[ContentType] ,[DatePosted] ,[FileLength] )
VALUES (@UploadID,@DocumentID,@UserID,@Title,@FileName,@FileData,@ContentType,@DatePosted,@FileLength)
END




miércoles, octubre 25, 2006

Desplegar una imagen JPG dinámicamente desde una Base de Datos SQL en Delphi

Hace algunos años tuve la necesidad en mi trabajo de hacer un aplicación que desplegara dinámicamente una imagen JPG que se encontraba almacenada en una base de datos MS SQL, y otra imagen identica almacenada en una base de datos DB2. Indagando entre los ejemplos y tutoriales de Delphi me encontre un ejercicio para generar "on-the-fly" una imagen BMP, de ahi me surgio la idea de hacer eso mismo para la imagen JPG.


La solución es una aplicación web ISAPI/DLL, la cual puede ser utilizada desde cualquier archivo HTML usando el tag <IMG..> indicando en la propiedad src el url donde se encuentra la imagen, en este caso no seria una dirección aboluta sino relativa, una llamada a la ISAPI que había creado. Esto me dió la ventaja de poder utilizar dicha DLL tanto en ASP, como en JSP, dándome una enorme ventaja sobre otras alternativas. Además de que la DLL se ejecuta muy rápidamente en comparación con algun servlet o una ASP simple.


La estructura de la solución se ilustra en el siguiente diagrama de clase:



Y la lógica básica en este diagrama de secuencia:

A continuación escribimos el código fuente de Delphi, para la versión 6 y 7:
----




library ShowSignImage;

uses
ActiveX,
ComObj,
WebBroker,
ISAPIThreadPool,
ISAPIApp,
uShowSignImage in 'uShowSignImage.pas' {WebModule1: TWebModule};

{$R *.res}

exports
GetExtensionVersion,
HttpExtensionProc,
TerminateExtension;

begin
CoInitFlags := COINIT_MULTITHREADED;
Application.Initialize;
Application.CreateForm(TWebModule1, WebModule1);
Application.Run;
end.





----


----


unit uShowSignImage;

interface

uses
SysUtils, Classes, HTTPApp, DB, ADODB;

type
TWebModule1 = class(TWebModule)
con: TADOConnection;
q: TADOQuery;
qSUCURSAL: TFloatField;
qACCOUNT: TStringField;
qNUMIMAG: TStringField;
qIMAGE: TBlobField;
procedure WebModule1WebActionItem1Action(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;

var
WebModule1: TWebModule1;

implementation

uses
Windows, ShellAPI;

const
MAX_PATH = 255;
{$R *.dfm}

procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);


var
S: TMemoryStream;
sucursal, cuenta, numfirma: string;

begin
try
S := TMemoryStream.Create;
try
// get url parameters
sucursal := Request.QueryFields.Values['sucursal'];
cuenta := Request.QueryFields.Values['cuenta'];
numfirma := Request.QueryFields.Values['numimag'];

q.Parameters[0].Value := StrToFloat(sucursal);
q.Parameters[1].Value := StrToFloat(cuenta);
q.Parameters[2].Value := StrToFloat(numfirma);
q.Open;
try
S.Position := 0;

qIMAGE.SaveToStream(S);

S.Position := 0;
Response.ContentType := 'image/jpeg';

Response.ContentStream := S;
Response.SendResponse;
finally
q.Close;
end;
finally
S.Free;
end;
except
on E: Exception do
Response.Content := '<html><body>Ocurrio un error (' +
E.ClassName + ': ' + E.Message + ')</body></html>';
end;
end;

end.






----



Technorati : , ,

viernes, octubre 13, 2006

¿Como desplegar una imagen JPG desde una Base de Datos con ASPX y C#?

Siempre es necesario tener guardadas imagenes de fotografías, firmas, o documentos en una base de datos. Actualmente ha proliferado la necesidad de digitalización de documentos y su uso desde aplicaciones Web. Lo tradicional es que las imagenes se guarden en disco duro, en el file system, lo cual conlleva problemas para el programador y para los sitemas, si no se tiene un esquema robusto para su correlacion con datos generalmente provenientes de un servidor SQL. Por ello es muy útil poder almacenar dichas imágenes en una BD, pero lo mas importante poderlas mostrar posteriormente.
La técnica común de lectura de imágenes consiste en leer la imagen de desde un campo tipo BLOB, (Image si se trata de MS SQL), después guardarla en el disco duro y accederla desde ahí con HTML, asp's y similares. Esto impacta en el desempeño de la aplicación de manera significativa a pesar de ser una técnica relativamente sencilla y de fácil implementación.
Sin embargo es posible mostrar la imagén al vuelo, es decir desde que se lee de la base de datos, mandarla al web, sin tener que dar el paso intermedio de grabación en disco. La técnica es mucho mas sencilla. Con una aplicación asp o aspx basta con leer la imagen de la BD y mandarla al Reponse, únacamente cambiando el tipo de respuesta Response.ContentType, asignando el valor 'image/JPEG'. Esto es súmamente fácil de implementar en cualquier lenguaje. Un ejemplo en ASPX con C# lo mostramos a continuación. (También publicaremos el ejemplo en Delphi, PHP y Java para ilustrarlo mas ampliamente)




<%@ Page language="c#" Codebehind="ViewImage.aspx.cs" AutoEventWireup="false" Inherits="Sorteo.ViewImage" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<TITLE>ViewImage</TITLE>
<METAname="GENERATOR"content="Microsoft Visual Studio .NET 7.1">
<METAname="CODE_LANGUAGE"content="C#">
<METAname="vs_defaultClientScript"content="JavaScript">
<METAname="vs_targetSchema"content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<BODYms_positioning="GridLayout">
<FORMid="Form1"method="post"runat="server">
</FORM>
</BODY>
</HTML>




--- C# ---


using System;
using System.Data.SqlClient;
using System.Web.UI;

namespace Sorteo
{
///<summary>
///Devuelve una imagen almacenada en una BD
///</summary>
public class ViewImage : System.Web.UI.Page
{
protected System.Data.SqlClient.SqlConnection con;
protected SqlCommand cmdImage;

private void Page_Load(object sender, EventArgs e)
{
try
{
con.Open();
int iIDPremio = Convert.ToInt32(Request.QueryString["IDPremio"]);
cmdImage.Parameters["@IDPremio"].Value = iIDPremio;
object o=cmdImage.ExecuteScalar();
byte[] bufr=(byte[])o;
Response.ContentType="image/JPEG";
Response.OutputStream.Write(bufr,0,bufr.Length);
}
catch(Exception except)
{
Response.Write(cmdImage.CommandText + "\n" + except.ToString()) ;
}
finally
{
con.Close();
}
}


#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

///<summary>
///Required method for Designer support - do not modify
///the contents of this method with the code editor.
///</summary>
private void InitializeComponent()
{
System.Configuration.AppSettingsReader configurationAppSettings = new System.Configuration.AppSettingsReader();
this.cmdImage = new System.Data.SqlClient.SqlCommand();
this.con = new System.Data.SqlClient.SqlConnection();
//
// cmdImage
//
this.cmdImage.CommandText = "SELECT Imagen FROM Premios WHERE (IDPremio = @IDPremio)";
this.cmdImage.Connection = this.con;
this.cmdImage.Parameters.Add(new System.Data.SqlClient.SqlParameter("@IDPremio", System.Data.SqlDbType.VarChar, 4, "IDPremio"));
//
// con
//
this.con.ConnectionString = ((string)(configurationAppSettings.GetValue("con.ConnectionString", typeof(string))));
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion
}
}



----------

Para ejecutar el programa basta llamarlo desde el browser para que muestre directamente la imagen almacenada en la base de datos.

http://localhost/MyImageApp/ViewImage.aspx?IDPremio=1

El campo IDPremio es el ID del registro que contiene la imagen, para este ejemplo es un listado de premios de un sorteo. Este se puede modificar segun la necesidad. Y se puede hacer mas generico o parametrizable.

Explicación Tecnica:

El programa utiliza una sencilla llamada SELECT a una Tabla Premios en la cual hay un campo Image que guarda imagenes tipo JPG. Basicamente el resultado es leido en forma de un arreglo de bytes y enviado a la respuesta de la aplicacion, especificando el ContentType como 'image/JPEG' para que sea identificado por el browser.

Si la necesidad es mostrar la imagen dentro de una pagina o en una tabla, o dentro de un DataGrid, se debe hacer uso del tag <IMG src...> y en la propiedad src (source) indicar la url de la aplicación en cuestión. Por ejemplo:


<imgsrc="ViewImage?IDPremio=1">


Esta sencilla llamada hara que se muestre la imagen desde cualquier pagina HTML. Por otro lado, si se quiere llamar desde una aplicacion asp, el código quedaría mas o menos asi:


<imgsrc="ViewImage?IDPremio=<%=NumPremio%>">


Donde se sobreentiende que NumPremio es una variable cuyo valor dependera del programa asp, esto es puede venir de una base de datos o de un ciclo for.



Technorati : , ,