【问题标题】:Find CMYK counts in bitmap pixels查找位图像素中的 CMYK 计数
【发布时间】:2013-09-23 05:01:39
【问题描述】:
  1. RGB 位图转 CMYK?
  2. 计算 CMYK 以读取颜色深度?

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

如何查找位图中 CMYK 的百分比。类似于 Ghostscript API。我不能在我的程序中使用它,因为它不受管理且不支持并行处理。我已经使用 RGB (as per this) 做到了这一点 ,但为了便于打印机使用 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 的百分比。如何在位图流中做到这一点?这可能很复杂,对于更简单的方法 Find RGB and then Convert RGB to CMYK based on ICC US webcotedSWOP v2 .ICC...

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


现在我得到了位图中 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();
    }

【问题讨论】:

    标签: c# wpf printing bitmap cmyk


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢,打印时的新分隔是什么意思。扫描作业不用担心,仅供参考,这仅适用于现有的 PDF 文档,就像在 PDF Pro 中一样检查墨水覆盖率,当您检查输出预览以百分比为您提供每页的墨水覆盖率详细信息。我是通过 RGB 位图获得 RGB 百分比的,但我需要与 adobe CMYK 值匹配的准确解决方案。像像素中的 RGB 一样可以检测 CMYK?还是我需要使用任何公式将 RGB 转换为 CMYK?
    • 如果您不打算再次打印文档,那么问题就简单多了。然后,您仍然需要进行颜色转换。 RGB 颜色空间的色域不会唯一映射到 CMYK,因此您的结果可能不完全正确。您应该能够评估某种标准颜色范围以提供覆盖范围。如果必须以 CMYK 进行计算,则需要进行转换。您至少可以先尝试获得 RBG 的覆盖范围。
    • 我已经做到了,我现在有 RGB 覆盖细节,但是哪个最好是 RGB 值到 CMYK 转换或 RGB 位图到 CMYK 位图?
    • 我不确定这些有何不同。如果您正在谈论为这两种方法使用不同的 API,那么您将不得不查看它们各自的算法来决定哪个更好地保留了原始意图。在比较值时,您还需要考虑 CMYK 中的非唯一性。还要记住,大多数分色会选择性地重叠像素以使墨水透过。是否有理由无法比较 RGB 值?这些将不一样,但如果有足够的分辨率,应该可以给出代表性计数。
    猜你喜欢
    • 2014-04-19
    • 1970-01-01
    • 2016-06-21
    • 2013-02-08
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多