将位图绘制到另一个上会产生扭曲的图像

时间:2016-08-05 21:34:37

标签: c# image-processing bitmap locking bitmapdata

我正在使用自定义类将图像写入另一个更大尺寸的图像。这是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;
        }
    }

这是生成扭曲的图像:

enter image description here

P.S。以下是输入图片:

enter image description here

1 个答案:

答案 0 :(得分:2)

    // 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()快,这是您应该总是喜欢的方法。