Recent

Author Topic: BGRABitmap and console problem  (Read 251 times)

xinyiman

  • Hero Member
  • *****
  • Posts: 2001
    • Lazarus and Free Pascal italian community
BGRABitmap and console problem
« on: November 21, 2019, 02:42:49 pm »
Hi guys, I created a small program to do image manipulation with lazarus. Use the BGRABitmap unit, as long as I run my program on ubuntu with a graphical interface (even if it's a console program) it works fine. When I move it to a server without a graphical interface it tells me:

./myprogramimage: error while loading shared libraries: libgdk-x11-2.0.so.0: cannot open shared object file: No such file or directory

To do image manipulation I use components:

           OriginalImage: TBGRABitmap;
           EditedImage: TBGRABitmap;

Can anyone tell me how to avoid having to install the whole graphical environment? Should I parameterize BGRA in any way ?! Do I have to use other components?
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

winni

  • Hero Member
  • *****
  • Posts: 602
Re: BGRABitmap and console problem
« Reply #1 on: November 21, 2019, 03:19:25 pm »
Hi!

If you want to work with BGRABitmap there must be some graphics libraries installed (!!!).

libgdk-x11-2.0.so.0 is part of the package libgtk-2_0-0  -  the GTK+ toolkit library

But I think this is not enough.

In the unit BGRAGtkBitmap there is a conditional compiling that shows you what other gtk units are needed:

Code: Pascal  [Select]
  1.  {$IFDEF LCLgtk2}
  2.   gdk2, gtk2def, gdk2pixbuf, glib2,
  3.  {$ENDIF}      
  4.  

For more details you should ask circular.

Winni
« Last Edit: November 21, 2019, 03:21:08 pm by winni »

circular

  • Hero Member
  • *****
  • Posts: 3053
    • Personal webpage
Re: BGRABitmap and console problem
« Reply #2 on: November 21, 2019, 04:13:50 pm »
Hello

If you don’t use the GUI you can use the package BGRABitmap4NoGui. Note that fonts work a bit differently in this case.

Regards
Conscience is the debugger of the mind

xinyiman

  • Hero Member
  • *****
  • Posts: 2001
    • Lazarus and Free Pascal italian community
Re: BGRABitmap and console problem
« Reply #3 on: November 21, 2019, 04:29:59 pm »
thank you now I try
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

xinyiman

  • Hero Member
  • *****
  • Posts: 2001
    • Lazarus and Free Pascal italian community
Re: BGRABitmap and console problem
« Reply #4 on: November 21, 2019, 04:44:35 pm »
I installed the package you recommended. But now it returns errors on my code.

uimagemanipulation.pas(142,78) Error: Incompatible type for arg no. 2: Got "TCanvas", expected "TBGRACustomBitmap"

Code: Pascal  [Select]
  1. unit uImageManipulation;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, BGRABitmap, BGRABitmapTypes, FPImage, FPReadJpeg, FPReadPng, Math;
  9.  
  10.  
  11.   type TImageType = (itIgnore, itJPEG, itBMP, itPNG);
  12.  
  13.   type
  14.  
  15.   { TImageManipulation }
  16.  
  17.  TImageManipulation = class
  18.  
  19.     private
  20.           OriginalImage   : TBGRABitmap;
  21.           EditedImage     : TBGRABitmap;
  22.           ValidFormat     : boolean;
  23.           CalcEncodeGamma : array of byte;
  24.           CalcDecodeGamma : array of byte;
  25.           function MyTruncate(value: single): byte;
  26.           procedure CalculateGammaEncodeValue(gamma : single);
  27.           procedure CalculateGammaDecodeValue(gamma : single);
  28.     public
  29.           constructor Create;
  30.           destructor Free;
  31.           function LoadFromFile(name_file : string; mode : TImageType = itIgnore) : boolean;
  32.           function CutRectangle(FSelectionRect : TRect) : boolean;
  33.           procedure SetOriginalImage;
  34.           procedure SaveToFile(name_file : string);
  35.           procedure SaveToStream(app_stream : TMemoryStream);
  36.           procedure RotateLeft();
  37.           procedure RotateRight();
  38.           procedure VerticalFlip();
  39.           procedure HorizontalFlip();
  40.           procedure Brightness(value_perc: single);
  41.           procedure Contrast(value_perc: single);
  42.           procedure Zoom(value_perc: single);
  43.           procedure EncodeGamma(gamma : single);
  44.           procedure DecodeGamma(gamma : single);
  45.   end;
  46.  
  47. implementation
  48.  
  49. { TImageManipulation }
  50.  
  51. constructor TImageManipulation.Create;
  52. begin
  53.      OriginalImage    := TBGRABitmap.Create;
  54.      EditedImage      := TBGRABitmap.Create;
  55.      Self.ValidFormat := false;
  56. end;
  57.  
  58. destructor TImageManipulation.Free;
  59. begin
  60.      EditedImage.Free;
  61.      EditedImage := nil;
  62.      OriginalImage.Free;
  63.      OriginalImage := nil;
  64. end;
  65.  
  66. function TImageManipulation.LoadFromFile(name_file: string; mode: TImageType
  67.   ): boolean;
  68. var
  69.    extension : string;
  70.    jpgReader : TFPReaderJPEG; //in unit FPReadJpeg
  71.    pngReader : TFPReaderPNG; //in unit FPReadPng
  72. begin
  73.  
  74.      if mode = itIgnore then
  75.      begin
  76.           extension := lowercase(ExtractFileExt(name_file));
  77.           case extension of
  78.  
  79.                '.jpg'  : mode := itJPEG;
  80.                '.jpeg' : mode := itJPEG;
  81.                '.png'  : mode := itPNG;
  82.                else
  83.                    mode := itBMP;
  84.           end;
  85.      end;
  86.  
  87.      if FileExists(name_file) then
  88.      begin
  89.           case mode of
  90.                itJPEG : begin
  91.                              Self.ValidFormat := true;
  92.                              jpgReader := TFPReaderJPEG.Create;
  93.                              Self.OriginalImage.LoadFromFile(name_file, jpgReader);
  94.                              jpgReader.Free;
  95.                              result := true;
  96.                         end;
  97.                itPNG  : begin
  98.                              Self.ValidFormat := true;
  99.                              pngReader := TFPReaderPNG.Create;
  100.                              Self.OriginalImage.LoadFromFile(name_file, pngReader);
  101.                              pngReader.Free;
  102.                              result := true;
  103.                         end;
  104.                itBMP  : begin
  105.                              Self.ValidFormat := true;
  106.                              Self.OriginalImage.LoadFromFile(name_file);
  107.                              result := true;
  108.                         end;
  109.                else
  110.                    Self.ValidFormat := false;
  111.  
  112.                end;
  113.      end else begin
  114.          Self.OriginalImage.Bitmap.Clear;
  115.          Self.EditedImage.Bitmap.Clear;
  116.          Self.ValidFormat := false;
  117.          result := false;
  118.      end;
  119.  
  120.      if (result) and (Self.ValidFormat) then
  121.         SetOriginalImage;
  122. end;
  123.  
  124. function TImageManipulation.CutRectangle(FSelectionRect : TRect): boolean;
  125. var
  126.   Bmp        : TBGRABitmap;
  127.   W,H        : Integer;
  128. begin
  129.      if Self.ValidFormat then
  130.      begin
  131.           result     := false;
  132.           Bmp        := TBGRABitmap.Create;
  133.           try
  134.             W := FSelectionRect.Right  - FSelectionRect.Left;
  135.             H := FSelectionRect.Bottom - FSelectionRect.Top;
  136.             Bmp.SetSize(W, H);
  137.             Bmp.Canvas.CopyRect(Rect(0,0,W,H), Self.EditedImage.Bitmap.Canvas, FSelectionRect);
  138.             Self.EditedImage.Assign(Bmp);
  139.             result := true;
  140.           finally
  141.             Bmp.Free;
  142.             Bmp        := nil;
  143.           end;
  144.      end else begin
  145.               result := false;
  146.      end;
  147. end;
  148.  
  149. procedure TImageManipulation.SetOriginalImage;
  150. begin
  151.  
  152.   try
  153.      try
  154.  
  155.         Self.EditedImage.Assign(Self.OriginalImage);
  156.  
  157.      finally
  158.     end;
  159.   except
  160.         on E: Exception do
  161.         begin
  162.  
  163.  
  164.         end;
  165.   end;
  166. end;
  167.  
  168. procedure TImageManipulation.SaveToFile(name_file: string);
  169. begin
  170.      if Self.ValidFormat then
  171.      begin
  172.           Self.EditedImage.SaveToFile(name_file);
  173.      end;
  174. end;
  175.  
  176. procedure TImageManipulation.SaveToStream(app_stream: TMemoryStream);
  177. begin
  178.   try
  179.      try
  180.  
  181.  
  182.         app_stream.Position:=0;
  183.         Self.EditedImage.Bitmap.SaveToStream(app_stream);
  184.         app_stream.Position:=0;
  185.  
  186.      finally
  187.  
  188.      end;
  189.   except
  190.         on E: Exception do
  191.         begin
  192.  
  193.  
  194.         end;
  195.   end;
  196. end;
  197.  
  198. procedure TImageManipulation.RotateLeft();
  199. begin
  200.      try
  201.         try
  202.            Self.EditedImage:=Self.EditedImage.RotateCCW as TBGRABitmap;
  203.         finally
  204.        end;
  205.      except
  206.            on E: Exception do
  207.            begin
  208.  
  209.            end;
  210.      end;
  211. end;
  212.  
  213. procedure TImageManipulation.RotateRight();
  214. begin
  215.      try
  216.         try
  217.  
  218.            Self.EditedImage:=Self.EditedImage.RotateCW as TBGRABitmap;
  219.  
  220.         finally
  221.  
  222.        end;
  223.      except
  224.            on E: Exception do
  225.            begin
  226.  
  227.            end;
  228.      end;
  229. end;
  230.  
  231. procedure TImageManipulation.VerticalFlip();
  232. begin
  233.      try
  234.         try
  235.            Self.EditedImage.VerticalFlip(Self.EditedImage.ClipRect);
  236.         finally
  237.        end;
  238.      except
  239.            on E: Exception do
  240.            begin
  241.  
  242.  
  243.            end;
  244.      end;
  245. end;
  246.  
  247. procedure TImageManipulation.HorizontalFlip();
  248. begin
  249.      try
  250.         try
  251.            Self.EditedImage.HorizontalFlip(Self.EditedImage.ClipRect);
  252.         finally
  253.        end;
  254.      except
  255.            on E: Exception do
  256.            begin
  257.  
  258.            end;
  259.      end;
  260. end;
  261.  
  262. procedure TImageManipulation.Brightness(value_perc: single);
  263. var
  264.    valore: integer;
  265.    x, y: integer;
  266.    p: PBGRAPixel;
  267.    app: TBGRABitmap;
  268. begin
  269.  
  270.      try
  271.         app:=TBGRABitmap.create;
  272.         try
  273.            app.Assign(Self.EditedImage.Bitmap);
  274.            valore := Round(Value_Perc / 100 * High(p^.red));
  275.            for y := 0 to app.Height - 1 do
  276.              begin
  277.                p := app.Scanline[y];
  278.                for x := 0 to app.Width - 1 do
  279.                begin
  280.                  p^.red := Min(p^.red + valore, 255);
  281.                  p^.green := Min(p^.green + valore, 255);
  282.                  p^.blue := Min(p^.blue + valore, 255);
  283.                  Inc(p);
  284.                end;
  285.              end;
  286.              app.InvalidateBitmap;
  287.              Self.EditedImage.Bitmap.Assign(app);
  288.         finally
  289.                app.Free;
  290.        end;
  291.      except
  292.            on E: Exception do
  293.            begin
  294.  
  295.  
  296.            end;
  297.      end;
  298. end;
  299.  
  300. procedure TImageManipulation.Contrast(value_perc: single);
  301. var
  302.    valore: single;
  303.    x, y: integer;
  304.    p: PBGRAPixel;
  305.    app: TBGRABitmap;
  306.    factor: single;
  307. begin
  308.  
  309.      try
  310.         app:=TBGRABitmap.create;
  311.         try
  312.            app.Assign(Self.EditedImage.Bitmap);
  313.            valore := (Value_Perc / 100 * 255);
  314.            factor := (259 * (valore + 255)) / (255 * (259 - valore));
  315.            for y := 0 to app.Height - 1 do
  316.              begin
  317.                p := app.Scanline[y];
  318.                for x := 0 to app.Width - 1 do
  319.                begin
  320.                  p^.red := MyTruncate( factor * (p^.red -255) + 255 );
  321.                  p^.green := MyTruncate( factor * (p^.green -255) + 255 );
  322.                  p^.blue := MyTruncate( factor * (p^.blue -255) + 255 );
  323.                  Inc(p);
  324.                end;
  325.              end;
  326.              app.InvalidateBitmap;
  327.              Self.EditedImage.Bitmap.Assign(app);
  328.         finally
  329.                app.Free;
  330.        end;
  331.      except
  332.            on E: Exception do
  333.            begin
  334.  
  335.  
  336.            end;
  337.      end;
  338. end;
  339.  
  340. procedure TImageManipulation.Zoom(value_perc: single);
  341. var
  342.   app: TBGRABitmap;
  343. begin
  344.  
  345.      try
  346.         app:=TBGRABitmap.create;
  347.         try
  348.            value_perc:=value_perc/100;
  349.            app.Assign(Self.EditedImage.Bitmap);
  350.            Self.EditedImage.Assign(app.Resample( trunc(app.Width*value_perc), Trunc(app.Height*value_perc)));
  351.         finally
  352.                app.Free;
  353.        end;
  354.      except
  355.            on E: Exception do
  356.            begin
  357.  
  358.  
  359.            end;
  360.      end;
  361.  
  362. end;
  363.  
  364. procedure TImageManipulation.EncodeGamma(gamma: single);
  365. var
  366.   p     : PBGRAPixel;
  367.   i     : integer;
  368. begin
  369.  
  370.   try
  371.      try
  372.  
  373.         if gamma>3 then
  374.            gamma := 3;
  375.  
  376.         if gamma<0.1 then
  377.            gamma := 0.1;
  378.  
  379.         CalculateGammaEncodeValue(gamma);
  380.  
  381.         p := Self.EditedImage.Data;
  382.  
  383.         for i := Self.EditedImage.NBPixels-1 downto 0 do
  384.         begin
  385.           {p^.red := round( power(p^.red / 255, 1 / gamma) * 255);
  386.           p^.green := round( power(p^.green / 255, 1 / gamma) * 255);
  387.           p^.blue := round( power(p^.blue / 255, 1 / gamma) * 255);
  388.           p^.alpha := round( power(p^.alpha / 255, 1 / gamma) * 255);  }
  389.  
  390.           p^.red := Self.CalcEncodeGamma[p^.red];
  391.           p^.green := Self.CalcEncodeGamma[p^.green];
  392.           p^.blue := Self.CalcEncodeGamma[p^.blue];
  393.           p^.alpha := Self.CalcEncodeGamma[p^.alpha];
  394.  
  395.           Inc(p);
  396.         end;
  397.  
  398.         Self.EditedImage.InvalidateBitmap;
  399.  
  400.      finally
  401.  
  402.     end;
  403.   except
  404.         on E: Exception do
  405.         begin
  406.  
  407.  
  408.         end;
  409.   end;
  410.  
  411. end;
  412.  
  413. procedure TImageManipulation.DecodeGamma(gamma: single);
  414. var
  415.   p     : PBGRAPixel;
  416.   i     : integer;
  417. begin
  418.  
  419.   try
  420.      try
  421.  
  422.         if gamma>3 then
  423.            gamma := 3;
  424.  
  425.         if gamma<0.1 then
  426.            gamma := 0.1;
  427.  
  428.         CalculateGammaDecodeValue(gamma);
  429.  
  430.  
  431.         p := Self.EditedImage.Data;
  432.  
  433.  
  434.         for i := Self.EditedImage.NBPixels-1 downto 0 do
  435.         begin
  436.           {p^.red := round( power(p^.red / 255, gamma) * 255);
  437.           p^.green := round( power(p^.green / 255, gamma) * 255);
  438.           p^.blue := round( power(p^.blue / 255, gamma) * 255);
  439.           p^.alpha := round( power(p^.alpha / 255, gamma) * 255);  }
  440.           p^.red := Self.CalcDecodeGamma[p^.red];
  441.           p^.green := Self.CalcDecodeGamma[p^.green];
  442.           p^.blue := Self.CalcDecodeGamma[p^.blue];
  443.           p^.alpha := Self.CalcDecodeGamma[p^.alpha];
  444.           Inc(p);
  445.         end;
  446.  
  447.         Self.EditedImage.InvalidateBitmap;
  448.  
  449.      finally
  450.  
  451.     end;
  452.   except
  453.         on E: Exception do
  454.         begin
  455.  
  456.  
  457.         end;
  458.   end;
  459.  
  460. end;
  461.  
  462. function TImageManipulation.MyTruncate(value: single): byte;
  463. var
  464.   ret: byte;
  465. begin
  466.      try
  467.         try
  468.  
  469.            ret := Round(value);
  470.  
  471.            If (value < 0) Then
  472.               ret := 0;
  473.  
  474.            If (value > 255) Then
  475.               ret := 255;
  476.  
  477.         finally
  478.  
  479.        end;
  480.      except
  481.            on E: Exception do
  482.            begin
  483.  
  484.  
  485.            end;
  486.      end;
  487.      result:= ret;
  488. end;
  489.  
  490. procedure TImageManipulation.CalculateGammaEncodeValue(gamma: single);
  491. var
  492.    i : integer;
  493. begin
  494.      SetLength(CalcEncodeGamma,0);
  495.      for i := 0 to 255 do
  496.      begin
  497.        SetLength(CalcEncodeGamma, Length(CalcEncodeGamma)+1);
  498.        CalcEncodeGamma[Length(CalcEncodeGamma)-1] := round( power(i / 255, 1 / gamma) * 255);
  499.      end;
  500. end;
  501.  
  502. procedure TImageManipulation.CalculateGammaDecodeValue(gamma: single);
  503. var
  504.    i : integer;
  505. begin
  506.      SetLength(CalcDecodeGamma,0);
  507.      for i := 0 to 255 do
  508.      begin
  509.        SetLength(CalcDecodeGamma, Length(CalcDecodeGamma)+1);
  510.        CalcDecodeGamma[Length(CalcDecodeGamma)-1] := round( power(i / 255, gamma) * 255);
  511.      end;
  512. end;
  513.  
  514. end.
  515.  
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

lainz

  • Hero Member
  • *****
  • Posts: 3313
    • Lainz
Re: BGRABitmap and console problem
« Reply #5 on: November 21, 2019, 05:38:45 pm »
I suppose there is no LCL in the no gui package, so you can't draw into Canvas...

circular

  • Hero Member
  • *****
  • Posts: 3053
    • Personal webpage
Re: BGRABitmap and console problem
« Reply #6 on: November 28, 2019, 11:51:07 pm »
Sorry for the late reply.

Indeed, the following code
Code: Delphi  [Select]
  1.             Bmp.SetSize(W, H);
  2.             Bmp.Canvas.CopyRect(Rect(0,0,W,H), Self.EditedImage.Bitmap.Canvas, FSelectionRect);
can be replaced for example by
Code: Delphi  [Select]
  1.             Bmp.SetSize(W, H);
  2.             Bmp.PutImage(-FSelectionRect.Left, -FSelectionRect.Top, Self.EditedImage, dmSet);

Regards
Conscience is the debugger of the mind