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 Raster
s, 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
How to Run Ssh Commands on Remote System Using Java
Threads Configuration Based on No. of Cpu-Cores
Is There Any Good and Free Date and Time Picker Available for Java Swing
Javafx and Maven: Nullpointerexception: Location Is Required
How to Pass Console Arguments to Application in Eclipse
Retrieve an Image Stored as Blob on a MySQL Db
How to Convert Int to Unsigned Byte and Back
Tomcat7 Starts Too Late on Ubuntu 14.04 X64 [Digitalocean]
Convert .Jar to an Osx Executable
How to Convert a Binary String to a Base 10 Integer in Java
How to Serialize Only the Id of a Child with Jackson
Differencebetween Bounded Wildcard and Type Parameters
A Simple Http Server with Java/Socket
How to Configure Hibernate Config File for SQL Server
Does Java Have Any Mechanism for a Vm to Trace Method Calls on Itself, Without Using Javaagent, etc