【问题标题】:Converting Bitmap PixelFormats in C#在 C# 中转换位图像素格式
【发布时间】:2010-01-06 21:32:05
【问题描述】:

我需要将位图从PixelFormat.Format32bppRgb 转换为PixelFormat.Format32bppArgb

我希望使用 Bitmap.Clone,但它似乎不起作用。

Bitmap orig = new Bitmap("orig.bmp");
Bitmap clone = orig.Clone(new Rectangle(0,0,orig.Width,orig.Height), PixelFormat.Format24bppArgb);

如果我运行上面的代码然后检查 clone.PixelFormat 它被设置为PixelFormat.Format32bppRgb。发生了什么/如何转换格式?

【问题讨论】:

  • 这种情况只发生在 XP 上吗?我在 XP 上发现了这个问题,但它似乎在 Windows 7 上运行良好。Hans 的解决方案为我解决了这个问题。
  • 这很有趣。我有一个在 XP 上运行良好但在 Windows 7 上出现此错误的解决方案...
  • 我可以确认只有 XP 受到影响。
  • 您也应该注意不是 XP 的系统。我没有测试过这个特殊的代码,但是在 Windows 7 上比较两个图像时在像素级别上工作时,我遇到了由这个错误/功能引起的类似问题。 Dan7 准确地解释了正在发生的事情以及修复它的更一般的方法。
  • This 适用于所有平台(免责声明:由我撰写)。可以下载为NuGet

标签: c# .net image


【解决方案1】:

草率,对于 GDI+ 来说并不少见。这解决了它:

Bitmap orig = new Bitmap(@"c:\temp\24bpp.bmp");
Bitmap clone = new Bitmap(orig.Width, orig.Height,
    System.Drawing.Imaging.PixelFormat.Format32bppPArgb);

using (Graphics gr = Graphics.FromImage(clone)) {
    gr.DrawImage(orig, new Rectangle(0, 0, clone.Width, clone.Height));
}

// Dispose orig as necessary...

【讨论】:

  • 我遇到了与 OP 类似的问题,除了保存为 32BppArgb PNG 的 48BppRgb TIFF 存在问题。 GDI+ 无法正确转换并且生成的图像非常暗。这个解决方案允许我通过手动将图像重绘为 32BppRgb 来解决这个问题,所以 +1。
【解决方案2】:

由于某种原因,如果您从文件路径(即Bitmap bmp = new Bitmap("myimage.jpg");)创建Bitmap,并在其上调用Clone(),则返回的Bitmap 将不会被转换。

但是,如果您从旧的 Bitmap 创建另一个 BitmapClone() 将按预期工作。

试试这样的:

using (Bitmap oldBmp = new Bitmap("myimage.jpg"))
using (Bitmap newBmp = new Bitmap(oldBmp))
using (Bitmap targetBmp = newBmp.Clone(new Rectangle(0, 0, newBmp.Width, newBmp.Height), PixelFormat.Format32bppArgb))
{
    // targetBmp is now in the desired format.
}

【讨论】:

  • +1 感谢 Dan7 解释触发器是什么。我以前见过new Bitmap(new Bitmap("image.jpg")),但不知道为什么会这样。
  • 有没有一种简单的方法可以Clone 并转换位图的所有页面?我注意到targtBmp 只有oldBmp 中的活动框架。
  • 这比标记为“解决方案”要好 - 它适用于 Indexed PixelFormat 4bpp, 8bpp
【解决方案3】:
using (var bmp = new Bitmap(width, height, PixelFormat.Format24bppArgb))
using (var g = Graphics.FromImage(bmp)) {
  g.DrawImage(..);
}

应该这样工作。也许您想在g 上设置一些参数来定义质量等的插值模式。

【讨论】:

  • InterpolationMode 用于缩放,我真的不认为他想缩放它。也许做类似 bmp.SetResolution(old.Horizo​​ntalResolution, old.VerticalResolution) 并调用 g.DrawImageUnscaled(old, 0,0)。但这只是我的看法:)
  • @Elmue - 你对你的陈述有任何参考吗?MSDN 声明其他......
猜你喜欢
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
  • 2014-10-26
  • 1970-01-01
  • 2011-05-11
  • 2014-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多