1
  1. RGB位图转CMYK?
  2. 数 CMYK 来读取颜色深度?

或者

  1. 计算 RGB 值(完成),不转换 RGB --> CMYK 使用 ICC 配置文件

如何在位图中查找 CMYK 的百分比。类似于 Ghostscript API。我不能在我的程序中使用它,因为它不受管理且不支持并行处理。我已经使用 RGB (按此)完成了此操作 ,但为了便于打印机使用 CMYK 中的此功能。

    public static bool IsCMYK(System.Drawing.Image image)
    {
        var flags = (ImageFlags)image.Flags;
        if (flags.HasFlag(ImageFlags.ColorSpaceCmyk) || flags.HasFlag(ImageFlags.ColorSpaceYcck))
        {
            return true;
        }

        const int PixelFormat32bppCMYK = (15 | (32 << 8));
        return (int)image.PixelFormat == PixelFormat32bppCMYK;
    } 

    public void ImagemagicTool(Bitmap bi)
    {
        ImageMagick.MagickImage img = new MagickImage(bi);
        string str= img.ColorSpace.ToString();
    }
    public ImageColorFormat GetColorFormat(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;
    }

*更新:看起来我必须分离图层 CMYK,然后找到每个 C、M、Y 和 K 的百分比。我该如何在位图流中做到这一点?这可能很复杂,对于更简单的方法,查找 RGB,然后基于 ICC US webcotedSWOP v2 .ICC 将 RGB 转换为 CMYK...

只是尝试上面提到的,感谢让我朝着正确的方向前进


现在我在位图中得到了 RGB 的 CMYK 比例值,但不确定所需的百分比结果,CMYK 有上限吗?

public static CMYK RGBtoCMYK(int red, int green, int blue)
    {
        double c = (double)(255 - red) / 255;
        double m = (double)(255 - green) / 255;
        double y = (double)(255 - blue) / 255;

        double min = (double)Math.Min(c, Math.Min(m, y));
        if (min == 1.0)
        {
            return new CMYK(0, 0, 0, 1);
        }
        else
        {
            return new CMYK((c - min) / (1 - min), (m - min) / (1 - min), (y - min) / (1 - min), min);
        }
    }

  public class CMYK
{
    public double Cyan { get; set; }
    public double Magenta { get; set; }
    public double Yellow { get; set; }
    public double Black { get; set; }
    public CMYK()
    {
    }
    public CMYK(double cyan, double magenta, double yellow,double black)
    {
        Cyan = cyan;
        Magenta = magenta;
        Yellow = yellow;
        Black = black;
    }
}
public static void GetRGBlock(Bitmap bmp)
    {
        System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
        System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
        IntPtr ptr = bmpData.Scan0;
        List<System.Drawing.Color> cols = new List<System.Drawing.Color>();
        int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
        byte[] rgbValues = new byte[bytes];
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

        int x = 0;
        int y = 0;
        int dx = 0;
        int l = 0;
        for (y = 0; y <= rect.Height - 1; y++)
        {
            l = y * bmpData.Stride;
            //calulate line based on stride
            for (x = 0; x <= rect.Width - 1; x++)
            {
                dx = l + x * 3;
                //3 for RGB, 4 for ARGB, notice l is used as offset
                cols.Add(System.Drawing.Color.FromArgb(rgbValues[dx + 2], rgbValues[dx + 1], rgbValues[dx]));
            }
        }          

        List<CMYK> cmykcols = new List<CMYK>();
        foreach (var item in cols)
            cmykcols.Add(RGBtoCMYK(item.R, item.G, item.B));

        bmp.UnlockBits(bmpData);
        bmp.Dispose();
    }
4

1 回答 1

1

扫描仪可能使用 RGB 颜色模型来存储图像。如果要恢复接近真实分色的内容,则需要以远高于原始屏幕的分辨率扫描图像,然后找到各个彩色点。

一般来说,这是不可能的,因为 CMYK 颜色可以故意重叠打印,并且由于墨水、纸张和读者感知而导致的打印中的许多非线性色彩空间效应会使这变得复杂。

您最好的方法可能是恢复 RGB 位图,然后在打印时再次创建新的分色。问题是您可能会在生成的图像中看到莫尔伪影。

于 2013-09-23T12:17:58.120 回答