Пример #1
0
        /// <summary>
        /// Convert raw data to bitmap
        /// </summary>
        /// <param name="scan0">The pointer to the raw data</param>
        /// <param name="step">The step</param>
        /// <param name="size">The size of the image</param>
        /// <param name="srcColorType">The source image color type</param>
        /// <param name="numberOfChannels">The number of channels</param>
        /// <param name="srcDepthType">The source image depth type</param>
        /// <param name="tryDataSharing">Try to create Bitmap that shares the data with the image</param>
        /// <returns>The Bitmap</returns>
        public static Bitmap RawDataToBitmap(IntPtr scan0, int step, Size size, Type srcColorType, int numberOfChannels,
                                             Type srcDepthType, bool tryDataSharing = false)
        {
            if (tryDataSharing)
            {
                if (srcColorType == typeof(Gray) && srcDepthType == typeof(Byte))
                {
                    //Grayscale of Bytes
                    Bitmap bmpGray = new Bitmap(
                        size.Width,
                        size.Height,
                        step,
                        System.Drawing.Imaging.PixelFormat.Format8bppIndexed,
                        scan0
                        );

                    bmpGray.Palette = GrayscalePalette;

                    return(bmpGray);
                }
                // Mono in Linux doesn't support scan0 constructor with Format24bppRgb, use ToBitmap instead
                // See https://bugzilla.novell.com/show_bug.cgi?id=363431
                // TODO: check mono buzilla Bug 363431 to see when it will be fixed
                else if (
                    Emgu.Util.Platform.OperationSystem == Emgu.Util.Platform.OS.Windows &&
                    Emgu.Util.Platform.ClrType == Emgu.Util.Platform.Clr.DotNet &&
                    srcColorType == typeof(Bgr) && srcDepthType == typeof(Byte) &&
                    (step & 3) == 0)
                {
                    //Bgr byte
                    return(new Bitmap(
                               size.Width,
                               size.Height,
                               step,
                               System.Drawing.Imaging.PixelFormat.Format24bppRgb,
                               scan0));
                }
                else if (srcColorType == typeof(Bgra) && srcDepthType == typeof(Byte))
                {
                    //Bgra byte
                    return(new Bitmap(
                               size.Width,
                               size.Height,
                               step,
                               System.Drawing.Imaging.PixelFormat.Format32bppArgb,
                               scan0));
                }

                //PixelFormat.Format16bppGrayScale is not supported in .NET
                //else if (typeof(TColor) == typeof(Gray) && typeof(TDepth) == typeof(UInt16))
                //{
                //   return new Bitmap(
                //      size.width,
                //      size.height,
                //      step,
                //      PixelFormat.Format16bppGrayScale;
                //      scan0);
                //}
            }

            System.Drawing.Imaging.PixelFormat format; //= System.Drawing.Imaging.PixelFormat.Undefined;

            if (srcColorType == typeof(Gray))          // if this is a gray scale image
            {
                format = System.Drawing.Imaging.PixelFormat.Format8bppIndexed;
            }
            else if (srcColorType == typeof(Bgra)) //if this is Bgra image
            {
                format = System.Drawing.Imaging.PixelFormat.Format32bppArgb;
            }
            else if (srcColorType == typeof(Bgr)) //if this is a Bgr Byte image
            {
                format = System.Drawing.Imaging.PixelFormat.Format24bppRgb;
            }
            else
            {
                using (Mat m = new Mat(size.Height, size.Width, CvInvoke.GetDepthType(srcDepthType), numberOfChannels,
                                       scan0, step))
                    using (Mat m2 = new Mat())
                    {
                        CvInvoke.CvtColor(m, m2, srcColorType, typeof(Bgr));
                        return(RawDataToBitmap(m2.DataPointer, m2.Step, m2.Size, typeof(Bgr), 3, srcDepthType, false));
                    }
            }

            Bitmap bmp = new Bitmap(size.Width, size.Height, format);

            System.Drawing.Imaging.BitmapData data = bmp.LockBits(
                new Rectangle(Point.Empty, size),
                System.Drawing.Imaging.ImageLockMode.WriteOnly,
                format);
            using (Mat bmpMat = new Mat(size.Height, size.Width, CvEnum.DepthType.Cv8U, numberOfChannels, data.Scan0,
                                        data.Stride))
                using (Mat dataMat = new Mat(size.Height, size.Width, CvInvoke.GetDepthType(srcDepthType), numberOfChannels,
                                             scan0, step))
                {
                    if (srcDepthType == typeof(Byte))
                    {
                        dataMat.CopyTo(bmpMat);
                    }
                    else
                    {
                        double scale = 1.0, shift = 0.0;
                        RangeF range = dataMat.GetValueRange();
                        if (range.Max > 255.0 || range.Min < 0)
                        {
                            scale = range.Max.Equals(range.Min) ? 0.0 : 255.0 / (range.Max - range.Min);
                            shift = scale.Equals(0) ? range.Min : -range.Min * scale;
                        }

                        CvInvoke.ConvertScaleAbs(dataMat, bmpMat, scale, shift);
                    }
                }

            bmp.UnlockBits(data);

            if (format == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
            {
                bmp.Palette = GrayscalePalette;
            }
            return(bmp);
        }