如何使用C#在ASP.NET中识别CMYK图像

Kri*_*aes 15 asp.net bitmap image-processing cmyk

有人知道如何使用C#在ASP.NET中正确识别CMYK图像吗?当我检查实例的Flags属性时Bitmap,我得到的结果不正确.

我已经创建了三个图像来测试它: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;
}
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出: 检测结果

我检查了实际图像,cmyk.jpg确实一个CMYK图像.

显然,这是一个"已知问题".Alex Gil在WPF中遇到了同样的问题(请参阅此问题:如何使用C#识别CMYK图像)并且他设法通过使用BitmapDecoder类来加载图像来解决它.我在ASP.NET中使用该解决方案有点不舒服,因为它要求我添加对WindowsBase.dll和PresentationCore.dll的引用,我不确定我是否想在Web项目中使用它们.

有没有人知道任何其他纯.NET解决方案来检查图像是否是我可以在ASP.NET中安全使用的CMYK格式?

Sha*_*ser 10

我使用ImageFlags和PixelFormat值的组合.请注意,.NET中缺少PixelFormat.Forma32bppCMYK - 我在Windows SDK中将其从GdiPlusPixelFormats.h中删除.

诀窍是Windows 7和Server 2008 R2返回正确的像素格式,但缺少图像标记.Vista和Server 2008返回无效的像素格式,但正确的图像标记.疯狂.

public ImageColorFormat GetColorFormat(this Bitmap bitmap)
{
    const int pixelFormatIndexed = 0x00010000;
    const int pixelFormat32bppCMYK = 0x200F;
    const int pixelFormat16bppGrayScale = (4 | (16 << 8);

    // Check image flags
    var flags = (ImageFlags)bitmap.Flags;
    if (flags.HasFlag(ImageFlags.ColorSpaceCmyk) || flags.HasFlag(ImageFlags.ColorSpaceYcck))
    {
        return ImageColorFormat.Cmyk;
    }
    else if (flags.HasFlag(ImageFlags.ColorSpaceGray))
    {
        return ImageColorFormat.Grayscale;
    }

    // Check pixel format
    var pixelFormat = (int)bitmap.PixelFormat;
    if (pixelFormat == pixelFormat32bppCMYK)
    {
        return ImageColorFormat.Cmyk;
    }
    else if ((pixelFormat & pixelFormatIndexed) != 0)
    {
        return ImageColorFormat.Indexed;
    }
    else if (pixelFormat == pixelFormat16bppGrayScale)
    {
        return ImageColorFormat.Grayscale;
    }

    // Default to RGB
    return ImageColorFormat.Rgb;
}    

public enum ImageColorFormat
{
    Rgb,
    Cmyk,
    Indexed,
    Grayscale
}
Run Code Online (Sandbox Code Playgroud)