如何使用 C# 在 ASP.NET 中识别 CMYK 图像
有谁知道如何使用 C# 正确识别 ASP.NET 中的 CMYK 图像?当我检查 Bitmap
实例的 Flags
属性时,我得到了不正确的结果。
我创建了三个图像来测试这一点:cmyk.jpg、rgb.jpg 和gray.jpg。它们分别是 CMYK、RGB 和灰度图像。
这是我的测试代码:
static void Main(string[] args)
{
Bitmap bmpCMYK = new Bitmap("cmyk.jpg");
Bitmap bmpRGB = new Bitmap("rgb.jpg");
Bitmap bmpGray = new Bitmap("gray.jpg");
Console.WriteLine("\t\tRgb\tCmyk\tGray\tYcbcr\tYcck\tPixelFormat");
Console.WriteLine("cmyk.jpg\t{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
IsSet(bmpCMYK, System.Drawing.Imaging.ImageFlags.ColorSpaceRgb),
IsSet(bmpCMYK, System.Drawing.Imaging.ImageFlags.ColorSpaceCmyk),
IsSet(bmpCMYK, System.Drawing.Imaging.ImageFlags.ColorSpaceGray),
IsSet(bmpCMYK, System.Drawing.Imaging.ImageFlags.ColorSpaceYcbcr),
IsSet(bmpCMYK, System.Drawing.Imaging.ImageFlags.ColorSpaceYcck),
bmpCMYK.PixelFormat);
Console.WriteLine("rgb.jpg\t\t{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
IsSet(bmpRGB, System.Drawing.Imaging.ImageFlags.ColorSpaceRgb),
IsSet(bmpRGB, System.Drawing.Imaging.ImageFlags.ColorSpaceCmyk),
IsSet(bmpRGB, System.Drawing.Imaging.ImageFlags.ColorSpaceGray),
IsSet(bmpRGB, System.Drawing.Imaging.ImageFlags.ColorSpaceYcbcr),
IsSet(bmpRGB, System.Drawing.Imaging.ImageFlags.ColorSpaceYcck),
bmpRGB.PixelFormat);
Console.WriteLine("gray.jpg\t{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
IsSet(bmpGray, System.Drawing.Imaging.ImageFlags.ColorSpaceRgb),
IsSet(bmpGray, System.Drawing.Imaging.ImageFlags.ColorSpaceCmyk),
IsSet(bmpGray, System.Drawing.Imaging.ImageFlags.ColorSpaceGray),
IsSet(bmpGray, System.Drawing.Imaging.ImageFlags.ColorSpaceYcbcr),
IsSet(bmpGray, System.Drawing.Imaging.ImageFlags.ColorSpaceYcck),
bmpGray.PixelFormat);
bmpCMYK.Dispose();
bmpRGB.Dispose();
bmpGray.Dispose();
Console.ReadLine();
}
private static bool IsSet(Bitmap bitmap, System.Drawing.Imaging.ImageFlags flag)
{
return (bitmap.Flags & (int)flag) == (int)flag;
}
这会产生以下输出:
我检查了实际图像,cmyk.jpg 确实是 CMYK 图像。
显然,这是一个“已知问题”。 Alex Gil 在 WPF 中遇到了同样的问题(请参阅此问题:如何识别 CMYK 图像使用 C#),他通过使用 BitmapDecoder
类加载图像来解决这个问题。我在 ASP.NET 中使用该解决方案有点不舒服,因为它要求我添加对 WindowsBase.dll 和PresentationCore.dll 的引用,而且我不确定是否希望在 Web 项目中使用它们。
有谁知道任何其他纯 .NET 解决方案来检查图像是否采用我可以在 ASP.NET 中安全使用的 CMYK 格式?
Does anybody know how to properly identify CMYK images in ASP.NET using C#? When I check the Flags
attribute of a Bitmap
instance, I get incorrect results.
I have created three images to test this: cmyk.jpg, rgb.jpg and gray.jpg. These are respectively CMYK, RGB and Grayscale images.
This is my test code:
static void Main(string[] args)
{
Bitmap bmpCMYK = new Bitmap("cmyk.jpg");
Bitmap bmpRGB = new Bitmap("rgb.jpg");
Bitmap bmpGray = new Bitmap("gray.jpg");
Console.WriteLine("\t\tRgb\tCmyk\tGray\tYcbcr\tYcck\tPixelFormat");
Console.WriteLine("cmyk.jpg\t{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
IsSet(bmpCMYK, System.Drawing.Imaging.ImageFlags.ColorSpaceRgb),
IsSet(bmpCMYK, System.Drawing.Imaging.ImageFlags.ColorSpaceCmyk),
IsSet(bmpCMYK, System.Drawing.Imaging.ImageFlags.ColorSpaceGray),
IsSet(bmpCMYK, System.Drawing.Imaging.ImageFlags.ColorSpaceYcbcr),
IsSet(bmpCMYK, System.Drawing.Imaging.ImageFlags.ColorSpaceYcck),
bmpCMYK.PixelFormat);
Console.WriteLine("rgb.jpg\t\t{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
IsSet(bmpRGB, System.Drawing.Imaging.ImageFlags.ColorSpaceRgb),
IsSet(bmpRGB, System.Drawing.Imaging.ImageFlags.ColorSpaceCmyk),
IsSet(bmpRGB, System.Drawing.Imaging.ImageFlags.ColorSpaceGray),
IsSet(bmpRGB, System.Drawing.Imaging.ImageFlags.ColorSpaceYcbcr),
IsSet(bmpRGB, System.Drawing.Imaging.ImageFlags.ColorSpaceYcck),
bmpRGB.PixelFormat);
Console.WriteLine("gray.jpg\t{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
IsSet(bmpGray, System.Drawing.Imaging.ImageFlags.ColorSpaceRgb),
IsSet(bmpGray, System.Drawing.Imaging.ImageFlags.ColorSpaceCmyk),
IsSet(bmpGray, System.Drawing.Imaging.ImageFlags.ColorSpaceGray),
IsSet(bmpGray, System.Drawing.Imaging.ImageFlags.ColorSpaceYcbcr),
IsSet(bmpGray, System.Drawing.Imaging.ImageFlags.ColorSpaceYcck),
bmpGray.PixelFormat);
bmpCMYK.Dispose();
bmpRGB.Dispose();
bmpGray.Dispose();
Console.ReadLine();
}
private static bool IsSet(Bitmap bitmap, System.Drawing.Imaging.ImageFlags flag)
{
return (bitmap.Flags & (int)flag) == (int)flag;
}
This produces the following output:
I have checked the actual images and cmyk.jpg really is a CMYK image.
Apparently, this is a "known issue". Alex Gil had the same problem in WPF (see this question: How to identify CMYK images using C#) and he managed to solve it by using a BitmapDecoder
class to load the images. I'm a bit uncomfortable using that solution in ASP.NET because it requires me to add references to WindowsBase.dll and PresentationCore.dll and I'm not sure I want those in a web project.
Does anyone know of any other pure .NET solutions to check if an image is in the CMYK format that I can safely use in ASP.NET?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我使用 ImageFlags 和 PixelFormat 值的组合。请注意,.NET 中缺少 PixelFormat.Forma32bppCMYK - 我从 Windows SDK 中的 GdiPlusPixelFormats.h 中获取了它。
窍门在于 Windows 7 和 Server 2008 R2 返回正确的像素格式,但缺少图像标志。 Vista 和 Server 2008 返回无效的像素格式,但返回正确的图像标志。疯狂。
I use a combination of the ImageFlags and PixelFormat values. Note that PixelFormat.Forma32bppCMYK is missing from .NET - I grabbed it out of GdiPlusPixelFormats.h in the Windows SDK.
The trick is that Windows 7 and Server 2008 R2 returns the correct pixel format but is missing the image flags. Vista and Server 2008 return an invalid pixel format but the correct image flags. Insanity.
一个想法:如果您不想在 Web 项目中引用这些 dll,您可以在 Web 项目之外的服务中进行处理,这可能会更好?
An idea: If you dont want to reference those dll's in your web project, you could do the processing outside the web project, in a service, which may be better anyway?
您可以查看 FreeImage,它是一个 win32 DLL,但有一个 .NET 包装器,我正在使用它在生产环境中,这非常棒。
如果它不能提供此信息,我会感到惊讶。
(编辑)在您要求纯 .NET 解决方案之前我没有注意到 - 所以也许这行不通 - 但我发现它是对 .NET 图像框架限制的有用补充操纵。
如果您只需要识别格式,另一个想法是直接从文件中提取格式。我不知道 JPEG 格式的规范可能有多复杂,但是,嘿,它只是 29页!
You might check out FreeImage which is a win32 DLL but has a .NET wrapper, I am using it in a production enviroment and it's great.
I would be surprised if it couldn't provide this information.
(edit) I didn't notice before you asked for pure .NET solutions - so maybe this won't work - but I have found it a useful supplement to the limitations of the .NET framework for image manipulation.
Another idea, if you only need to identify the format, is to extract that directly from the file. I have no idea how complex the specification for the JPEG format might be, but hey, it's only 29 pages!
正如之前回答的那样,最可靠的方法是解析文件头以检索此数据。
As previously answered, the most reliable way will be to parse the file's header to retrieve this data.
因此,这就是我解决您遇到的问题的方法,该问题与我遇到的问题相同。当您知道它是 100% cymk 图像时,csharp 中的所有内容都会返回 rgb 信息。那么该怎么办呢,我们去根目录读取文件。这是我所做的,并经过测试,效果良好,应该涵盖所有操作系统,并且 50 个图像中的 50 个图像经过正确测试。这也是 2.0 以防万一。
干杯-杰里米
So here is how I solved the issue you were having which was the same as what I was having. Everything in csharp looks to return rgb info when you know it's a 100% a cymk image. So what to do, well go to the root and read the file. Here is what I had done and tested to work well and should cover all OS's, and 50 for 50 imgs tested right. This is 2.0 too just in case.
cheers - Jeremy
我假设 .NET 中的所有内容都基于 RGB、aRGB 和灰度(因为灰度是 RGB(128, 128, 128))。
如果我的假设是正确的,那么您将不得不走第三方路线。
I was under the assumption that everything in .NET was based on
RGB
,aRGB
and grayscale (as grayscale is RGB(128, 128, 128)).If my assumption is correct then you will have to go the third party route.