我有3个System.Drawing.Bitmap对象。 RGB前景,RGB背景和每像素掩码图像的单字节,其中0表示采用背景像素,1表示采用前景像素。这三个都是相同的维度。
我选择使用Bitmap对象,因为我需要最终在MonoTouch和MonoDroid中运行此代码。如果需要,我可以重新考虑。
我的代码已经过优化但仍然很慢。这也是整个操作中最慢的部分,所以我想更优化它。我也不禁想到有一些秘密的方法能为我做这一切。
如果有帮助的话。在此之前,所有3都是byte [],我将其转换为图像并重新调整为均匀尺寸。如果我能做得更好一步,请告诉我。
以下代码是我目前使用的代码,实质上是使用适当的前景像素更新背景图像。
BitmapData backgroundData = background.LockBits(new System.Drawing.Rectangle(0, 0, background.Width, background.Height), ImageLockMode.ReadOnly, background.PixelFormat);
int backgroundPixelSize = GetPixelSize(backgroundData);
BitmapData foregroundData = foreground.LockBits(new System.Drawing.Rectangle(0, 0, foreground.Width, foreground.Height), ImageLockMode.ReadOnly, foreground.PixelFormat);
int foregroundPixelSize = GetPixelSize(foregroundData);
BitmapData maskData = mask.LockBits(new System.Drawing.Rectangle(0, 0, mask.Width, mask.Height), ImageLockMode.ReadOnly, mask.PixelFormat);
//int maskPixelSize = GetPixelSize(maskData);
for (int y = 0; y < background.Height; y++)
{
byte* backgroundRow = (byte*)backgroundData.Scan0 + (y * backgroundData.Stride);
byte* foregroundRow = (byte*)foregroundData.Scan0 + (y * foregroundData.Stride);
byte* maskRow = (byte*)maskData.Scan0 + (y * maskData.Stride);
for (int x = 0; x < background.Width; x++)
{
// Check if the mask byte is set
if (maskRow[x] > 0)
{
// Copy the bytes over
for (int p = 0; p < backgroundPixelSize; p++)
{
backgroundRow[x * backgroundPixelSize + p] = foregroundRow[x * foregroundPixelSize + p];
}
}
}
}
更新 两个图像是每个像素3个字节,掩模图像是每个像素1个字节。
答案 0 :(得分:0)
您可以尝试使用此代码。我认为它更加快速和清晰(如果所有三个图像都具有相同的尺寸)。
BitmapData backgroundData = background.LockBits(
new System.Drawing.Rectangle(0, 0, background.Width, background.Height),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
BitmapData foregroundData = foreground.LockBits(
new System.Drawing.Rectangle(0, 0, foreground.Width, foreground.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData maskData = mask.LockBits(
new System.Drawing.Rectangle(0, 0, mask.Width, mask.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
uint* backgroundPtr = (uint*)backgroundData.Scan0;
uint* foregroundPtr = (uint*)foregroundData.Scan0;
uint* maskPtr = (uint*)maskData.Scan0;
int dataLength = backgroundData.Height * backgroundData.Width;
for (int i = 0; i < dataLength; i++)
if (maskPtr[i] > 0)
backgroundPtr[i] = foregroundPtr[i];
<强>更新强>
也可以使用掩码PixelFormat:
BitmapData maskData = mask.LockBits(
new System.Drawing.Rectangle(0, 0, mask.Width, mask.Height),
ImageLockMode.ReadOnly, mask.PixelFormat);
byte* maskPtr = (byte*)maskData.Scan0;
int dataLength = backgroundData.Height * backgroundData.Width;
for (int i = 0; i < dataLength; i++)
if (maskPtr[i] > 0)
backgroundPtr[i] = foregroundPtr[i];