Rgb to Cmyk and Back Algorithm

RGB to CMYK and back algorithm

As Lea Verou said you should make use of color space information because there isn't an algorithm to map from RGB to CMYK. Adobe has some ICC color profiles available for download1, but I'm not sure how they are licensed.

Once you have the color profiles something like the following would do the job:

import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
import java.io.IOException;
import java.util.Arrays;

public class ColorConv {
final static String pathToCMYKProfile = "C:\\UncoatedFOGRA29.icc";

public static float[] rgbToCmyk(float... rgb) throws IOException {
if (rgb.length != 3) {
throw new IllegalArgumentException();
}
ColorSpace instance = new ICC_ColorSpace(ICC_Profile.getInstance(pathToCMYKProfile));
float[] fromRGB = instance.fromRGB(rgb);
return fromRGB;
}
public static float[] cmykToRgb(float... cmyk) throws IOException {
if (cmyk.length != 4) {
throw new IllegalArgumentException();
}
ColorSpace instance = new ICC_ColorSpace(ICC_Profile.getInstance(pathToCMYKProfile));
float[] fromRGB = instance.toRGB(cmyk);
return fromRGB;
}

public static void main(String... args) {
try {
float[] rgbToCmyk = rgbToCmyk(1.0f, 1.0f, 1.0f);
System.out.println(Arrays.toString(rgbToCmyk));
System.out.println(Arrays.toString(cmykToRgb(rgbToCmyk[0], rgbToCmyk[1], rgbToCmyk[2], rgbToCmyk[3])));
} catch (IOException e) {
e.printStackTrace();
}
}
}

RGB to CMYK Conversion Algorithm

That is simply not true. All RGB colors can be represented as CMYK, but not the opposite. The link you sent works, but it seems the range of the three R, G, B components is [0,255], while the range of the four C, M, Y, K components is [0,1]. This is usual, the RGB coordinates expressed as integers and the CMYK as floating-point numbers. Almost all the algorithms you can find on the web will work like this.

PS: here is a sample implementation of the algorithm, http://www.javascripter.net/faq/rgb2cmyk.htm .

EDIT:

I'm afraid it can be long to explain in detail, but here we go. On one hand, you have the components of each color. On the other hand, you have the display of a certain color on a device. Since each color is physically a function on the wavelength, the RGB representation is a rough approximation of that function.

The problem with that arises when you need to match a certain color on a device. For instance, two screens can show slightly different colors for the same RGB color. To overcome the difficulty of perceptually matching a color with the displayed value on a given device, there exist the so-called color profiles, which specify how the device matches the RGB (or CMYK, or LAB, or whatever color system you use) coordinates with the actual displayed color.

As I understand the situation, the conversion you want to perform involves color profiles. Moreover, when we say RGB we are usually talking about screens, and when we say CMYK we are usually talking about printers (the CMYK components usually specify the amount of ink pigments the printer uses to represent the color). The Wikipedia entry can give you more information on this: https://en.wikipedia.org/wiki/Color_space

Let me finally point out that the conversion you want to perform involves exploring the color profiles associated to the involved devices and is not trivial. However, the first step in RGB->CMYK conversion would be to do a straight conversion with the simple algorithm we discussed first. Then, apply if needed a color correction.

Any faster algorithm to transform from RGB to CMYK

You should probably use ColorConvertOp. It uses optimized native code on most platforms, and supports ICC profile transforms.

Not sure how fast it will work when using float based Rasters, but it does the job.

Something like:

ICC_Profile cmyk = ...;
ICC_Profile sRGB = ...;

ColorConvertOp cco = new ColorConvertOp(sRGB, cmyk);

Raster rgbRaster = ...;
WritableRaster cmykRaster = cco.filter(rgbRaster, null);

// Or alternatively, if you have a BufferedImage input
BufferedImage rgbImage = ...;
BufferedImage cmykImage = cco.filter(rgbImage, null);

RGB to CMYK converter in Java without imports

The below code will store zero in r as the initial value of r is less than 255 and r is an int. So as per integer division r/255 will be zero.

r = r/255;

Instead you can store the result of division in a double variable, try the below (make sure at least one of the operand in the division is a double, else you can cast it to double)

double rC = r/255.0;
c = ((w-rC)/w);

How can I convert RGB to CMYK and vice versa in python?

Here's a Python port of a Javascript implementation.

RGB_SCALE = 255
CMYK_SCALE = 100

def rgb_to_cmyk(r, g, b):
if (r, g, b) == (0, 0, 0):
# black
return 0, 0, 0, CMYK_SCALE

# rgb [0,255] -> cmy [0,1]
c = 1 - r / RGB_SCALE
m = 1 - g / RGB_SCALE
y = 1 - b / RGB_SCALE

# extract out k [0, 1]
min_cmy = min(c, m, y)
c = (c - min_cmy) / (1 - min_cmy)
m = (m - min_cmy) / (1 - min_cmy)
y = (y - min_cmy) / (1 - min_cmy)
k = min_cmy

# rescale to the range [0,CMYK_SCALE]
return c * CMYK_SCALE, m * CMYK_SCALE, y * CMYK_SCALE, k * CMYK_SCALE

RGB TO CMYK conversion using Java

Just an update of my problem.

Use ImageMagick software and i get all my problems resolved.

Cheers,

Bigster

Draw CMYK Color from RGB

It looks to me like the java color class, has a constructor for making a color object in cmyk

https://docs.oracle.com/javase/7/docs/api/java/awt/Color.html#Color(java.awt.color.ColorSpace,%20float[],%20float)

and

https://docs.oracle.com/javase/7/docs/api/java/awt/color/ColorSpace.html

So you would end up with something like

Color cmykColorValue = new Color(TYPE_CMYK, [cValue, mValue, yValue, kValue], alpha)

Where alpha is form 0 to 1, and cValue, mValue, yValue, kValue are the corresponding cmyk values.

That should make a new CMYK color object that can be used anywhere a color object can be used.



Related Topics



Leave a reply



Submit