|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
C# Photo Album ViewerThis sample is a C# Windows application that uses a SQL Server 2000 database to store and retrieve images. Images are organized under albums in a The Database TablesCREATE TABLE [dbo].[Albums] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[name] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[desc] [varchar] (200) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Photos] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[name] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[desc] [varchar] (200) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[album_id] [int] NOT NULL ,
[photo] [image] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
The Stored ProceduresCREATE PROC sp_GetPhotoAlbums AS
SELECT Albums.[id] AS AlbumID, Albums.[name] AS Album,
Albums.[desc] AS Album_Desc, Photos.[id] AS PhotoID,
Photos.[name] AS Photo, Photos.photo, Photos.[desc] AS Photo_Desc
FROM Albums INNER JOIN Photos ON Albums.[id] = Photos.album_id
ORDER BY Albums.[id]
GO
CREATE PROCEDURE sp_InsertPhoto
@name AS VARCHAR(50),
@image AS IMAGE,
@album AS INT
AS
INSERT INTO Photos ([name], photo, album_id)
VALUES (@name, @image, @album)
RETURN @@identity
GO
CREATE PROCEDURE sp_NewAlbum
@name AS VARCHAR(20)
AS
INSERT INTO Albums ([name])
VALUES (@name)
RETURN @@identity
GO
Storing the imagesAfter selecting the Add Photo context menu item a multi select The last step is to add the image to the private void OnAddPhoto(object sender, System.EventArgs e)
{
// Show the file open dialog
if( DialogResult.OK == FileOpenDlg.ShowDialog() )
{
// Retrieve the treeitem for the selected parent node
TreeItem item = (TreeItem)treeAlbum.SelectedNode.Tag;
// We allow multiple selections so loop through each one
foreach( string file in FileOpenDlg.FileNames )
{
// Create a new stream to load this photo into
System.IO.FileStream stream = new System.IO.FileStream(file,
System.IO.FileMode.Open,
System.IO.FileAccess.Read);
// Create a buffer to hold the stream bytes
byte[] buffer = new byte[stream.Length];
// Read the bytes from this stream
stream.Read(buffer, 0, (int)stream.Length);
// Now we can close the stream
stream.Close();
// Extract out the name of the file an use it for the name
// of the photo
string strName = System.IO.Path.GetFileNameWithoutExtension(file);
// Insert the image into the database and add it to the tree
InsertImage(ref buffer, strName, item.Id);
buffer = null;
}
// Select the last child node under this album
treeAlbum.SelectedNode = treeAlbum.SelectedNode.LastNode;
}
}
private void InsertImage(ref byte[] buffer, string strName, int nAlbum)
{
try
{
// Create a stored procedure command
SqlCommand cmd = new SqlCommand("sp_InsertPhoto", sqlConn);
cmd.CommandType = CommandType.StoredProcedure;
// Add the return value parameter
SqlParameter param = cmd.Parameters.Add("RETURN_VALUE", SqlDbType.Int);
param.Direction = ParameterDirection.ReturnValue;
// Add the name paramter and set the value
cmd.Parameters.Add("@name", SqlDbType.VarChar).Value = strName;
// Add the image paramter and set the value
cmd.Parameters.Add("@image", SqlDbType.Image).Value = buffer;
// Add the album paramter and set the value
cmd.Parameters.Add("@album", SqlDbType.Int).Value = nAlbum;
// Execute the insert
cmd.ExecuteNonQuery();
// Return value will be the index of the newly added photo
int nID = (int)cmd.Parameters["RETURN_VALUE"].Value;
// Create a new node
TreeNode node = new TreeNode(strName);
// Create new treeitem to store the info about this photo
node.Tag = new TreeItem(ItemType.Photo, nID, "Enter description");
// Get the index of the album we are adding to
// and insert the new photo node
nID = treeAlbum.SelectedNode.Index;
treeAlbum.Nodes[nID].Nodes.Add(node);
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
}
Display the imageThe AfterSelect event captures the selection of an image or album. If an images is selected the private void OnAfterSelect(object sender,
System.Windows.Forms.TreeViewEventArgs e)
{
try
{
// Disable edit controls if we were in edit mode
if( true == btnUpdate.Visible )
{
btnUpdate.Visible = false;
txtDesc.Visible = false;
lblDesc.Visible = true;
}
// Retrieve the item info for this node
TreeItem item = (TreeItem)e.Node.Tag;
// If the selected item is an album...
if( ItemType.Album == item.Type )
{
lblDesc.Text = item.Desc; // Set the description
pictureBox.Image = null; // Clear the image
return;
}
// ...otherwise it is a photo
// Create a command to select the selected photo
string strCmd = String.Format("SELECT photo FROM Photos WHERE id = {0}",
item.Id);
SqlCommand cmd = new SqlCommand(strCmd, sqlConn);
// Set the description
lblDesc.Text = item.Desc;
// Get bytes return from stored proc
byte[] b = (byte[])cmd.ExecuteScalar();
if(b.Length > 0)
{
// Open a stream for the image and write the bytes into it
System.IO.MemoryStream stream = new System.IO.MemoryStream(b, true);
stream.Write(b, 0, b.Length);
// Create a bitmap from the stream
Bitmap bmp = new Bitmap(stream);
// Check for scaling and assign the bitmap to the Picturebox
if( bmp.Width > 500 && bmp.Height > 300)
{
Bitmap bmp1 = new Bitmap(bmp, new Size(500,300));
pictureBox.Image = bmp1;
}
else
pictureBox.Image = bmp;
// Close the stream
stream.Close();
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
ConclusionThis is a relatively simple implementation of a photo album viewer application. Using .NET and C# definitely made this application very easy to make. Storing the images in a SQL Server database adds a bit to the distribution but also simplifies the application by having one source to store and retrieve images from. You also don't have to worry about missing files or broken links. One area in which this application can be improved is the scaling of the displayed images. Unfortunately I have not had the time to add this. Despite this limitation I felt the application sufficient to share with others for their benefit.
|
||||||||||||||||||||||