C# 索引图像上的图形

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17313285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:08:15  来源:igfitidea点击:

Graphics on indexed image

c#imagegraphicsindexed-image

提问by Krivers

I am getting error:

我收到错误:

"A Graphics object cannot be created from an image that has an indexed pixel format."

“无法从具有索引像素格式的图像创建 Graphics 对象。”

in function:

在功能上:

public static void AdjustImage(ImageAttributes imageAttributes, Image image)
{
        Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);

        Graphics g = Graphics.FromImage(image);       
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imageAttributes);
        g.Dispose();
}

I would like to ask you, how can I fix it?

我想问你,我该如何解决?

采纳答案by Microsoft DN

Refering to this, it can be solved by creating a blank bitmap with the same dimensions and the correct PixelFormat and the draw on that bitmap.

参考this,可以通过创建具有相同尺寸和正确PixelFormat的空白位图并在该位图上绘制来解决。

// The original bitmap with the wrong pixel format. 
// You can check the pixel format with originalBmp.PixelFormat
Bitmap originalBmp = new (Bitmap)Image.FromFile("YourFileName.gif");

// Create a blank bitmap with the same dimensions
Bitmap tempBitmap = new Bitmap(originalBmp.Width, originalBmp.Height);

// From this bitmap, the graphics can be obtained, because it has the right PixelFormat
using(Graphics g = Graphics.FromImage(tempBitmap))
{
    // Draw the original bitmap onto the graphics of the new bitmap
    g.DrawImage(originalBmp, 0, 0);
    // Use g to do whatever you like
    g.DrawLine(...);
}

// Use tempBitmap as you would have used originalBmp
return tempBitmap;

回答by Bart Vanseer

The simplest way is to create a new image like this:

最简单的方法是创建一个像这样的新图像:

Bitmap EditableImg = new Bitmap(IndexedImg);

It creates a new image exactly like the original was with all its contents.

它创建一个与原始图像完全相同的新图像及其所有内容。

回答by Nyerguds

Overall, if you want to work with indexed images and actually preserve their colour depth and palette, this will always mean writing explicit checks and special code for them. Graphicssimply can't work with them, because it manipulates colours, and the actual pixels of indexed images contain no colours, just indices.

总的来说,如果您想使用索引图像并实际保留它们的颜色深度和调色板,这将始终意味着为它们编写明确的检查和特殊代码。Graphics根本无法使用它们,因为它操纵颜色,并且索引图像的实际像素不包含颜色,只包含索引。

For anyone still seeing this all these years later... the valid way to paint an image onto an existing (8-bit) indexed image is this:

对于多年后仍然看到这一点的任何人......将图像绘制到现有(8位)索引图像上的有效方法是:

  • Go over all the pixels of the image you want to paste and, for each colour, find the closest match on the target image's colour palette, and save its index into a byte array.
  • Open the backing bytes array of the indexed image using LockBits, and paste your matched bytes onto it, at the desired location, by looping over the relevant indices using the height and image stride.
  • 遍历要粘贴的图像的所有像素,对于每种颜色,在目标图像的调色板上找到最接近的匹配项,并将其索引保存到字节数组中。
  • 使用打开索引图像的后备字节数组LockBits,并通过使用高度和图像步幅循环相关索引,将匹配的字节粘贴到所需位置。

It's not an easy task, but it's certainly possible. If the pasted image is also indexed, and contains more than 256 pixels, you can speed up the process by doing the colour matching on the palette instead of on the actual image data, then getting the backing bytes from the other indexed image, and remapping them using the created mapping.

这不是一件容易的事,但这当然是可能的。如果粘贴的图像也被索引,并且包含超过 256 个像素,您可以通过在调色板上而不是实际图像数据上进行颜色匹配来加快进程,然后从另一个索引图像中获取支持字节,并重新映射他们使用创建的映射。

Note that all of this only applies to eight bit. If your image is four-bit or one-bit, the simplest way to handle it is to convert it to 8-bit first so you can handle it as one byte per pixel, and convert it back afterwards.

请注意,所有这些仅适用于八位。如果您的图像是 4 位或 1 位,最简单的处理方法是先将其转换为 8 位,这样您就可以将其作为每个像素一个字节处理,然后再将其转换回来。

For more information on that, see How can I work with 1-bit and 4-bit images?

有关更多信息,请参阅如何使用 1 位和 4 位图像?