以位图像素查找CMYK计数

时间:2013-09-23 05:01:40

标签: c# wpf printing bitmap cmyk

  1. RGB位图到CMYK?
  2. 计算CMYK以读取颜色深度?
    1. 计算RGB值(完成),不转换RGB - > CMYK使用ICC配置文件
    2. 如何在位图中找到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&amp;的百分比。 K.如何在位图流中执行此操作?这可能很复杂,因为更简单的方法找到RGB,然后根据ICC US webcotedSWOP v2 .ICC ...

      将RGB转换为CMYK

      试着上面提到的,欣赏让我朝着正确的方向前进


      现在我已经在位图中获得了RGB的CMYK propotionate值,但不确定所需的百分比结果,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();
          }
      

1 个答案:

答案 0 :(得分:1)

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

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

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