将位图绘制到另一个位图上会产生扭曲的图像
Drawing a Bitmap onto another produces a distorted image
我正在使用自定义 class 将一个图像写到另一个更大尺寸的图像上。这是 DotNetFiddle 中的完整 source code。
我的自定义 GetPixel()
工作正常。但是下面的 SetPixel()
无法产生正确的输出。可能地址的计算出现了一些问题。但是,我无法检测到它。
public void SetPixel(int x, int y, Color color)
{
// Get color components count
int cCount = ColorDepth / 8;
// Get start index of the specified pixel
int i = ((y * Width) + x) * cCount;
//int i = ((x * Width) + y) * cCount;
if (ColorDepth == 32) // For 32 bpp set Red, Green, Blue and Alpha
{
_imageData[i] = color.B;
_imageData[i + 1] = color.G;
_imageData[i + 2] = color.R;
_imageData[i + 3] = color.A;
}
if (ColorDepth == 24) // For 24 bpp set Red, Green and Blue
{
_imageData[i] = color.B;
_imageData[i + 1] = color.G;
_imageData[i + 2] = color.R;
}
if (ColorDepth == 8)
{
// For 8 bpp set color value (Red, Green and Blue values are the same)
_imageData[i] = color.B;
string str = string.Empty;
}
}
这是在生成扭曲的图像:
.
P.S. 这是输入图像:
.
.
// Get start index of the specified pixel
int i = ((y * Width) + x) * cCount;
这是不正确的,无论是在 GetPixel 还是在 SetPixel 中。您会出现偏差,因为您忽略了 Stride。这是图像单个扫描线中的字节数。它是4的倍数对齐内存中的像素数据,有助于处理器更快地读取数据。修复:
int i = y * Stride + x * cCount;
您的代码中还隐藏着另一个错误,扫描线颠倒存储。换句话说,最后一个扫描线的数据首先被存储。但前提是 BitmapData.Height 不是负数。由于该错误同时出现在您的 GetPixel 和 SetPixel 方法中,因此它们相互抵消了。正确的代码是 (Height - y - 1) * Stride + x * cCount.
此代码并不比 Graphics.DrawImage() 快,您应该始终喜欢这种方法。
我正在使用自定义 class 将一个图像写到另一个更大尺寸的图像上。这是 DotNetFiddle 中的完整 source code。
我的自定义 GetPixel()
工作正常。但是下面的 SetPixel()
无法产生正确的输出。可能地址的计算出现了一些问题。但是,我无法检测到它。
public void SetPixel(int x, int y, Color color)
{
// Get color components count
int cCount = ColorDepth / 8;
// Get start index of the specified pixel
int i = ((y * Width) + x) * cCount;
//int i = ((x * Width) + y) * cCount;
if (ColorDepth == 32) // For 32 bpp set Red, Green, Blue and Alpha
{
_imageData[i] = color.B;
_imageData[i + 1] = color.G;
_imageData[i + 2] = color.R;
_imageData[i + 3] = color.A;
}
if (ColorDepth == 24) // For 24 bpp set Red, Green and Blue
{
_imageData[i] = color.B;
_imageData[i + 1] = color.G;
_imageData[i + 2] = color.R;
}
if (ColorDepth == 8)
{
// For 8 bpp set color value (Red, Green and Blue values are the same)
_imageData[i] = color.B;
string str = string.Empty;
}
}
这是在生成扭曲的图像:
.
P.S. 这是输入图像:
.
.
// Get start index of the specified pixel
int i = ((y * Width) + x) * cCount;
这是不正确的,无论是在 GetPixel 还是在 SetPixel 中。您会出现偏差,因为您忽略了 Stride。这是图像单个扫描线中的字节数。它是4的倍数对齐内存中的像素数据,有助于处理器更快地读取数据。修复:
int i = y * Stride + x * cCount;
您的代码中还隐藏着另一个错误,扫描线颠倒存储。换句话说,最后一个扫描线的数据首先被存储。但前提是 BitmapData.Height 不是负数。由于该错误同时出现在您的 GetPixel 和 SetPixel 方法中,因此它们相互抵消了。正确的代码是 (Height - y - 1) * Stride + x * cCount.
此代码并不比 Graphics.DrawImage() 快,您应该始终喜欢这种方法。