unit RGBCMYKUtils; {$IF FPC_Fullversion >= 30200} {$WARN 6058 off : Call to subroutine "$1" marked as inline is not inlined} {$IFEND} interface // Activate only one of these defines - see comments below {.$DEFINE CMYK_FORMULA_1} // Original formula used by mbColorLib {$DEFINE CMYK_FORMULA_2} // Result agrees with OpenOffice uses LCLIntf, Graphics, Math; function CMYtoColor(C, M, Y: integer): TColor; procedure RGBtoCMY(clr: TColor; var C, M, Y: integer); function CMYKToColor (C, M, Y, K: Integer): TColor; procedure ColorToCMYK(clr: TColor; out C, M, Y, K: integer); function GetCValue(c: TColor): integer; function GetMValue(c: TColor): integer; function GetYValue(c: TColor): integer; function GetKValue(c: TColor): integer; implementation function CMYtoColor(C, M, Y: integer): TColor; begin Result := RGB(255 - C, 255 - M, 255 - Y); end; procedure RGBtoCMY(clr: TColor; var C, M, Y: integer); begin C := 255 - GetRValue(clr); M := 255 - GetGValue(clr); Y := 255 - GetBValue(clr); end; {$IFDEF CMYK_FORMULA_1} //============================================================================== // Original formulas of mbColorLib //============================================================================== function CMYKtoColor(C, M, Y, K: Integer): TColor; begin Result := RGBtoColor( (255 - (C + K)) mod 255, // wp: added mod 255, otherwise the result is nonsense (255 - (M + K)) mod 255, (255 - (Y + K)) mod 255 ); end; procedure ColorToCMYK(clr: TColor; out C, M, Y, K: integer); begin C := 255 - GetRValue(clr); M := 255 - GetGValue(clr); Y := 255 - GetBValue(clr); K := MinIntValue([C, M, Y]); C := C - K; M := M - K; Y := Y - K; end; {$ENDIF} {$IFDEF CMYK_FORMULA_2} //============================================================================== // Other formulas // http://www.rapidtables.com/convert/color/cmyk-to-rgb.htm // or https://stackoverflow.com/questions/2426432/convert-rgb-color-to-cmyk // // Result agrees with OpenOffice. //============================================================================== function CMYKtoColor(C, M, Y, K: Integer): TColor; begin Result := RGBtoColor( (255-C) * (255-K) div 255, (255-M) * (255-K) div 255, (255-Y) * (255-K) div 255 ); end; procedure ColorToCMYK(clr: TColor; out C, M, Y, K: Integer); var r, g, b: Integer; r1, g1, b1, c1, m1, y1, k1: Double; begin r := GetRValue(clr); g := GetGValue(clr); b := GetBValue(clr); if (r = 0) and (g = 0) and (b = 0) then begin C := 0; M := 0; Y := 0; K := 1; exit; end; r1 := r / 255; g1 := g / 255; b1 := b / 255; k1 := MinValue([1-r1, 1-g1, 1-b1]); c1 := (1 - r1 - k1) / (1 - k1); m1 := (1 - g1 - k1) / (1 - k1); y1 := (1 - b1 - k1) / (1 - k1); C := round(255 * c1); M := round(255 * m1); Y := round(255 * y1); K := round(255 * k1); end; {$ENDIF} //============================================================================== function GetCValue(c: TColor): integer; var d: integer; begin ColorToCMYK(c, Result, d, d, d); end; function GetMValue(c: TColor): integer; var d: integer; begin ColorToCMYK(c, d, Result, d, d); end; function GetYValue(c: TColor): integer; var d: integer; begin ColorToCMYK(c, d, d, Result, d); end; function GetKValue(c: TColor): integer; var d: integer; begin ColorToCMYK(c, d, d, d, Result); end; end.