コード例 #1
0
        /// <summary>
        /// OpenCVのMatを指定した出力先にSystem.Drawing.Bitmapとして変換する
        /// </summary>
        /// <param name="src">変換するMat</param>
        /// <param name="dst">出力先のSystem.Drawing.Bitmap</param>
        /// <remarks>Author: shimat, Gummo (ROI support)</remarks>
#else
        /// <summary>
        /// Converts Mat to System.Drawing.Bitmap
        /// </summary>
        /// <param name="src">Mat</param>
        /// <param name="dst">Mat</param>
        /// <remarks>Author: shimat, Gummo (ROI support)</remarks>
#endif
        public static unsafe void ToBitmap(this Mat src, Bitmap dst)
        {
            if (src == null)
                throw new ArgumentNullException("src");
            if (dst == null)
                throw new ArgumentNullException("dst");
            if (src.IsDisposed)
                throw new ArgumentException("The image is disposed.", "src");
            if (src.Depth() != MatType.CV_8U)
                throw new ArgumentException("Depth of the image must be CV_8U");
            //if (src.IsSubmatrix())
            //    throw new ArgumentException("Submatrix is not supported");
            if (src.Width != dst.Width || src.Height != dst.Height)
                throw new ArgumentException("");

            PixelFormat pf = dst.PixelFormat;

            // 1プレーン用の場合、グレースケールのパレット情報を生成する
            if (pf == PixelFormat.Format8bppIndexed)
            {
                ColorPalette plt = dst.Palette;
                for (int x = 0; x < 256; x++)
                {
                    plt.Entries[x] = Color.FromArgb(x, x, x);
                }
                dst.Palette = plt;
            }

            int w = src.Width;
            int h = src.Height;
            Rectangle rect = new Rectangle(0, 0, w, h);
            BitmapData bd = null;

            bool submat = src.IsSubmatrix();
            bool continuous = src.IsContinuous();

            try
            {
                bd = dst.LockBits(rect, ImageLockMode.WriteOnly, pf);

                IntPtr srcData = src.Data;
                byte* pSrc = (byte*)(srcData.ToPointer());
                byte* pDst = (byte*)(bd.Scan0.ToPointer());
                int ch = src.Channels();
                int sstep = (int)src.Step();
                int dstep = ((src.Width * ch) + 3) / 4 * 4; // 4の倍数に揃える
                int stride = bd.Stride;

                switch (pf)
                {
                    case PixelFormat.Format1bppIndexed:
                    {
                        if (submat)
                            throw new NotImplementedException("submatrix not supported");

                        // BitmapDataは4byte幅だが、IplImageは1byte幅
                        // 手作業で移し替える				 
                        //int offset = stride - (w / 8);
                        int x = 0;
                        int y;
                        int bytePos;
                        byte mask;
                        byte b = 0;
                        int i;
                        for (y = 0; y < h; y++)
                        {
                            for (bytePos = 0; bytePos < stride; bytePos++)
                            {
                                if (x < w)
                                {
                                    for (i = 0; i < 8; i++)
                                    {
                                        mask = (byte)(0x80 >> i);
                                        if (x < w && pSrc[sstep * y + x] == 0)
                                            b &= (byte)(mask ^ 0xff);
                                        else
                                            b |= mask;

                                        x++;
                                    }
                                    pDst[bytePos] = b;
                                }
                            }
                            x = 0;
                            pDst += stride;
                        }
                        break;
                    }

                    case PixelFormat.Format8bppIndexed:
                    case PixelFormat.Format24bppRgb:
                    case PixelFormat.Format32bppArgb:
                        if (sstep == dstep && !submat && continuous)
                        {
                            uint imageSize = (uint)(src.DataEnd.ToInt64() - src.Data.ToInt64());
                            Utility.CopyMemory(pDst, pSrc, imageSize);
                        }
                        else
                        {
                            for (int y = 0; y < h; y++)
                            {
                                long offsetSrc = (y * sstep);
                                long offsetDst = (y * dstep);
                                // 一列ごとにコピー
                                Utility.CopyMemory(pDst + offsetDst, pSrc + offsetSrc, w * ch);
                            }
                        }
                        break;

                    default:
                        throw new NotImplementedException();
                }
            }
            finally
            {
                dst.UnlockBits(bd);
            }
        }
コード例 #2
0
        /// <summary>
        /// OpenCVのMatをSystem.Drawing.Bitmapに変換する
        /// </summary>
        /// <param name="src">変換するMat</param>
        /// <returns>System.Drawing.Bitmap</returns>
#else
        /// <summary>
        /// Converts Mat to System.Drawing.Bitmap
        /// </summary>
        /// <param name="src">Mat</param>
        /// <returns></returns>
#endif
        public static Bitmap ToBitmap(this Mat src)
        {
            if (src == null)
            {
                throw new ArgumentNullException("src");
            }

            PixelFormat pf;
            switch (src.Channels())
            {
                case 1:
                    pf = PixelFormat.Format8bppIndexed; break;
                case 3:
                    pf = PixelFormat.Format24bppRgb; break;
                case 4:
                    pf = PixelFormat.Format32bppArgb; break;
                default:
                    throw new ArgumentException("Number of channels must be 1, 3 or 4.", "src");
            }
            return ToBitmap(src, pf);
        }