1

I want to paint some Graphics2D objects, using java printing mechanism. So i have to define a subclass of Printable.

public class PrintCMYK() implements Printable {
      public int print(Graphics g, PageFormat pf, int page)
                                           throws PrinterException {
          g.setColor(Color.RED);
          g.fillOval(44, 44, 100, 100);
      }
}

So this code just prints a red rgb circle. Java probably converts somehow rgb color in some CMYK, to be able to print it with CMYK. But i want a full control here. So can i somehow explicit set wanted CMYK color. Something like

public class PrintCMYK() implements Printable {
      public int print(Graphics g, PageFormat pf, int page)
                                           throws PrinterException {
          float[] ff = {0, 1, 0, 0}; // pure magenta
          Color cmykColor = new Color(ColorSpace.getInstance(TYP_CMYK), ff, 1);
          g.setPaint(cmykColor);
          g.fillOval(44, 44, 100, 100);
      }
}

This code does not work unfortunately.

UPD: In Postscript produces by java code used instruction setrgbcolor but i need setcmykcolor. Can i achieve this behavior somehow?

AvrDragon
  • 7,139
  • 4
  • 27
  • 42

3 Answers3

2

There's no simple way to do it - because there is no exact algorithm for conversion between RGB and CMYK. If you are forced to use CMYK color space you have 2 ways out:

  1. Approximate conversion between RGB and CMYK and vice versa (http://www.javascripter.net/faq/rgb2cmyk.htm , http://www.rapidtables.com/convert/color/cmyk-to-rgb.htm)

  2. using a profile (RGB to CMYK and back algorithm)

EDIT:

RGB describes computer monitor colors. CMYK describes printing colors. You don't need to care about that - CMYK is printer dependent, Just use RGB and printing will be fine.

EDIT 2: How to ensure printing colors are the closest to the desired ones: http://desktoppub.about.com/cs/colorcalibration/a/cal_printer.htm?terms=color+calibration

Community
  • 1
  • 1
Alexi Akl
  • 1,934
  • 1
  • 21
  • 20
  • but i don't need/want to convert to RGB, i am already using CMYK values and typical printer uses cmyk. So i just need to set a cmyk color, without any conversion. But i can not find any interface in Grapics2D to do that. – AvrDragon Mar 19 '13 at 15:20
  • RGB describes computer colors. CMYK describes printing colors. You don't need to care about that - CMYK is printer dependent, Just use RGB and printing will be fine. – Alexi Akl Mar 19 '13 at 15:30
  • unfortunately i need to care about it, and actually this is what my question is about. So i just want to explicit set a cmyk color and be sure that printer uses the same color. – AvrDragon Mar 19 '13 at 15:34
  • You will have to use an ICC profile. Adobe Photoshop does this. – Alexi Akl Mar 19 '13 at 15:54
  • 1
    I already use it, but ICC_Profile is for CONVERTING. I do not need to convert anything. I just need to set cmyk values direct. (if it is possible). – AvrDragon Mar 19 '13 at 15:56
1

The following code will create an EPS with CMYK color space:

import java.io.*;
import java.awt.*;
import java.awt.geom.*;
import org.apache.fop.util.CMYKColorSpace;
import org.apache.xmlgraphics.java2d.GraphicContext;
import org.apache.xmlgraphics.java2d.ps.EPSDocumentGraphics2D;

public class RenderEPS {
    public static void renderEPS(Path2D path, Color color, String filename) throws Exception {
        EPSDocumentGraphics2D graphics = new EPSDocumentGraphics2D(false);
        FileOutputStream fileOutputStream = new FileOutputStream(filename);
        graphics.setupDocument(fileOutputStream, 200, 200);
        graphics.setGraphicContext(new GraphicContext());
        graphics.setPaint(color);
        graphics.scale(50, 50);
        graphics.fill(path);
        graphics.finish();
    }

    public static void main(String[] args) {
        Path2D path = new Path2D.Double();
        path.moveTo(2, 1);
        path.lineTo(3, 2);
        path.lineTo(2, 3);
        path.lineTo(1, 2);
        path.lineTo(2, 1);

        float[] colorComponents = {1, 0, 0, 0}; // CMYK cyan
        Color color = new Color(CMYKColorSpace.getInstance(), colorComponents, 1f);

        try {
            renderEPS(path, color, "cmyk.eps");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Confirmed:

$ grep cmyk cmyk.eps
1 0 0 0 setcmykcolor

And by:

$ gs -o - -sQUIET -sDEVICE=inkcov cmyk.eps 
 0.01057  0.00000  0.00000  0.00000 CMYK OK
ford
  • 10,687
  • 3
  • 47
  • 54
0

I think you're looking for the java.awt.Color class

so: g.setColor(new Color(200,10,15)); //note numbers are r,g,b between 0 and 255

Richard Tingle
  • 16,906
  • 5
  • 52
  • 77
  • But i need CMYK, not RGB. Does java.awt.Color supports CMYK? – AvrDragon Mar 19 '13 at 14:58
  • ok, i admit i'm not familiar with that technique so i'll assume extracting r,g,b is not an option. General debugging though, you pass in TYP_CMYK, is that a variable defined elsewhere, because the method you're calling expects an int as its input. You can find your options (if you're in a good integrated development environment) by going ColorSpace.getInstance(ColorSpace.); //not a valid line but as soon as you type the . you get your list of options, i note TYP_CMYK is not one of them, but you have more experience with this and may see an equivalent – Richard Tingle Mar 19 '13 at 15:04
  • i.e. it expects an int as its imput BUT what those ints mean are statically defined within the ColorSpace class – Richard Tingle Mar 19 '13 at 15:05
  • Alternatively, see this link for convertion formulars between CMYK and RGB http://www.rapidtables.com/convert/color/cmyk-to-rgb.htm – Richard Tingle Mar 19 '13 at 15:12