//
// This source code is licensed for commercial and non-commercial use under the
// Code Project Open License (CPOL) 1.02 http://www.codeproject.com/info/cpol10.aspx
// Developer: Joerg Lang (lang.joerg@gmail.com)
//
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
namespace DbDzComposer
{
public class DzDbAccess : IDzDbPersistance
{
private OleDbConnection dbConnection;
/// <summary>
/// Gets or sets the db connection.
/// </summary>
/// <value>The db connection.</value>
public override IDbConnection DbConnection
{
get { return dbConnection; }
set { dbConnection = (OleDbConnection)value; }
}
/// <summary>
/// Saves the basic information about an image.
/// </summary>
/// <param name="imageName">Name of the image.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="tileSize">Size of the tile.</param>
/// <param name="overlap">The overlap.</param>
/// <param name="mimeType">The mime type of the tiles</param>
/// <param name="thumbnail">A thumbnail preview</param>
/// <returns></returns>
public override int SaveImageInfo(string imageName, int width, int height, int tileSize, int overlap,
string mimeType,
Bitmap thumbnail)
{
// Create the sql
string sql =
"INSERT INTO DeepZoomImage(imageId, imageName, width, height, tileSize, overlap, mimeType, thumbnail) values (?, ?, ?, ?, ?, ?, ?, ?)";
var cmd = new OleDbCommand(sql, dbConnection);
// Get the next available id
int newId = GetNextDeepZoomImageId();
// Add the parameters
cmd.Parameters.Add("@imageid", OleDbType.Integer).Value = newId;
cmd.Parameters.Add("@imageName", OleDbType.VarChar).Value = imageName;
cmd.Parameters.Add("@width", OleDbType.Integer).Value = width;
cmd.Parameters.Add("@height", OleDbType.Integer).Value = height;
cmd.Parameters.Add("@tileSize", OleDbType.Integer).Value = tileSize;
cmd.Parameters.Add("@overlap", OleDbType.Integer).Value = overlap;
cmd.Parameters.Add("@mimeType", OleDbType.VarChar).Value = mimeType;
if (thumbnail != null)
cmd.Parameters.Add("@thumbnail", OleDbType.LongVarBinary).Value = BitmapToByteArray(thumbnail);
else
cmd.Parameters.Add("@thumbnail", OleDbType.LongVarBinary).Value = DBNull.Value;
// Execute it
cmd.ExecuteNonQuery();
// return the new id
return newId;
}
/// <summary>
/// Gets a list with the information about the images.
/// </summary>
/// <param name="fromUri">The Url from which the call is made.</param>
/// <returns></returns>
public override List<ImageInfo> GetImageInfo(Uri fromUri)
{
// Prepare the sql and the dataset
string sql = "Select * from DeepZoomImage order by imageName";
var dataAdapter = new OleDbDataAdapter(sql, dbConnection);
var ds = new DataSet();
// Fill the dataset
dataAdapter.Fill(ds, "ImageInfo");
// Use Linq to convert the dataset into a list of ImageInfo objects.
var imageInfos = from image in ds.Tables["ImageInfo"].AsEnumerable()
select new ImageInfo
{
ImageId = image.Field<int>("ImageId"),
ImageName = image.Field<string>("ImageName"),
Height = image.Field<int>("Height"),
Width = image.Field<int>("Width"),
TileSize = image.Field<int>("TileSize"),
Overlap = image.Field<int>("Overlap"),
MimeType = image.Field<string>("MimeType"),
ThumbnailUrl = new Uri(fromUri,
"ThumbnailHandler.ashx?ImageId=" +
image.Field<int>("ImageId")).ToString()
};
return imageInfos.ToList();
}
/// <summary>
/// Gets the next deep zoom image id.
/// </summary>
/// <returns></returns>
private int GetNextDeepZoomImageId()
{
string sql = "Select max(imageId) as nextId from DeepZoomImage";
var cmd = new OleDbCommand(sql, dbConnection);
object o = cmd.ExecuteScalar();
if (o == DBNull.Value)
return 1;
else
return ((int)o) + 1;
}
/// <summary>
/// Saves one image tile to a image that was created before using the SaveImageInfo method.
/// </summary>
/// <param name="imageId">The image id.</param>
/// <param name="level">The level.</param>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
/// <param name="bitmap">The bitmap.</param>
public override void SaveImageTile(int imageId, int level, int x, int y, Bitmap bitmap)
{
// Create the sql
string sql = "INSERT INTO DeepZoomTile(imageId, [level], x, y, bitmap) values (?, ?, ?, ?, ?)";
var cmd = new OleDbCommand(sql, dbConnection);
//serialise the image
byte[] bytes = BitmapToByteArray(bitmap);
// Add the parameters
cmd.Parameters.Add("@imageid", OleDbType.Integer).Value = imageId;
cmd.Parameters.Add("@level", OleDbType.Integer).Value = level;
cmd.Parameters.Add("@x", OleDbType.Integer).Value = x;
cmd.Parameters.Add("@y", OleDbType.Integer).Value = y;
cmd.Parameters.Add("@bitmap", OleDbType.LongVarBinary, bytes.Length).Value = bytes;
// Execute it
cmd.ExecuteNonQuery();
}
/// <summary>
/// Gets the image tile requested by the level, and the x and y coordinates for a specific image.
/// </summary>
/// <param name="imageId">The image id.</param>
/// <param name="level">The level.</param>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
/// <returns></returns>
public override Bitmap GetImageTile(int imageId, int level, int x, int y)
{
try
{
string sql = "select bitmap from deepZoomTile where imageId = {0} and level={1} and x = {2} and y = {3}";
sql = String.Format(sql, imageId, level, x, y);
var cmd = new OleDbCommand(sql, dbConnection);
object o = cmd.ExecuteScalar();
Bitmap bmp = BitmapFromByteArray((byte[])o);
return bmp;
}
catch (Exception)
{
return new Bitmap(1, 1);
}
}
/// <summary>
/// Gets the thumbnail for a specifig image
/// </summary>
/// <param name="imageId">The image id.</param>
/// <returns></returns>
public override Bitmap GetThumbnail(int imageId)
{
try
{
string sql = "select thumbnail from deepZoomImage where imageId = {0}";
sql = String.Format(sql, imageId);
var cmd = new OleDbCommand(sql, dbConnection);
object o = cmd.ExecuteScalar();
Bitmap bmp = BitmapFromByteArray((byte[])o);
return bmp;
}
catch (Exception)
{
return new Bitmap(1, 1);
}
}
/// <summary>
/// Serializes a bitmap to an byte array
/// </summary>
/// <param name="bitmap">The bitmap.</param>
/// <returns></returns>
private static byte[] BitmapToByteArray(Bitmap bitmap)
{
var memStream = new MemoryStream();
var formatter = new BinaryFormatter();
formatter.Serialize(memStream, bitmap);
byte[] bytes = memStream.GetBuffer();
memStream.Close();
return bytes;
}
/// <summary>
/// Gets the bitmap from a byte array.
/// </summary>
/// <param name="bytes">The byte array.</param>
/// <returns></returns>
private static Bitmap BitmapFromByteArray(byte[] bytes)
{
var formatter = new BinaryFormatter();
var memStream = new MemoryStream(bytes);
var bmp = (Bitmap)formatter.Deserialize(memStream);
memStream.Close();
return bmp;
}
}
}