ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 3D LUT (*.cube)

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
Fellafoo Posted - Jul 23 2024 : 07:37:45
Programs like ACDSee Photo Studio have an option to load a Color LUT (*.cube, *.3dl) into an image. I see that TIEVisionImage has a LUT procedure, but I haven't found an example of how to use it.

Is it possible to import a 3D LUT into an image using ImageEn?
6   L A T E S T    R E P L I E S    (Newest First)
Dennis445a Posted - Aug 22 2024 : 21:36:15
Awesome, I look forward to testing it.

dm
xequte Posted - Aug 21 2024 : 22:39:42
Hi

You can email me to test the latest beta which supports loading 3D cube files and applying 3D LUTs.



Nigel
Xequte Software
www.imageen.com
Dennis445a Posted - Aug 13 2024 : 08:04:33
I second support for LUT'S in a future version if possible.

dm
xequte Posted - Jul 26 2024 : 20:44:43
Unfortunately I do not know the cube format, so I cannot adequately critique your code. I cannot see any obvious issues with it.


Nigel
Xequte Software
www.imageen.com
Fellafoo Posted - Jul 24 2024 : 09:15:17
I've attached a sample cube file.

attach/Fellafoo/202472491239_Chicago.zip
41.82 KB

Here's my test code to parse and apply the LUT to an image. The results I'm getting are very close to what I see in ACDSee but I'm not familiar enough with the process to know whether I'm on the right track.

type
  LUT = array of array of array of TRGB;

function LoadCubeFile(const FileName: string): LUT;
var
  FileLines: TStringList;
  i, j, k, L, Size: Integer;
  Line, FloatStr: string;
  Sz1, Sz2, Sz3: Char;
  Sz3D: string;
  aLUT: LUT;
  LineIndex: Integer;

  function IsFloatChar(ch: Char): Boolean;
  begin
    Result := (ch in ['0' .. '9', '-', '.']);
  end;

begin
  FileLines := TStringList.Create;
  try
    FileLines.LoadFromFile(FileName);
    // Read size from the header (assuming "LUT_3D_SIZE" is present in the file)
    for i := 0 to FileLines.Count - 1 do begin
      Line := Trim(FileLines.Strings[i]);
      if Pos('LUT_3D_SIZE', Line) = 1 then begin
        LineIndex := i + 1;

        Sz3 := Line[Length(Line)];
        Sz2 := Line[Length(Line) - 1];
        Sz1 := Line[Length(Line) - 2];
        Sz3D := Trim(Sz1 + Sz2 + Sz3);
        if Sz3D = '' then Exit;
        Size := StrToInt(Sz3D);
        Break;
      end;
    end;

    SetLength(aLUT, Size, Size, Size);

    // Read LUT values
    for i := 0 to Size - 1 do begin
      for j := 0 to Size - 1 do begin
        for k := 0 to Size - 1 do begin
          if LineIndex >= FileLines.Count then Break;

          Line := Trim(FileLines[LineIndex]);
          Inc(LineIndex);

          L := 1;

          FloatStr := '';
          while (L <= Length(Line)) and IsFloatChar(Line[L]) do begin
            FloatStr := FloatStr + Line[L];
            Inc(L);
          end;
          aLUT[i, j, k].R := Round(StrToFloat(FloatStr) * 255);
          FloatStr := '';

          // Skip whitespace
          while (L <= Length(Line)) and (Line[L] = ' ') do Inc(L);

          // Read Green value
          while (L <= Length(Line)) and IsFloatChar(Line[L]) do begin
            FloatStr := FloatStr + Line[L];
            Inc(L);
          end;
          aLUT[i, j, k].G := Round(StrToFloat(FloatStr) * 255);
          FloatStr := '';

          // Skip whitespace
          while (L <= Length(Line)) and (Line[L] = ' ') do Inc(L);

          // Read Blue value
          while (L <= Length(Line)) and IsFloatChar(Line[L]) do begin
            FloatStr := FloatStr + Line[L];
            Inc(L);
          end;
          aLUT[i, j, k].B := Round(StrToFloat(FloatStr) * 255);
        end;
      end;
    end;
  finally
    FileLines.Free;
  end;
  Result := aLUT;
end;

procedure ApplyLUTToImage(var Image: TIEBitmap; const aLUT: LUT; DomMin, DomMax: TRGB);
var
  x, y, Size: Integer;
  PixelColor, MappedColor: TRGB;
  R, G, B: Byte;
  LUTIndexR, LUTIndexG, LUTIndexB: Integer;
  ScaleR, ScaleG, ScaleB: Single;

begin
  Size := Length(aLUT);
  ScaleR := (Size - 1) / (DomMax.R - DomMin.R);
  ScaleG := (Size - 1) / (DomMax.G - DomMin.G);
  ScaleB := (Size - 1) / (DomMax.B - DomMin.B);

  for y := 0 to Image.Height - 1 do begin
    for x := 0 to Image.Width - 1 do begin
      PixelColor := Image.Pixels[x, y];

      // Normalize and scale the pixel color values to LUT index range
      LUTIndexR := Round((PixelColor.R / 255 - DomMin.R) * ScaleR);
      LUTIndexG := Round((PixelColor.G / 255 - DomMin.G) * ScaleG);
      LUTIndexB := Round((PixelColor.B / 255 - DomMin.B) * ScaleB);

      // Prevent out-of-bound indexing
      LUTIndexR := Max(0, Min(LUTIndexR, Size - 1));
      LUTIndexG := Max(0, Min(LUTIndexG, Size - 1));
      LUTIndexB := Max(0, Min(LUTIndexB, Size - 1));

      // Retrieve mapped color from LUT
      MappedColor := aLUT[LUTIndexR, LUTIndexG, LUTIndexB];

      // Apply mapped color to image
      { Is cube in BGR format? }
      Image.Pixels[x, y] := CreateRGB(MappedColor.B, MappedColor.G, MappedColor.R);
    end;
  end;
end;
xequte Posted - Jul 24 2024 : 05:18:21
Hi

Can you post or email me some sample files for analysis?



Nigel
Xequte Software
www.imageen.com