1

我正在尝试将一个Bitmaps 数组合并为一个Bitmap. 给定一个像下面这样的Bitmap[,]数组b(假设这些是看起来像字符的图像):

b[0,0] = 1
b[1,0] = 2
b[0,1] = 3
b[1,1] = 4

我要生成

result = 12
         34

例如,给定以下四个Bitmaps:

b[0,0] =图片 0,0;

b[1,0] =图片 1,1;

b[0,1] =图片 0,1;

b[1,1] =图片 1,1;

我要生成 result =结果;

到目前为止,这是我的代码:

    public static Bitmap Moisac(ref Bitmap[,] b)
    {
        BitmapData[,] bmData = new BitmapData[b.GetUpperBound(0) + 1, b.GetUpperBound(1) + 1];
        IntPtr[,] scan0 = new IntPtr[b.GetUpperBound(0) + 1, b.GetUpperBound(1) + 1];
        unsafe
        {
            byte*[,] p = new byte*[b.GetUpperBound(0) + 1,b.GetUpperBound(1) + 1];
            for (int i = 0; i <= b.GetUpperBound(0); i++)
                for (int j = 0; j <= b.GetUpperBound(1); j++)
                    if (b[i, j].Width != b[0, 0].Width | b[i, j].Height != b[0, 0].Height)
                        throw new ArgumentException(
                            "Width and Height properties of all elements of b must be equal.",
                            "b");

            int oneW = b[0, 0].Width;
            int oneH = b[0, 0].Height;
            int overallWidth = oneW * (b.GetUpperBound(0) + 1);
            int overallHeight = oneH * (b.GetUpperBound(1) + 1);
            Bitmap result = new Bitmap(b[0, 0], overallWidth, overallHeight);

            for (int i = 0; i <= b.GetUpperBound(0); i++)
                for (int j = 0; j <= b.GetUpperBound(1); j++)
                {
                    bmData[i, j] = b[i, j].LockBits(new Rectangle(0, 0, oneW, oneH),
                                                    ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                    scan0[i, j] = bmData[i, j].Scan0;
                    p[i, j] = (byte*)(void*)scan0[i, j];
                }

            BitmapData rbmData = result.LockBits(new Rectangle(0, 0, overallWidth, overallHeight),
                                                 ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            int stride = bmData[0, 0].Stride;
            int nOffset = stride - 3*b[0, 0].Width;

            int rStride = rbmData.Stride;
            IntPtr rScan0 = rbmData.Scan0;
            byte* rp = (byte*) (void*) rScan0;

            for (int imgY = 0; imgY < b.GetUpperBound(1); ++imgY)
            {
                for (int imgX = 0; imgX <= b.GetUpperBound(0); ++imgX)
                {
                    byte* currp = p[imgX, imgY];
                    for (int y = 0; y < oneH; ++y)
                    {
                        for (int x = 0; x < 3*oneW; ++x)
                        {
                            rp[rStride*(imgY*oneH + y) + 3*imgX*oneW + x] = currp[0];
                            ++currp;
                        }
                        currp += nOffset;
                    }
                }
            }

            for (int i = 0; i <= b.GetUpperBound(0); i++)
                for (int j = 0; j <= b.GetUpperBound(1); j++)
                    b[i, j].UnlockBits(bmData[i,j]);


            result.UnlockBits(rbmData);
            return result;
        }
    }

在此处查看相册中的图像。它们都不会在这里显示。

4

2 回答 2

1

我犯了有史以来最愚蠢的错误。但是,如果它可以帮助任何人,请更改

for (int imgY = 0; imgY < b.GetUpperBound(1); ++imgY)

for (int imgY = 0; imgY <= b.GetUpperBound(1); ++imgY)

<应该是<=)。

于 2012-11-06T10:35:09.907 回答
0

我根据您的代码制作了一个版本,它复制像素行而不是像素。至少在我的盒子上似乎工作(更快)。也许你喜欢它。仅在 for each 循环内的最小更改。我真的只使用它来连接......在将图像扭曲成甜甜圈以获得多个相机图像的 360 度简单视图之前......

 public static Bitmap Mosaic(ref Bitmap[,] b)
    {
        BitmapData[,] bmData = new BitmapData[b.GetUpperBound(0) + 1, b.GetUpperBound(1) + 1];
        IntPtr[,] scan0 = new IntPtr[b.GetUpperBound(0) + 1, b.GetUpperBound(1) + 1];
        unsafe
        {
            byte*[,] p = new byte*[b.GetUpperBound(0) + 1, b.GetUpperBound(1) + 1];
            for (int i = 0; i <= b.GetUpperBound(0); i++)
                for (int j = 0; j <= b.GetUpperBound(1); j++)
                    if (b[i, j].Width != b[0, 0].Width | b[i, j].Height != b[0, 0].Height)
                        throw new ArgumentException(
                            "Width and Height properties of all elements of b must be equal.",
                            "b");

            int oneW = b[0, 0].Width;
            int oneH = b[0, 0].Height;
            int overallWidth = oneW * (b.GetUpperBound(0) + 1);
            int overallHeight = oneH * (b.GetUpperBound(1) + 1);
            Bitmap result = new Bitmap(b[0, 0], overallWidth, overallHeight);

            for (int i = 0; i <= b.GetUpperBound(0); i++)
                for (int j = 0; j <= b.GetUpperBound(1); j++)
                {
                    bmData[i, j] = b[i, j].LockBits(new Rectangle(0, 0, oneW, oneH),
                                                    ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                    scan0[i, j] = bmData[i, j].Scan0;
                    p[i, j] = (byte*)(void*)scan0[i, j];
                }

            BitmapData rbmData = result.LockBits(new Rectangle(0, 0, overallWidth, overallHeight),
                                                 ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

            int stride = bmData[0, 0].Stride;
            int nOffset = stride - 4 * b[0, 0].Width;

            int rStride = rbmData.Stride;
            IntPtr rScan0 = rbmData.Scan0;
            byte* rp = (byte*)(void*)rScan0;



            for (int imgY = 0; imgY <= b.GetUpperBound(1); ++imgY)
            {
                    for (int y = 0; y < oneH; ++y)
                    {
                        byte* currp = p[0, imgY];
                        for (int imgX = 0; imgX <= b.GetUpperBound(0); ++imgX)
                        {
                            currp = p[imgX, imgY];
                            currp += stride*y;
                        byte[] buffer = new byte[stride];
                        Marshal.Copy(new IntPtr(currp), buffer, 0, buffer.Length);
                        Marshal.Copy(buffer, 0, new IntPtr(rp), buffer.Length);

                        rp += stride;

                        }



                   }



            }

            for (int i = 0; i <= b.GetUpperBound(0); i++)
                for (int j = 0; j <= b.GetUpperBound(1); j++)
                    b[i, j].UnlockBits(bmData[i, j]);


            result.UnlockBits(rbmData);
            return result;
        }
    }
于 2014-06-02T23:57:18.927 回答