Scroll an image with Rect lazarus / 39-Graphics ---------------------------------------------------------------------- xinyiman · 2016-01-27 20:49 Hello guys, I'm playing a little 'with the pictures and I wanted to figure out how to scroll an image, with the rect. That is, I'm trying to read the box to box the whole image.Just I do not understand where I'm wrong, instead of slide shows me always the same memory area. I do not understand. Who tells me where I'm wrong? View attachment Thanks ---------------------------------------------------------------------- xinyiman · 2016-01-27 21:15 So in the second image I'm going to put the part of image1 interests me. But in image2 going to put it on a white background in the same position as the original. I need to put the extracted in a TImage running from Top = 0 and Left = 0. I do not understand where I'm wrong Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i           Self.Edit1.Text:=IntToStr(DaLeft) + ' - ' + IntToStr(DaTop) + ' - ' + IntToStr(LargRect) + ' - ' + IntToStr(AltezRect);            MyRect := Rect(DaLeft,DaTop,(LargRect),(AltezRect));            MyOther := Rect(DaLeft,DaTop,(LargRect),(AltezRect));             Form1.Image2.Canvas.Clear;            Form1.Image2.Canvas.CopyRect(MyOther,Self.Image1.Canvas,MyRect); ---------------------------------------------------------------------- xinyiman · 2016-01-27 23:13 I solved with             MyRect := Rect(DaLeft,DaTop,(LargRect+DaLeft),(AltezRect+DaTop));             //MyOther := Rect(DaLeft,DaTop,(LargRect+DaLeft),(AltezRect+DaTop));             MyOther := Rect(0,0,(LargRect),(AltezRect)); But another problem arose. I used to do the manipulations of TImage image to scan images. If I wanted to do it in bacground? With a console program? TImage not good because if it is not drawn on the form must be in error. Tips? ---------------------------------------------------------------------- molly · 2016-01-27 23:37 Quote from: xinyiman on January 28, 2016, 12:13:46 amBut another problem arose. I used to do the manipulations of TImage image to scan images. If I wanted to do it in bacground? With a console program? TImage not good because if it is not drawn on the form must be in error. Tips? TBitmap or TPicture ? You mentioned console mode,in case only compiling with FPC you can perhaps take a look at fcl-image package. ---------------------------------------------------------------------- Carver413 · 2016-01-28 00:37 what sort of manipulations do you plan to do ---------------------------------------------------------------------- xinyiman · 2016-01-28 07:32 I have to pull out of parts of the image that has a certain height and width and that has only in orange and black ---------------------------------------------------------------------- xinyiman · 2016-01-28 07:48 And then a curiosity, if I use a TImage.CopyRect in a cycle works only if you use Application.ProcessMessage each cycle. I get it off not working. As if he was drawing within the TImage. Who explains to me why and how to fix? ---------------------------------------------------------------------- molly · 2016-01-28 08:14 Quote from: xinyiman on January 28, 2016, 08:48:42 amAnd then a curiosity, if I use a TImage.CopyRect in a cycle works only if you use Application.ProcessMessage each cycle. I get it off not working. As if he was drawing within the TImage. Who explains to me why and how to fix? If you 'loop' the copyrect in order to ''simulate' scrolling, it is most probably that the image is not updated when done with a copyrect. Processmessages 'allows' for the (re)paint messages to be send to the control. You can probably 'force' that without using processmessages when doing either an .update, .repaint or .refresh ---------------------------------------------------------------------- xinyiman · 2016-01-28 11:43 Hello, I'm trying to do as I had suggested and use fcl-image. But I have some questions, as shown by the code below required width TFPCustomImage with fixed values. To do that you change the loading LoadFromFile how? Does this automatically? Then I would understand, I can not put the contents of the image in the canvas, I change the canvas, but if I want to reset the image to the canvas changed and then save it as I do? Thanks Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  procedure ElaboraSingolaImmagine(AFileName, ADestFileName: string);  procedure CopyPartOfImage(Origine, Destinazione: TCanvas; Top,Left,Height,Width: integer);  var     x, y,i,j: integer;  begin       i:=0;       //Destinazione.clear;       for y:=Top to (Top+Height) do       begin            j:=0;            for x:=Left to (Left+Width) do          begin                 Destinazione.Pixels[j,i]:=Origine.Pixels[x,y];                 Inc(j);            end;            Inc(i);       end;  end;var  image: TFPCustomImage;  reader: TFPCustomImageReader;  writer: TFPCustomImageWriter;  canvasOrig, canvasDest : TFPCustomCanvas;begin  Image := TFPMemoryImage.Create(450, 300);  Image.LoadFromFile(AFileName, Reader);   CanvasOrig := TFPImageCanvas.Create (image);  CanvasDest := TFPImageCanvas.Create (image);   CopyPartOfImage(CanvasOrig, CanvasDest, 0,0,100,200);   Image.  Image.SaveToFile(ADestFileName); end; ---------------------------------------------------------------------- molly · 2016-01-28 16:09 Hi xinyiman, Unfortunately it seems like i am a bit lost with my English skills, as i did not completely understood what you asked for exactly (so please accept my apologies, in case i answered wrongly). QuoteTo do that you change the loading LoadFromFile how? Does this automatically? Yes, FPimage works a bit differently from what we are used to with Lazarus. AFAIK you need to define the dimensions yourself and this can't be done automatically (please, someone correct me when wrong). QuoteThen I would understand, I can not put the contents of the image in the canvas, I change the canvas, but if I want to reset the image to the canvas changed and then save it as I do? If i understood correctly (also by having looked at your code), then you seem to be unable to save your copied rectangle to a new file on disk ? That is probably because you are using two canvases on the same image... Code: [Select]  CanvasOrig := TFPImageCanvas.Create (image);   CanvasDest := TFPImageCanvas.Create (image); I have modified your code a little, and the following seems to work for me: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program test1; {$MODE OBJFPC}{$H+} Uses  FPImage, FPCanvas, FPImgCanv,  FPReadPNG, FPWritePNG;  procedure CopyPartOfImage(Origine, Destinazione: TFPCustomCanvas; Top, Left, Height, Width: integer);var  x,y   : integer;  i,j   : integer;begin  i := 0;   //Destinazione.clear;  for y := Top to (Top + Height) do  begin    j:=0;     for x := Left to (Left + Width) do    begin      Destinazione.Colors[j, i] := Origine.Colors[x, y];      inc(j);    end;    inc(i);   end;end;   procedure ElaboraSingolaImmagine(AFileName, ADestFileName: string);var  SourceImage       : TFPCustomImage;  SourceCanvas      : TFPCustomCanvas;   DestinationImage  : TFPCustomImage;  DestinationCanvas : TFPCustomCanvas;   reader            : TFPCustomImageReader;  writer            : TFPCustomImageWriter;begin  // Create in memory image  SourceImage       := TFPMemoryImage.Create(144, 144);  // Create appropiate reader  Reader          := TFPReaderPNG.Create;  // Read imagedata from file  SourceImage.LoadFromFile(AFileName, Reader);  // Create canvas for the image  SourceCanvas := TFPImageCanvas.Create(SourceImage);   // Prepare destination  DestinationImage  := TFPMemoryImage.Create(144, 144);  DestinationCanvas := TFPImageCanvas.Create(DestinationImage);   CopyPartOfImage(SourceCanvas, DestinationCanvas, 0, 0, 50, 50);   Writer := TFPWriterPNG.Create;  DestinationImage.SaveToFile(ADestFileName, Writer);   // Clean up  SourceImage.Free;  DestinationImage.Free;    SourceCanvas.Free;  DestinationCanvas.Free;    Reader.Free;  Writer.Free;end;  //// GreenSwirl.png (144 x 144)// begin  ElaboraSingolaImmagine('greenswirl.png', 'result1.png');end.  It might perhaps not be entirely what you are looking for, but hopefully can aid you with your questions. BTW: i noticed some other postings from you concerning images. In case these questions all belong to the same project then it would perhaps be an idea to do some research on what would be the best option (read: graphics package or other helpful related functionality) that are better suited for helping you out with your project. edit: a couple of "perhaps" too many -> rephrased and removed ---------------------------------------------------------------------- xinyiman · 2016-01-28 19:54 Hello, thank you, I tested your code, but not working. The result is a png file completely black. Are you sure that you work? I am attaching the program to fill in with the image. You tell me if it works for you? Thank you ---------------------------------------------------------------------- xinyiman · 2016-01-28 20:08 I apologize, using another image png works. ---------------------------------------------------------------------- xinyiman · 2016-01-28 20:26 Now I just have to figure out how to read the size of the images to read! fcl-image as it runs? If you do not run it the only way it is through a TImage? ---------------------------------------------------------------------- molly · 2016-01-28 20:46 Quote from: xinyiman on January 28, 2016, 08:54:48 pmAre you sure that you work? Yes, it works for me. Quote from: xinyiman on January 28, 2016, 09:08:19 pmI apologize, using another image png works. Hmz, no idea why it works with some png images while not with other. Might perhaps be related to the colourdepth in the png. Quote from: xinyiman on January 28, 2016, 09:26:51 pmfcl-image as it runs? If you do not run it the only way it is through a TImage? No, as i pointed out you can also use a TPicture to load a graphics file and use TBitmap to manipulate your image (or use TBitmap class directly in case working with BMP files). I'm sure there are lot of other approaches possible (*) There is a distinct difference between not using a visible canvas and creating a program for FPC (console) only, hence why i mentioned fcl- image. Besides the 'default' solutions provided by FPC/Lazarus there are a lot of other 3th party libraries that can aid you in working with graphics. Here you can find some of those graphics libraries being listed. Unfortunately, only you can decide if any of these libraries will be helpful for your project or not (or that it is perhaps better to use standard FCL/LCL components). I don't have many experience with any of them to be able to give any advise on that topic. If you are able to share with us what kind of functionality you are looking for then i'm confident someone else reading might be able to give you some direction. In case you are only toying around, then please try any of the libraries in the wiki, i'm sure some of those libraries will impress the living daylights out of you (*) ;-) (*) Some of those libraries are very impressive and can take a while to get yourself familiar with. ---------------------------------------------------------------------- xinyiman · 2016-01-28 21:21 I thank you really nice. But for now what I needed I was able to do it with your help. I still have a thing to understand. I have to be able to go to change the color of a part of the image and put it white. But this code is not working. It puts the background all black and do not know why Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i    MyColor: TFPColor;   MyRed, MyBlue, MyGreen: byte;  MyCanvas: TFPCustomCanvas;...                    MyColor.blue:=255;                 MyColor.green:=255;                   MyColor.red:=255;                 MyCanvas.Colors[i,j]:=MyColor; ---------------------------------------------------------------------- xinyiman · 2016-01-28 22:02 Quote from: xinyiman on January 28, 2016, 10:21:56 pmI thank you really nice. But for now what I needed I was able to do it with your help. I still have a thing to understand. I have to be able to go to change the color of a part of the image and put it white. But this code is not working. It puts the background all black and do not know why Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i    MyColor: TFPColor;   MyRed, MyBlue, MyGreen: byte;  MyCanvas: TFPCustomCanvas;...                    MyColor.blue:=255;                 MyColor.green:=255;                   MyColor.red:=255;                 MyCanvas.Colors[i,j]:=MyColor;  Solved with                    MyCanvas.Colors[i,j]:=FPColor(65535, 65535, 65535, 65535); But I do not understand. The colors should not go from 0 to 255? ---------------------------------------------------------------------- molly · 2016-01-28 22:20 Quote from: xinyiman on January 28, 2016, 11:02:33 pmBut I do not understand. The colors should not go from 0 to 255? Ah, you found that already  Nevermind, i post an updated example, which explained that in the comments. It searches for a particular color on the sourcecanvas and replaces it with another on the destination canvas while copying the pixels (and when the color matches). Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program test2;  {$MODE OBJFPC}{$H+} Uses  FPImage, FPCanvas, FPImgCanv,  FPReadPNG, FPWritePNG;  procedure CopyPartOfImage(Origine, Destinazione: TFPCustomCanvas; Top, Left, Height, Width: integer);var  x,y   : integer;  i,j   : integer;    CheckForColor     : TFPColor; // The colour that we want to search for in order to replace  ChangeIntoColor   : TFPColor; // The 'replacement' colour  ThisPixelColor    : TFPColor; // To temporary store current pixel (x,y) colorbegin  i := 0;   {   BIG NOTE: Each individual R,G,B and Alpha channel inside TFPCColor is              expressed in 16 bits = 1 word      you: $aa $rr $gg $bb   me: $aaaa $rrrr $gggg $bbbb    Where each letter represents a hexadecimal nibble.   So, instead of a colour occupying the usual widely used 4 bytes, TFPColor    stores a single colorvalue into 8 bytes. }       // Intialize rgb values for that colour that needs to be searched for and   // that we want to replace  // For this example we search for a white colour  CheckForColor.Red   := $FFFF;  CheckForColor.Green := $FFFF;  CheckForColor.Blue  := $FFFF;   // Initialize rgb values for the replacement colour  // For this example we want to replace all green pixels to blue  ChangeIntoColor.Red   := $0000;  ChangeIntoColor.Green := $0000;  ChangeIntoColor.Blue  := $FFFF;   // Blue     //Destinazione.clear;  for y := Top to (Top + Height) do  begin    j:=0;     for x := Left to (Left + Width) do    begin      // Temp. store coloor of curent pixel into ThisPixelColor      ThisPixelColor := Origine.Colors[x, y];       // Now check if ThisPixelColor matches the colour that we want to replace      // Note: No comparison for the alpha channel (change accordingly to your wishes)      If (          ( ThisPixelColor.Red   = CheckForColor.Red   ) and            ( ThisPixelColor.Green = CheckForColor.Green ) and            ( ThisPixelColor.Blue  = CheckForColor.Blue  )         ) then      // Here it is pretty sure that current pixel matches the rgb values      // of the color that need to change so, let's accomodate the 'destination'      // color      begin        // First we copy the alpha channel, as we didn't checked for that value        // (in order to alllow all possible alpha values -> change according to         // your wishes)        ChangeIntoColor.Alpha := ThisPixelColor.Alpha;      Destinazione.Colors[j, i] := ChangeIntoColor;      end      else       // just copy the pixel colour from source to destination for all other        // pixels that did not match the color that we wanted to change.        Destinazione.Colors[j, i] := Origine.Colors[x, y];    inc(j);    end;    inc(i);   end;end;   procedure ElaboraSingolaImmagine(AFileName, ADestFileName: string);var  SourceImage       : TFPCustomImage;  SourceCanvas      : TFPCustomCanvas;   DestinationImage  : TFPCustomImage;  DestinationCanvas : TFPCustomCanvas;   reader            : TFPCustomImageReader;  writer            : TFPCustomImageWriter;begin  // Create in-memory image  SourceImage       := TFPMemoryImage.Create(300, 273);  // Create appropiate reader  Reader          := TFPReaderPNG.Create;  // Read imagedata from file  SourceImage.LoadFromFile(AFileName, Reader);  // Create a canvas for the image  SourceCanvas := TFPImageCanvas.Create(SourceImage);   // Prepare destination  DestinationImage  := TFPMemoryImage.Create(300, 273);  DestinationCanvas := TFPImageCanvas.Create(DestinationImage);   CopyPartOfImage(SourceCanvas, DestinationCanvas, 0, 0, 50, 50);   Writer := TFPWriterPNG.Create;  DestinationImage.SaveToFile(ADestFileName, Writer);   // Clean up  SourceImage.Free;  DestinationImage.Free;    SourceCanvas.Free;  DestinationCanvas.Free;    Reader.Free;  Writer.Free;end;  //// additive-colors.png (300 x 273)// begin  ElaboraSingolaImmagine('additive-colors.png', 'result1.png');end.  Yes, the TFPcolor is 16 bits per gun, see documentation. QuoteThe TFPColor record contains the Red, Green, Blue and Alpha channel values as left adjusted 16 bit words, with increasing intensity from 0 to $FFFF edit: sorry for my terrible typo's in English comments inside the source-code -> i've made some improvements to them so you are (hopefully) able to translate better.