C#中图形未定义,绘制到目标位图

3

这是我发布的第一个问题,请对我温柔一点,但欢迎提出如何改进我的问题以提高可读性的建议。

我试图使用图形来旋转一个 short 类型的数组。

我将 short 类型的数组读入到图像中,使用图形旋转它,然后将其存回到 short 类型的数组中。 然而,我发现图形处理程序并不像预期的那样工作,所以我简化了代码,看起来像这样:

首先,它使用 Marshal.Copy() 将一个简单的 short 数组(source48)复制到 src Bitmap 中。

   short[] source48= new short[]{255,255,255,2,2,2,5,5,5];
   int srcCols=3,int srcRows=1;
   Drawing.Bitmap srcImage = new Drawing.Bitmap(srcCols,srcRows, System.Drawing.Imaging.PixelFormat.Format48bppRgb);   
   System.Drawing.Imaging.BitmapData data = srcImage.LockBits(
                new Drawing.Rectangle(0, 0, srcCols, srcRows),
                System.Drawing.Imaging.ImageLockMode.WriteOnly,
                System.Drawing.Imaging.PixelFormat.Format48bppRgb);
   // Copy the source buffer to the bitmap
   Marshal.Copy(source48, 0, data.Scan0, source48.Length);
   // Unlock the bitmap of the input image again.
   srcImage.UnlockBits(data);
   data = null;             

然后它创建一个新的位图“rotatedImage”,并使用图形填充“rotatedImage”以使用“srcImage”(现在我先跳过实际的旋转)

  Drawing.Bitmap rotatedImage = new drawing.Bitmap(srcCols,srcRows,System.Drawing.Imaging.PixelFormat.Format48bppRgb);
  rotatedImage.SetResolution(srcImage.HorizontalResolution, srcImage.VerticalResolution);
  using (Drawing.Graphics g = Drawing.Graphics.FromImage(rotatedImage))
  {
        g.Clear(Drawing.Color.Black);
        g.DrawImage(srcImage, 0, 0);
  }

然后,我从“旋转”的图像中读取原始数据。
 data = rotatedImage.LockBits(
                new Drawing.Rectangle(0, 0, srcCols, srcRows),
                System.Drawing.Imaging.ImageLockMode.ReadOnly,
                System.Drawing.Imaging.PixelFormat.Format48bppRgb);
 // Copy the bulk from the output image bitmap to a 48bppRGB buffer
 short[] destination48 = new short[9];
 Marshal.Copy(data.Scan0, destination48, 0, destination48.Length);

很遗憾,我发现destination48中填充了{252, 252, 252, 2, 2, 2, 5, 5, 5},而不是期望的[255, 255, 255, 2, 2, 2, 5, 5, 5]。
我尝试过填充背景、绘制矩形等,但真的不知道为什么目标位图中的数据不包含源图像中的数据。图形的准确性是否受到影响?

如果您先保存Bitmap并检查图像会怎样? - Jeroen van Langen
另外,Format48bppRgb * srcCols * srcRows 不等于 sizeof(short) * srcCols * srcRows - Jeroen van Langen
Marshall.copy需要以字节为单位的大小。尝试使用destination.length * sizeof(short)。 - Jeroen van Langen
@JeroenvanLangen 如果我尝试那样做,就会得到一个超出范围的异常。仍然存在一些未定义的行为。如果我将short数组更改为: [1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0] ,并且 srcRows = 3 和srcColumns = 2。 结果是 [0 0 0 2 0 0 2 0 0 0 0 0 5 0 0 5 0 0]。我现在很困惑。 - Deltadaniel
1个回答

0
在 MSDN 上,有一条评论 指出:

PixelFormat48bppRGB、PixelFormat64bppARGB 和 PixelFormat64bppPARGB 使用每个颜色分量(通道)16 位。GDI+ 版本 1.0 和 1.1 可以读取 16 位每通道图像,但这些图像会被转换为 8 位每通道格式进行处理、显示和保存。每个 16 位颜色通道可以容纳 0 到 2^13 的值。

我猜这就是导致精度丢失的原因。
也许您可以选择 Format24bppRgb 并使用每个 short 两个像素;当将 srcCols 的值设置为其两倍时,它似乎能够返回您示例的正确结果。

是的,没错。这绝对是原因!我猜这是方法固有的问题?所以我想没有办法解决这个问题(比如重新调整图像大小)? - Deltadaniel
@Deltadaniel 我能想到的唯一方法就是使用 Format24bppRgb 和每个 short 两个“像素”。 - C.Evenhuis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接