Database Techniques for Pictures, PDF and Other Byte Arrays

download Database Techniques for Pictures, PDF and Other Byte Arrays

of 19

Transcript of Database Techniques for Pictures, PDF and Other Byte Arrays

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    1/19

    Writing pictures, pdf and other byte arrays to SQL Server in C#.NetReading and displaying pictures, pdf and other byte arrays to Web Pages in C#.NetThis project is created with Visual Studio 2008, using C# to create a Web application.

    This project consists of :Default.aspx upload and invoke the page, BinaryViewer.aspx to see the stored contentsDefault.aspx.cs code behindThumbnail.ashx Web handler to direct the byte[] image streamDataAccess.cs Separate connectivity and the clientsWeb.config control the connection string used for an included SQL Server database, ImageStore.mdf BinaryViewer.aspxBinaryViewer.aspx.csImageStore.mdf Second database, just to show you can have your SQL Server inside the application project or you can access an independent SQL Server (as you can see in DataAccess.cs).

    SQL Script.sql - Script to create the database, table and stored procedure

    This project saves jpgs, bmps, pdfs, etc. to a SQL Server Images table. The script is also included fromthe original project downloaded some time ago from the Web. The repeater that displays the list of items in the table on Default.aspx is not necessary for the purpose of this application. What is usuallydesired is to have a pdf store for such things as operating procedures or references that can be accessedand viewed through portal web sites or maintenance applications in a distributed Web. Obviously theapproach here will not show the pdf file in the image box, but as illustrated, images do display as thethumbnails.

    I posted this as a reference for anyone to find a complete example of what one would expect for a Webapplication that saves image/pdf data to the server and expects to read it back to a Web page. Havingimages, pdfs, Word, Powerpoint, Excel and other document formats in a database instead of externaldocuments lends extreme flexibility to the search process of the users. Replacements of documents area snap as opposed to writing over documents that are stored in folders on the Web site. Physicalstorage in folders presents access permissions issues that are easily handled with SQL Server.

    Although this example is for SQL Server, it can apply just a well to Microsoft Access (although this is nothighly recommend, but if your Web server is without SQL Server, it is an alternate approach), MySQL, orOracle. In each case, you will need to implement the appropriate framework for the database ( using System.Data.SqlClient; for SQL Server, using System.Data.OleDb; or .Odbc forODBC connectivity through an appropriate driver to your database).

    Good luck. There are many other examples of this in Google or Bing.

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    2/19

    You will need to enter the ID number for each record and select the appropriate

    Response.ContentType for that record. Obviously your production application will have all the

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    3/19

    features built-in so the user will not have to determine these details. So entering 1 and selectingimage/GIF will produce the following web page:

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    4/19

    If, instead, the user enters the id of 7 and selects the application/PDF Response.ContentType thispage appears, a pdf sheet music score that was saved earlier to SQL Server:

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    5/19

    Here is the client source for the Default.aspx page that provides the ability to upload into your SQL Servedatabase:

    Image Upload to DB

    Enter ID (1, 2, or a valid record id in the Images table: application/PDF application/vnd.ms-excel application/msword application/vnd.ms-

    powerpoint application/zip image/gif image/vnd.microsoft.icon image/jpeg text/html


    < asp : Button ID ="btnSubmitImageId" runat ="server" Text ="View Saved Byte Array"

    onclick ="btnSubmitImageId_Click" style =" height : 26px" />

    Enter a description for image
    < br />< br />Browse for your file (jpg only)
    < br

    />

    Images in Database
    < br />


    < br />

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    6/19

    Here is the C# code-behind for Default.aspx:

    using System;using System.IO;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;

    public partial class _Default : System.Web.UI. Page{

    protected void Page_Load( object sender, EventArgs e){

    // bind the list of images from the databaseif (!IsPostBack)

    repImages.DataSource = DataAccess .ListImages();

    DataBind();}

    protected void Submit_Click( object sender, EventArgs e){

    if (IsPostBack)HandleUploadedFile();

    }/// /// Method to handle pulling the files from the request and send them to the database///

    private void HandleUploadedFile(){

    // get the file instanceHttpPostedFile fi = Request.Files.Get(0);

    // get the descriptionstring description = Description.Text;

    // create a byte array to store the file bytes byte [] fileBytes = new byte [fi.ContentLength];

    // fill the byte array

    using (System.IO. Stream stream = fi.InputStream){stream.Read(fileBytes, 0, fi.ContentLength);

    }

    // insert the imageDataAccess .InsertImage(description, fileBytes);

    // bind the image listrepImages.DataSource = DataAccess .ListImages();DataBind();

    // clean upDescription.Text = "" ;fileBytes = null ;

    }

    /// /// on each item in the repeater setup the asp controls with some properties/// /// ///

    protected void repImages_ItemDataBound( object sender, RepeaterItemEventArgs e){

    // get our object from the datasourceDataAccess . ImageData item = ( DataAccess . ImageData )e.Item.DataItem;

    // get a reference to our controls in the item templateImage image = ( Image )e.Item.FindControl( "imageThumb" );

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    7/19

    Label label = ( Label )e.Item.FindControl( "labelDescription" );

    // set the image control properties. This is for the display of all the contentsin thumbnail format.

    if (image != null ){

    image.ImageUrl = string .Format( "~/Thumbnail.ashx?id={0}" , item.ID);image.AlternateText = item.Description;

    image.Visible = true ;}

    // set the image titleif (label != null ){

    label.Text = item.Description;label.Visible = true ;

    }}

    protected void btnSubmitImageId_Click( object sender, EventArgs e){

    //Here is where we send the request to view the page with our image data type resolved:if ( this .txtImageId.Text.Trim().Length > 0){

    Response.Redirect( "BinaryViewer.aspx?imageid=" + this .txtImageId.Text.Trim() +"&contenttype=" +

    this .listResponseTypes.Items[listResponseTypes.SelectedIndex].Value.ToString());}}

    }

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    8/19

    This nifty item, Thumbnail.ashx, allows you to create thumbnails and pass the image through it to be resolved asyour database contents. Image types (jpg or bmp) are necessary to be successfully displayed.

    < %@ WebHandler Language ="C#" Class ="Thumbnail" %>

    using System;using System.Drawing;using System.Drawing.Drawing2D;using System.Drawing.Imaging;using System.IO;using System.Web;

    public class Thumbnail : IHttpHandler {

    public void ProcessRequest ( HttpContext context){

    // Set up the response settingscontext.Response.ContentType = "image/jpeg" ;context.Response.Cache.SetCacheability( HttpCacheability .Public);context.Response.BufferOutput = false ;

    if (! string .IsNullOrEmpty(context.Request.QueryString[ "ID" ])){

    // get the id for the imageint id = Convert .ToInt32(context.Request.QueryString[ "ID" ]);

    // get the image as a byte array byte [] imageAsBytes = DataAccess .GetImageByID(id);

    // resize the image to a thumb (100)imageAsBytes = ResizeImageFile(imageAsBytes, 100);

    // put the byte array into a stream Stream stream = new MemoryStream (( byte [])imageAsBytes);

    // setup the chunking of the image data (good for large images)int buffersize = 1024 * 16;

    byte [] buffer = new byte [buffersize];

    // push the bytes to the output stream in chunksint count = stream.Read(buffer, 0, buffersize);while (count > 0){

    context.Response.OutputStream.Write(buffer, 0, count);count = stream.Read(buffer, 0, buffersize);

    }}

    }

    public bool IsReusable{

    get { return true ; }}

    /// /// Resizes an image/// /// the byte array of the file /// the target size of the file (may affect width or height)/// depends on orientation of file (landscape or portrait) /// Byte array containing the resized file

    private static byte [] ResizeImageFile( byte [] imageFile, int targetSize){

    using (System.Drawing. Image oldImage =System.Drawing. Image .FromStream( new MemoryStream (imageFile)))

    {Size newSize = CalculateDimensions(oldImage.Size, targetSize);

    using ( Bitmap newImage =

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    9/19

    new Bitmap (newSize.Width,newSize.Height, PixelFormat .Format24bppRgb))

    {using ( Graphics canvas = Graphics .FromImage(newImage)){

    canvas.SmoothingMode = SmoothingMode .AntiAlias;canvas.InterpolationMode = InterpolationMode .HighQualityBicubic;canvas.PixelOffsetMode = PixelOffsetMode .HighQuality;

    canvas.DrawImage(oldImage, new Rectangle ( new Point (0, 0), newSize));

    MemoryStream m = new MemoryStream ();newImage.Save(m, ImageFormat .Jpeg);return m.GetBuffer();

    }}

    }}

    /// /// Calculates the new size of the image based on the target size/// /// Is the size of the original file /// Is the target size of the resized file /// The new size

    private static Size CalculateDimensions( Size oldSize, int targetSize){Size newSize = new Size ();if (oldSize.Height > oldSize.Width){

    newSize.Width =( int )(oldSize.Width * (( float )targetSize / ( float )oldSize.Height));

    newSize.Height = targetSize;}else{

    newSize.Width = targetSize;newSize.Height =

    ( int )(oldSize.Height * (( float )targetSize / ( float )oldSize.Width));}return newSize;

    }

    }

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    10/19

    Here we keep some separation between our database connection and the clients. This is the DataAccess.cs class:

    using System;using System.Collections.Generic;using System.Configuration;using System.Data;using System.Data.SqlClient;using System.IO;using System.Linq;using System.Web;

    public class DataAccess{

    public DataAccess(){}

    public static byte [] GetImageByID( int ImageID){//string cnn = "Server=CQSFP260457\\MSSQL2008;Database=master;Trusted_Connection=True;";string cnn = ConfigurationManager .ConnectionStrings[ "LocalSqlServer" ].ConnectionString;

    using ( SqlConnection connection = new SqlConnection (cnn)){

    using ( SqlCommand command = new SqlCommand ( "dbo.up_GetImageByID" ,connection))

    {command.CommandType = CommandType .StoredProcedure;command.Parameters.Add( new SqlParameter ( "@ID" , ImageID));connection.Open();

    object result = command.ExecuteScalar();

    try{

    return ( byte [])result;}catch{

    return null ;}

    }}}

    public static void InsertImage( string description, byte [] imageAsBytes){

    //string cnn ="Server=CQSFP260457\\MSSQL2008;Database=master;Trusted_Connection=True;";

    string cnn = ConfigurationManager .ConnectionStrings[ "LocalSqlServer" ].ConnectionString;

    using ( SqlConnection connection = new SqlConnection (cnn)){

    using ( SqlCommand command = new SqlCommand ( "dbo.up_InsertImage" ,connection))

    {command.CommandType = CommandType .StoredProcedure;command.Parameters.Add( new SqlParameter ( "@description" ,

    description)); command.Parameters.Add( new SqlParameter ( "@imageAsBytes" ,imageAsBytes));

    connection.Open();command.ExecuteNonQuery();

    }}

    }

    public static List < ImageData > ListImages(){//string cnn = "Server=CQSFP260457\\MSSQL2008;Database=master;Trusted_Connection=True;";

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    11/19

    string cnn = ConfigurationManager .ConnectionStrings[ "LocalSqlServer" ].ConnectionString;

    using ( SqlConnection connection = new SqlConnection (cnn)){

    using ( SqlCommand command = new SqlCommand ( "dbo.up_ListImages" ,connection))

    {command.CommandType = CommandType .StoredProcedure;

    connection.Open();List < ImageData > list = new List < ImageData >();

    using ( SqlDataReader reader = command.ExecuteReader()){

    while (reader.Read()){

    ImageData item = new ImageData (){

    ID = ( int )reader[ "ID" ],Description = ( string )reader[ "Description" ]

    };

    list.Add(item);}

    }

    return list;}}

    }

    public class ImageData{

    public int ID { get ; set ; } public string Description { get ; set ; }

    public ImageData() { }}

    }

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    12/19

    Web. Config:

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    13/19

    symbols into the compiled page. Because thisaffects performance, set this value to true onlyduring development.

    -->

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    14/19

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    15/19

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    16/19

    BinaryViewer.aspx (Nothing but a default aspx page)

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    17/19

    BinaryViewer.aspx.csResolves the image datatype stream:using System;using System.Collections.Generic;using System.Linq;using System.Web;

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

    public partial class BinaryViewer : System.Web.UI. Page{

    protected void Page_Load( object sender, EventArgs e){

    if (Request.QueryString[ "imageid" ] != null &&Request.QueryString[ "contenttype" ] != null )

    {int id = System. Convert .ToInt32(Request.QueryString[ "imageid" ]);byte [] byteArray = DataAccess .GetImageByID(id);//Disply content type of PDF://Response.ContentType = "application/pdf";Response.ContentType =

    Request.QueryString[ "contenttype" ].ToString();Response.BinaryWrite(( byte [])byteArray);

    }}

    }

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    18/19

    SQL Script.sql:

    IF EXISTS ( SELECT * FROM dbo.sysobjects WHERE id =OBJECT_ID (N '[dbo].[Images]' ) AND OBJECTPROPERTY(id, N 'IsUserTable' ) = 1)DROP TABLE [dbo].[Images]GOIF EXISTS ( SELECT * FROM dbo.sysobjects WHERE id =OBJECT_ID (N '[dbo].[up_GetImageByID]' ) AND OBJECTPROPERTY(id,N 'IsProcedure' ) =1)DROP PROCEDURE [dbo].[up_GetImageByID]GOIF EXISTS ( SELECT * FROM dbo.sysobjects WHERE id =OBJECT_ID (N '[dbo].[up_InsertImage]' ) AND OBJECTPROPERTY(id,N 'IsProcedure' ) =1)DROP PROCEDURE [dbo].[up_InsertImage]GOIF EXISTS ( SELECT * FROM dbo.sysobjects WHERE id =OBJECT_ID (N '[dbo].[up_ListImages]' ) AND OBJECTPROPERTY(id,N 'IsProcedure' ) =1)DROP PROCEDURE [dbo].[up_ListImages]GO

    SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[Images](

    [ID] [int] IDENTITY (1,1) NOT NULL ,[Description] [nvarchar](50) NOT NULL ,[Image] [image] NOT NULL

    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]GO

    SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [dbo].[up_GetImageByID]

    @ID intAS

    SET NOCOUNT ON

    SELECT [Image] FROM Images WHERE ID = @IDGOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [dbo].[up_InsertImage]

    @description nvarchar(50),@imageAsBytes image

    AS

    INSERT INTO Images (Description, [Image])VALUES (@description, @imageAsBytes)

  • 8/14/2019 Database Techniques for Pictures, PDF and Other Byte Arrays

    19/19

    SELECT SCOPE_IDENTITY()GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [dbo].[up_ListImages]

    AS

    SELECT ID, Description FROM Images