Creating the Class Picture

Now we add a new class Picture. You’ll find the code below.

The class has a persistent field of type byte[] that holds the picture data and passes it on to the database. Normally pictures are encapsulated in the .NET class System.Drawings.Image. But there is no automatic conversion available for image objects to database fields. We have to take care of the conversion by ourselves.

To the outside the class seems to accept Image objects. But if a picture is assigned to the property Image, it is converted into raw byte data. Vice versa, if someone retrieves the property, the raw byte array is converted to an image. The particular image is stored in the member variable image so that it is converted just once and not for every request. It is marked with the attribute NDOTransient to avoid NDO management of this variable.

Adapting the Mapping File

After building the application the file NDOMapping.xml in the project BusinessClasses needs to be opened. You can do this with the visual mapping tool, available with this button:

Look for the Class element with the name BusinessClasses.PictureHeader. For this element change the attribute TableName from PictureHeader to Picture (see the Picture below). 

After that, delete the file NDOMapping.xml from the project TestApp (you can do this in the Solution Explorer) and start a rebuild.

Preparing the Database

Each database handles the storing of raw data with another data type. Have a look at your documentation of how a picture can be stored. In Access the type is Oleobject and in Sql Server you can use the data type Image. Which type applies is determined by the NDO provider dll for the database.

The Class Code

Now here is the source code for the class Picture:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using NDO;
namespace BusinessClasses
{
    [NDOPersistent]
    public class Picture : PictureHeader
    {
        byte[] rawbytes = null;
        [NDOTransient]
        // cannot be stored directly
        Image image = null;

        public Image Image
        {
            get
            {
                if (rawbytes == null)
                  return null;
                if (image == null)
                {
                    System.IO.MemoryStream ms = new MemoryStream(rawbytes);
                    image = Image.FromStream(ms);
                }
                return image;
            }
            set
            {
                image = value;
                if (image == null)
                {
                    rawbytes = null;
                    return;
                }
                // horizontal align to 4 bytes
                int horsize = image.Size.Width * 3;
                int rest = horsize % 4;
                if (rest > 0) rest = 1;
                horsize = horsize / 4;
                horsize = (horsize + rest) * 4;
                int vertsize = image.Size.Height;
                rawbytes = new byte[horsize * vertsize + 56];
                System.IO.MemoryStream ms = new MemoryStream(rawbytes);
                image.Save(ms, ImageFormat.Bmp);
            }
        }

        public Picture()
        {
        }
    }
}