/// <summary> /// The GetImageData function converts a Bitmap into a Datum. /// </summary> /// <param name="bmp">Specifies the Bitmap containing the image.</param> /// <param name="nChannels">Specifies the number of channels contained in the Bitmap (e.g. 3 = color, 1 = black and white).</param> /// <param name="bDataIsReal">Specifies whether or not to add each color to the List of <i>double</i> or to the list of <i>byte</i>. Using the <i>byte</i> array is more common for it already separates a 3 color Bitmap into 3 channels of data.</param> /// <param name="nLabel">Specifies the known label.</param> /// <returns>The Datum representing the image is returned.</returns> public static Datum GetImageData(Bitmap bmp, int nChannels, bool bDataIsReal, int nLabel) { if (nChannels != 1 && nChannels != 3) { throw new Exception("Images only support either 1 or 3 channels."); } List <byte>[] rgrgByteData = new List <byte> [nChannels]; List <double>[] rgrgRealData = new List <double> [nChannels]; for (int i = 0; i < nChannels; i++) { rgrgByteData[i] = new List <byte>(); rgrgRealData[i] = new List <double>(); } LockBitmap bmp1 = new LockBitmap(bmp); try { bmp1.LockBits(); for (int y = 0; y < bmp1.Height; y++) { for (int x = 0; x < bmp1.Width; x++) { Color clr = bmp1.GetPixel(x, y); if (nChannels == 1) { if (bDataIsReal) { rgrgRealData[0].Add(clr.ToArgb()); } else { rgrgByteData[0].Add((byte)((clr.R * 0.3) + (clr.G * 0.59) + (clr.B * 0.11))); } } else { if (bDataIsReal) { rgrgRealData[0].Add(clr.R); rgrgRealData[1].Add(clr.G); rgrgRealData[2].Add(clr.B); } else { rgrgByteData[0].Add(clr.R); rgrgByteData[1].Add(clr.G); rgrgByteData[2].Add(clr.B); } } } } } catch (Exception excpt) { throw excpt; } finally { bmp1.UnlockBits(); } List <byte> rgByteData = new List <byte>(); List <double> rgRealData = new List <double>(); for (int i = 0; i < nChannels; i++) { rgByteData.AddRange(rgrgByteData[i]); rgRealData.AddRange(rgrgRealData[i]); } if (bDataIsReal) { return(new Datum(true, nChannels, bmp.Width, bmp.Height, nLabel, DateTime.MinValue, null, new List <double>(rgRealData), 0, false, -1)); } else { return(new Datum(false, nChannels, bmp.Width, bmp.Height, nLabel, DateTime.MinValue, new List <byte>(rgByteData), null, 0, false, -1)); } }
/// <summary> /// The GetImageDataD function converts a Bitmap into a Datum using the <i>double</i> type for real data. /// </summary> /// <param name="bmp">Specifies the Bitmap containing the image.</param> /// <param name="nChannels">Specifies the number of channels contained in the Bitmap (e.g. 3 = color, 1 = black and white).</param> /// <param name="bDataIsReal">Specifies whether or not to add each color to the List of <i>double</i> or to the list of <i>byte</i>. Using the <i>byte</i> array is more common for it already separates a 3 color Bitmap into 3 channels of data.</param> /// <param name="nLabel">Specifies the known label.</param> /// <param name="bUseLockBitmap">Optionally, use the Lock Bitmap which is faster but may produce corrupted images in a few scenarios (default = true).</param> /// <param name="rgFocusMap">Optionally, specifies a focus map where values = 1 are used, and all other values are masked out to 0.</param> /// <returns>The Datum representing the image is returned.</returns> public static Datum GetImageDataD(Bitmap bmp, int nChannels, bool bDataIsReal, int nLabel, bool bUseLockBitmap = true, int[] rgFocusMap = null) { if (nChannels != 1 && nChannels != 3) { throw new Exception("Images only support either 1 or 3 channels."); } List <byte>[] rgrgByteData = new List <byte> [nChannels]; List <double>[] rgrgRealData = new List <double> [nChannels]; for (int i = 0; i < nChannels; i++) { rgrgByteData[i] = new List <byte>(); rgrgRealData[i] = new List <double>(); } if (bmp.Width >= bmp.Height && bUseLockBitmap) { LockBitmap bmp1 = new LockBitmap(bmp); try { bmp1.LockBits(); for (int y = 0; y < bmp1.Height; y++) { for (int x = 0; x < bmp1.Width; x++) { int nFocus = 1; if (rgFocusMap != null) { int nIdx = y * bmp1.Width + x; nFocus = rgFocusMap[nIdx]; } Color clr = (nFocus == 1) ? bmp1.GetPixel(x, y) : Color.Black; if (nChannels == 1) { if (bDataIsReal) { rgrgRealData[0].Add(clr.ToArgb()); } else { rgrgByteData[0].Add((byte)((clr.R * 0.3) + (clr.G * 0.59) + (clr.B * 0.11))); } } else { if (bDataIsReal) { rgrgRealData[0].Add(clr.R); rgrgRealData[1].Add(clr.G); rgrgRealData[2].Add(clr.B); } else { rgrgByteData[0].Add(clr.R); rgrgByteData[1].Add(clr.G); rgrgByteData[2].Add(clr.B); } } } } } catch (Exception excpt) { throw excpt; } finally { bmp1.UnlockBits(); } } // LockBitmap currently has a bug with images were bmp.Width < bmp.Height so in this case we use the slower Bitmap.GetPixel. else { for (int y = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++) { int nFocus = 1; if (rgFocusMap != null) { int nIdx = y * bmp.Width + x; nFocus = rgFocusMap[nIdx]; } Color clr = (nFocus == 1) ? bmp.GetPixel(x, y) : Color.Black; if (nChannels == 1) { if (bDataIsReal) { rgrgRealData[0].Add(clr.ToArgb()); } else { rgrgByteData[0].Add((byte)((clr.R * 0.3) + (clr.G * 0.59) + (clr.B * 0.11))); } } else { if (bDataIsReal) { rgrgRealData[0].Add(clr.R); rgrgRealData[1].Add(clr.G); rgrgRealData[2].Add(clr.B); } else { rgrgByteData[0].Add(clr.R); rgrgByteData[1].Add(clr.G); rgrgByteData[2].Add(clr.B); } } } } } List <byte> rgByteData = new List <byte>(); List <double> rgRealData = new List <double>(); for (int i = 0; i < nChannels; i++) { rgByteData.AddRange(rgrgByteData[i]); rgRealData.AddRange(rgrgRealData[i]); } if (bDataIsReal) { return(new Datum(true, nChannels, bmp.Width, bmp.Height, nLabel, DateTime.MinValue, new List <double>(rgRealData), 0, false, -1)); } else { return(new Datum(false, nChannels, bmp.Width, bmp.Height, nLabel, DateTime.MinValue, new List <byte>(rgByteData), 0, false, -1)); } }