[delphi] Konwersja koloru zapisanego w RGB do CMYK

0

Bry..

Szukalem wskazowki i znalazlem cos:
http://www.assu-assist.nl/pgg/324.shtml

Jednakze wynik rozni sie od tego co podaje na przyklad Fotoszkop..
Jakies idee? sugestie?

0

Może to Ci jakoś pomoże http://www.efg2.com/Lab/Graphics/Colors/ShowImage.htm

Jak jeszcze coś znajdę to dodam :)

0

No slodkie,ale zanim sie przekopie przez te unity i kod to szaleju dostane..

Mialem na mysli jakis Tips w stylu tego co link umiescilem

0

Sorki ze moze tu zaśmiecam ale chce pomóc ;)
Znalazłem gdzieś taki unit:

unit ColorDecode;

interface

uses Windows, Math;

//==Other===================================================
Function RGBToSaturation(const R, G, B: Byte):Integer;
Function RGBToLightness(const R, G, B: Byte):Integer;
Function RGBToIntensity(const R, G, B: Byte):Integer;
Procedure RGBToYIQ(const R, G, B: Byte; var Y, I, Q: Integer);

//==RGB/HSV======================================
Procedure RGBToHSV(const R, G, B: Byte; var H: Integer; var S, V: Byte);
Procedure HSVToRGB(const H: Integer; const S, V: Byte; var R, G, B: Byte);

//==RGB/HLS=====================================
const
  iNAN=-1;//Not A Number
Function IsiNan(Value: Integer): Boolean;
{
Hue is in [0,360) or -1 (Not A Number) [like 360 degrees around hexcone]
L & S are in 0..255
}
Procedure RGBToHLS(const R, G, B: Byte; var H: Integer; var L, S: Byte);
Procedure HLSToRGB(const H: Integer; const L, S: Byte; var R, G, B: Byte);

//==RGB/CMYK===================================
Procedure RGBToCMYK(const R, G, B: Byte; var C, M, Y, K: Byte);
Procedure CMYKToRGB(const C, M, Y, K: Byte; var R, G, B: Byte);

//==RGB/CMY====================================
Procedure RGBToCMY(const R, G, B: Byte; var C, M, Y: Byte);
Procedure CMYToRGB(const C, M, Y: Byte; var R, G, B: Byte);


implementation


//==Other================================
Function RGBToSaturation(const R, G, B: Byte):Integer;
begin
  if MaxIntValue([R, G, B])=0 then
    Result:=0
  else
    Result:=Round(((MaxIntValue([R, G, B])-MinIntValue([R, G, B]))/MaxIntValue([R, G, B]))*255);
end;

Function RGBToLightness(const R, G, B: Byte):Integer;
begin
  Result:=(MinIntValue([R, G, B])+MaxIntValue([R, G, B])) div 2;
end;

Function RGBToIntensity(const R, G, B: Byte):Integer;
begin
  Result:=(R+G+B) div 3;
end;

Procedure RGBToYIQ(const R, G, B: Byte; var Y, I, Q: Integer);
begin
  Y:=Integer(77*R+150*G+29*B) shr 8;
  I:=Integer(153*R-70*G-82*B) shr 8;
  Q:=Integer(54*B-134*G+80*B) shr 8;
end;

//==RGB/HSV==========================
Procedure RGBToHSV(const R, G, B: Byte; var H: Integer; var S, V: Byte);
var
  Min, Delta: Integer;
begin
  Min:=MinIntValue([R, G, B]);
  V:=MaxIntValue([R, G, B]);
  Delta:=V-Min;
  If V=0 then
    S:=0
  else
    S:=Round(Delta/V);
  If S=0 then
    H:=0
  else
    begin
      If R=V then
        H:=Round(60*(G-B)/Delta)
      else
        if G=V then
          H:=120+Round(60*(B-R)/Delta)
        else
          if B=V then
            H:=240+Round(60*(R-G)/Delta);
      if H<0 then
        H:=H+360;
    end;
end;

Procedure HSVToRGB(const H: Integer; const S, V: Byte; var R, G, B: Byte);
const
  divisor:Integer=255*60;
VAR
  f, hTemp, p, q, t, VS:Integer;
BEGIN
  If S=0 then
    begin
      R:=V;
      G:=V;
      B:=V;
    end
  else
    begin
      If H=360 then
        hTemp:=0
      else
        hTemp:=H;
      f:=hTemp mod 60;
      hTemp:=hTemp div 60;
      VS:=V*S;
      p:=V-VS div 255;
      q:=V-(VS*f) div divisor;
      t:=V-(VS*(60-f)) div divisor;
      case hTemp of
        0:
          begin
            R:=V;
            G:=t;
            B:=p;
          end;
        1:
          begin
            R:=q;
            G:=V;
            B:=p
          end;
        2:
          begin
            R:=p;
            G:=V;
            B:=t;
          end;
        3:
          begin
            R:=p;
            G:=q;
            B:=V;
          end;
        4:
          begin
            R:=t;
            G:=p;
            B:=V;
          end;
        5:
          begin
            R:=V;
            G:=p;
            B:=q;
          end;
        else
          begin
            R:=0;
            G:=0;
            B:=0;
          end;
      end;
    end;
end;

//==RGB/HLS=================================
Function IsiNan(Value: Integer): Boolean;
begin
  Result:=Value=iNaN;
end;

Procedure RGBToHLS(const R, G, B: Byte; var H: Integer; var L, S: Byte);
var
  Hue, Lightness, Saturation: Real;

  Procedure FloatRGBToHLS(const R,G,B: Real; var H,L,S: Real);
  {R, G, B, L, S are in [0,1]; H is in [0,360)}
  var
    Delta, Min, Max: Real;
  begin
    Max:=MaxValue([R, G, B]);
    Min:=MinValue([R, G, B]);
    L:=(Max+Min)/2.0;
    if Max=Min then
      begin
        S:=0.0;
        H:=NaN;
      end
    else
      begin
        Delta:=Max-Min;
        if L<=0.5 then
          S:=Delta/(Max+Min)
        else
          S:=Delta/(2.0-(Max+Min));
        if R=Max then
          H:=(60.0*(G-B))/Delta
        else
          if G=Max then
            H:=120+(60.0*(B-R))/Delta
          else
            H:=240+(60.0*(R-G))/Delta;
        if H<0 then
          H:=H+360.0;
      end;
  end;

begin
  FloatRGBToHLS(R/255, G/255, B/255, Hue, Lightness, Saturation);
  if IsNaN(Hue) then
    H:=iNan
  else
    H:=Round(Hue);
  L:=Round(Lightness*255);
  S:=Round(Saturation*255);
end;

Procedure HLSToRGB(const H: Integer; const L, S: Byte; var R, G, B: Byte);
var
  Hue: Real;
  Red, Green, Blue: Real;

  Procedure FloatHLSToRGB(const H, L, S: Real; var R, G, B: Real);
    var
      m1: Real;
      m2: Real;

    Function Value(const n1,n2: Real; hue: Real): Real;
    begin
      if hue>360.0 then
        hue:=hue-360.0
      else
        if hue<0.0 then
          hue:=hue+360.0;
      if hue<60.0 then
        Result:=n1+(n2-n1)*hue/60.0
      else
        if   hue < 180
        then RESULT := n2
        else
          if   hue < 240.0
          then RESULT := n1 + (n2-n1)*(240.0 - hue) / 60.0
          else RESULT := n1
    end;
    
  begin
    if   L <= 0.5
    then m2 := L * (1 + S)
    else m2 := L + S - L*S;
    m1 := 2.0 * L - m2;
    if   S = 0.0
    then begin
      if   IsNAN(H)
      then begin
        R := L;
        G := L;
        B := L
      end
    end
    else begin
      R := Value(m1, m2, H + 120.0);
      G := Value(m1, m2, H);
      B := Value(m1, m2, H - 120.0)
    end
  end;
  
begin
  if IsiNaN(H) then
    Hue:=NaN
  else
    Hue:=H;
  FloatHLSToRGB(Hue, L/255, S/255, Red, Green, Blue);
  R:=Round(Red*255);
  G:=Round(Green*255);
  B:=Round(Blue*255);
end;

//==RGB/CMYK==============================
Procedure RGBToCMYK(const R, G, B: Byte; var C, M, Y, K: Byte);
begin
  //First - Convert RGB to CMY
  RGBToCMY(R, G, B, C, M, Y);
  //Now we downgarding color ink use by boosting blacK
  K:=MinIntValue([C, M, Y]); //minimum  color value
  C:=C-K;
  M:=M-K;
  Y:=Y-K;
end;

Procedure CMYKToRGB(const C, M, Y, K: Byte; var R, G, B: Byte);
begin
  R:=255-(C+K);
  G:=255-(M+K);
  B:=255-(Y+K);
end;

//==RGB/CMY==============================
Procedure RGBToCMY(const R, G, B: Byte; var C, M, Y: Byte);
begin
  C:=255-R;
  M:=255-G;
  Y:=255-B;
end;

Procedure CMYToRGB(const C, M, Y: Byte; var R, G, B: Byte);
begin
  R:=255-C;
  G:=255-M;
  B:=255-Y;
end;

end.

A poniżej praktyczne zastosowanie (taki tam sobie programik do testowania kolorków) mozesz zobaczyć czy to samo wyświetla w PhotoShopie

unit Unit1;

interface

uses
  ColorDecode,
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls, ExtCtrls;
 
type
  TForm1 = class(TForm)
    GroupBox1: TGroupBox;
    GroupBox2: TGroupBox;
    TrackBarR: TTrackBar;
    TrackBarG: TTrackBar;
    TrackBarB: TTrackBar;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    LabelR: TLabel;
    LabelG: TLabel;
    LabelB: TLabel;
    Panel1: TPanel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    TrackBarC: TTrackBar;
    TrackBarM: TTrackBar;
    TrackBarY: TTrackBar;
    TrackBarK: TTrackBar;
    LabelC: TLabel;
    LabelM: TLabel;
    LabelY: TLabel;
    LabelK: TLabel;
    Panel2: TPanel;
    Timer1: TTimer;
    Button1: TButton;
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure TrackBarRChange(Sender: TObject);
    procedure TrackBarCChange(Sender: TObject);
   private
    { Private declarations }

  public

    { Public declarations }
  end;

var
  Form1: TForm1;
  Kolor1,Kolor2 :TColor;

implementation {$R *.DFM}
{**********************************************}
procedure TForm1.Timer1Timer(Sender: TObject);
var
 R,G,B   :Integer;
 C,M,Y,K :Integer;
Begin
 {-------------- składowe typu RGB -------------------}
 //pobiera wartości składowych R,G,B z pasków przesuwu
 R:= TrackBarR.Position;
 G:= TrackBarG.Position;
 B:= TrackBarB.Position;
 //Utworzenie koloru ze składowych R,G,B
 kolor1:= RGB(R,G,B); //czerwony, zielony, niebieski
 //wyświetla te wartości i pokazuje kwadrat o danym kolorze
 LabelR.Caption:= IntToStr(R);
 LabelG.Caption:= IntToStr(G);
 LabelB.Caption:= IntToStr(B);
 Panel1.Color:= kolor1;
 {--------------- składowe typu CMYK -------------------}
 //pobiera wartości składowych C,M,Y,K z pasków przesuwu
 C:= TrackBarC.Position;
 M:= TrackBarM.Position;
 Y:= TrackBarY.Position;
 K:= TrackBarK.Position;
 //Utworzenie koloru ze składowych C,M,Y,K
 kolor2:= CMYK(C,M,Y,K); //Cyan, Magent, Yellow(żólty), K(czarny)
 //wyświetla te wartości i pokazuje kwadrat o danym kolorze
 LabelC.Caption:= IntToStr(C);
 LabelM.Caption:= IntToStr(M);
 LabelY.Caption:= IntToStr(Y);
 LabelK.Caption:= IntToStr(K);
 Panel2.Color:= kolor2;;
End;
{======= Śedzi ruchy pasków zmiany RGB i ustawia CMYK na taki sam kolor ======}
procedure TForm1.TrackBarRChange(Sender: TObject);
Begin
 TrackBarC.Position:= GetCValue( kolor1 );
 TrackBarM.Position:= GetMValue( kolor1 );
 TrackBarY.Position:= GetYValue( kolor1 );
 TrackBarK.Position:= GetKValue( kolor1 );
End;
{======= Śedzi ruchy pasków zmiany CMYK i ustawia RGB na taki sam kolor ======}
procedure TForm1.TrackBarCChange(Sender: TObject);
begin
 IF  GETASYNCKEYSTATE(VK_rBUTTON)  < 0 THEN BEGIN;
 TrackBarR.Position:= GetRValue( kolor2 );
 TrackBarG.Position:= GetGValue( kolor2 );
 TrackBarB.Position:= GetBValue( kolor2 );
 END;
end;
{============================}
procedure TForm1.Button1Click(Sender: TObject);
Begin
Close;
End;



END.
0

Sorki ze moze tu zaśmiecam ale chce pomóc
Znalazłem gdzieś taki unit:

To HColorUtitles.. niestety zamiana podobna do tej co pokazał lofix.. więc sie nie zda - chociaż jest to poprawny kod.

0

No tak, dotychczas zaden kod ktory znalazlem nie mial wynikow jak FotoShop

Moje kryterium rozwiazania wlasnie polega na tym by wynik byl taki sam jak w fotoszkopie

0

Może to debilne co powiem ale może to Photoshop się myli?

0

Może to debilne co powiem ale może to Photoshop się myli?

Moze,ale program ma konwertowac na takie wartosci jak fotoszkop!

1 użytkowników online, w tym zalogowanych: 0, gości: 1