Симон Моурир дал этот пример :
object o = null;
DateTime d = (DateTime)o; // NullReferenceException
, где unboxing преобразование (литье) из object
(или из одного из классов System.ValueType
или System.Enum
или из типа интерфейса) - тип значения (кроме Nullable<>
) сам по себе дает NullReferenceException
.
В другом направлении конверсия бокса из a Nullable<>
, которая имеет HasValue
, равную false
, на ссылочный тип, может дать ссылку null
, которая затем может привести к NullReferenceException
. Классический пример:
DateTime? d = null;
var s = d.ToString(); // OK, no exception (no boxing), returns ""
var t = d.GetType(); // Bang! d is boxed, NullReferenceException
Иногда бокс происходит по-другому. Например, с помощью этого не общего метода расширения:
public static void MyExtension(this object x)
{
x.ToString();
}
следующий код будет проблематичным:
DateTime? d = null;
d.MyExtension(); // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here.
Эти случаи возникают из-за специальных правил, используемых во время выполнения при боксе Nullable<>
экземпляров.
Проверьте эту ссылку: http://www.codeproject.com/KB/applications/xcmyk.aspx . Он дает эту формулу.
Black = minimum(1-Red,1-Green,1-Blue)
Cyan = (1-Red-Black)/(1-Black)
Magenta = (1-Green-Black)/(1-Black)
Yellow = (1-Blue-Black)/(1-Black)
Я согласен с предыдущими ответами, но хочу сказать, что:
if ( K == 1 )
{
C = 0
M = 0
Y = 0
}
Это может быть, если r = g = b = 0.
Если вы хотите получить хороший результат, вам необходимо применить цветовой профиль. В .NET вы можете сделать это так (предполагая, что исходные компоненты CMYK находятся в диапазоне от 0 до 255):
float[] colorValues = new float[4];
colorValues[0] = c / 255f;
colorValues[1] = m / 255f;
colorValues[2] = y / 255f;
colorValues[3] = k / 255f;
System.Windows.Media.Color color = Color.FromValues(colorValues,
new Uri(@"C:\Users\me\Documents\ISOcoated_v2_300_eci.icc"));
System.Drawing.Color rgbColor = System.Drawing.Color.FromArgb(color.R, color.G, color.B);
Обратите внимание, что используются два разных класса Color из двух разных пространств имен. Вероятно, вам нужно добавить DLL PresentationCore в качестве ссылки.
Необходимый профиль цвета можно загрузить из раздела загрузки eci.org . Это часть большого ZIP-файла, содержащего несколько профилей. Они явно рекомендуют использовать профиль ISO Coated v2 300% (ECI).
Если вам нужно преобразовать полное изображение из CMYK в RGB, для этого в этом пространстве имен есть специальные классы.
Мой полный пример преобразования C # между CMYK & lt; -> HEX:
public class ColorConverter
{
public static string CMYKtoHex(decimal[] cmyk)
{
if (cmyk.Length != 4) return null;
var r = (int)(255 * (1 - cmyk[0]) * (1 - cmyk[3]));
var g = (int)(255 * (1 - cmyk[1]) * (1 - cmyk[3]));
var b = (int)(255 * (1 - cmyk[2]) * (1 - cmyk[3]));
var hex = "#" + r.ToString("X2") + g.ToString("X2") + b.ToString("X2");
return hex;
}
public static decimal[] HexToCMYK(string hex)
{
decimal computedC = 0;
decimal computedM = 0;
decimal computedY = 0;
decimal computedK = 0;
hex = (hex[0] == '#') ? hex.Substring(1, 6) : hex;
if (hex.Length != 6)
{
return null;
}
decimal r = int.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
decimal g = int.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
decimal b = int.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
// BLACK
if (r == 0 && g == 0 && b == 0)
{
computedK = 1;
return new[] { 0, 0, 0, computedK };
}
computedC = 1 - (r / 255);
computedM = 1 - (g / 255);
computedY = 1 - (b / 255);
var minCMY = Math.Min(computedC, Math.Min(computedM, computedY));
computedC = (computedC - minCMY) / (1 - minCMY);
computedM = (computedM - minCMY) / (1 - minCMY);
computedY = (computedY - minCMY) / (1 - minCMY);
computedK = minCMY;
return new[] { computedC, computedM, computedY, computedK };
}
}
Я думаю, что Photoshop использует конверсии на основе профиля. Посмотрите документацию для параметров цвета . Если это так, вы не сможете сопоставить это поведение с простыми решениями на основе формулы.
Я обнаружил, что LCMS очень удобен, прост и эффективен для такого рода задач. известно, если для него есть привязка .net ...
Преобразование из RGB в CMYK зависит от физического устройства / процесса, используемого для установки чернил CMYK. Они представлены в программном обеспечении в виде цветовых профилей. ICC и ICM цветовые профили физических устройств определяют полученные цвета.
Если вас не интересует истинное представление на физическом устройстве, используйте прямой конверсии в других сообщениях.
Если, однако, вы обеспокоены этим аспектом, вам нужно использовать либо API управления цветом Windows , либо что-то вроде LittleCMS , чтобы сделать преобразования цвета для вас (поскольку они применяют правильный цветовой профиль во время преобразования).