我正在尝试将Bitmap
的数组合并为一个Bitmap
。给定Bitmap[,]
数组b
,如下所示(假设这些图像看起来像字符):
b[0,0] = 1
b[1,0] = 2
b[0,1] = 3
b[1,1] = 4
我想生成
result = 12
34
例如,给出以下四个Bitmap
s:
b[0,0] =
;
b[1,0] =
;
b[0,1] =
;
b[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;
}
}
查看相册here中的图片。所有这些都不会在这里显示。
答案 0 :(得分:1)
我犯了最愚蠢的错误。但是,如果它可以帮助任何人,请更改
for (int imgY = 0; imgY < b.GetUpperBound(1); ++imgY)
到
for (int imgY = 0; imgY <= b.GetUpperBound(1); ++imgY)
(<
应为<=
)。
答案 1 :(得分:0)
我根据你的代码创建了一个版本,它复制像素行而不是像素。似乎至少在我的盒子上工作(更快)。也许你喜欢它。每个循环内的最小变化。 我使用它真的只是为了连接......在将图像变形为甜甜圈之前,可以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;
}
}