Recent

Author Topic: [SOLVED] Need some help with my first lazarus project.  (Read 3487 times)

panosdk

  • New Member
  • *
  • Posts: 16
[SOLVED] Need some help with my first lazarus project.
« on: May 02, 2016, 11:25:27 pm »
I decided to learn lazarus and pascal in order to make a simple image compression program. Of course there are some programs that do that but...
1) I dont want to install .net framework
2) I want it to be crossplatform(win,linux) 
3) And most important i want to have a good time creating something.

After i made the basic stuff, like opening an image show it on a picture box then compress and save it, i decided to try and add features. One feature that i am writing right now is the ability to paste an image from clipboard and then compressed it. I will add here the paste procedure and the compress procedure. My problem is that the compress procedure checks for Assigned(pic). Well i am a complete noob (3 days into lazarus) and i dont know how to tell my program that i have a pic from the clipboard so i can pass that check. So if anyone has time please give me a hand. Thank you.

[paste from clipboard code]
Code: Pascal  [Select][+][-]
  1. procedure Tform1.menupasteclipClick(Sender: TObject);
  2.  
  3.   var
  4.   tempBitmap: TBitmap;
  5.   PictureAvailable: boolean = False;
  6.  
  7. begin
  8.   // we determine if any image is on clipboard
  9.   if (Clipboard.HasFormat(PredefinedClipboardFormat(pcfDelphiBitmap))) or
  10.     (Clipboard.HasFormat(PredefinedClipboardFormat(pcfBitmap))) then
  11.     PictureAvailable := True;
  12.  
  13.   if PictureAvailable then
  14.   begin
  15.  
  16.     tempBitmap := TBitmap.Create;
  17.     if Clipboard.HasFormat(PredefinedClipboardFormat(pcfDelphiBitmap)) then
  18.       tempBitmap.LoadFromClipboardFormat(PredefinedClipboardFormat(pcfDelphiBitmap));
  19.  
  20.     if Clipboard.HasFormat(PredefinedClipboardFormat(pcfBitmap)) then
  21.       tempBitmap.LoadFromClipboardFormat(PredefinedClipboardFormat(pcfBitmap));
  22.  
  23.     //Image1.Width := tempBitmap.Width;
  24.     //Image1.Height := tempBitmap.Height;
  25.  
  26.  
  27.     image1.Canvas.Draw(0, 0, tempBitmap);
  28.    
  29.     lbl_size.Caption:='Width x Height: ' + inttostr(tempbitmap.Width) + ' x ' +
  30.     inttostr(tempbitmap.Height);
  31.  
  32.  
  33.     image1.Picture.Bitmap.Assign(tempBitmap);
  34.  
  35.  
  36.     tempBitmap.Free;
  37.   end
  38.   else
  39.   begin
  40.  
  41.     ShowMessage('No image is found on clipboard');
  42.  
  43.   end;
  44. end;                                        
  45.  

[compression code]
Code: Pascal  [Select][+][-]
  1. procedure Tform1.btn_convertClick(Sender: TObject);
  2.   var
  3.   MyStream: TMemoryStream;
  4. begin
  5.   if Assigned(pic) then begin
  6.  
  7.     if Assigned(jpg) then FreeAndNil(jpg);
  8.     jpg:=TJPEGImage.Create;
  9.  
  10.     try
  11.       jpg.CompressionQuality:=Slider.Position;
  12.       jpg.Assign(pic.Bitmap);
  13.       MyStream := TMemoryStream.create;
  14.       jpg.SaveToStream(MyStream);
  15.       MyStream.Position:=0;
  16.     finally
  17.       image2.Picture.LoadFromStream(MyStream);
  18.       FreeAndNil(MyStream);
  19.     end;
  20.  
  21.   end;
  22.   btn_save.Enabled:=true;
  23.   menusave.Enabled:=true;
  24. end;                      
  25.  


By the way its pretty impressive what a noob can do in lazarus. So a big thanks to all the devs for this amazing tool. http://tinypic.com/r/2vjq001/9
« Last Edit: May 04, 2016, 01:33:22 pm by panosdk »

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: Need some help with my first lazarus project.
« Reply #1 on: May 03, 2016, 12:09:51 am »
If I understand you correctly you first paste the clipboard (which contains an image) into a TImage component, and then you want to convert this image to a compressed jpeg and you want to display this (lower-quality) image in another TImage component for comparison?

So what is "pic"? It is not declared anywhere in your code excerpt. But I guess you don't need it. Just assign the bitmap of the image (Image1.Picture.Bitmap) to a temporary jpg which you then can either SaveToStream or assign to the bitmap of another TImage component:
Code: Pascal  [Select][+][-]
  1. procedure Tform1.btn_convertClick(Sender: TObject);
  2. var
  3.   jpg: TJPEGImage;   // make it local, I think you don't need the jpeg anywhere else.
  4. begin
  5.   // Create temporary jpeg
  6.   jpg := TJPEGImage.Create;
  7.   try
  8.     // Set up jpeg compression & quality
  9.     jpg.CompressionQuality := Slider.Position;
  10.     // copy bitmap from Image1 to this jpeg
  11.     // Note that this compresses the image according to the CompressionQuality.
  12.     jpg.Assign(Image1.Picture.Bitmap);
  13.     // Assign compressed image to a second TImage
  14.     Image2.Picture.Bitmap.Assign(jpg);
  15.     // Re-enable button and menu
  16.     // Note: I am missing a bnt_save.enabled := false at the beginning of this procedure! Dto with menusave.
  17.     btn_save.Enabled:=true;  
  18.     menusave.Enabled:=true
  19.   finally
  20.     // destroy temporary jpeg image (Note: this does not affect Image2)
  21.     jpg.Free;
  22.   end;
  23. end;

panosdk

  • New Member
  • *
  • Posts: 16
Re: Need some help with my first lazarus project.
« Reply #2 on: May 03, 2016, 07:30:18 pm »
Thank you for taking the time to help me. The code works but it doesnt compress images which is weird. I am using jpg to save the picture so i have it as a global. But it the code doesnt compress if its a global or a local variable.

Code: Pascal  [Select][+][-]
  1. procedure Tform1.btn_saveClick(Sender: TObject);
  2. begin
  3.    if SaveDialog1.Execute then
  4.    begin
  5.       try
  6.       jpg.SaveToFile(savedialog1.FileName);
  7.       except
  8.       on e: exception do // Exception handling
  9.       begin
  10.       showmessage('Error: ' + e.message);
  11.       end;
  12.       end;
  13.    end;
  14.  
  15. end;                                        
  16.  

By the way this program is based on an article on lazplanet (http://lazplanet.blogspot.gr/2014/03/how-to-compress-image-to-jpg-wo-preview.html)

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: Need some help with my first lazarus project.
« Reply #3 on: May 03, 2016, 08:39:04 pm »
The code works but it doesnt compress images which is weird.
How can you tell? But it is true, my code compresses when the image is assigned to the jpg, but when the jpg is assigned to the other image it becomes a bitmap and expands again. Since you did not write the image to disk I thought your intention of showing the jpg in an image was to visualize the quality loss of the jpg...

Look here: this code writes the bitmap and jpg images to a temporay stream and determines their size this way:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. var
  3.   jpg: TJpegImage;
  4.   stream: TMemorystream;
  5.   bmpSize: Integer;
  6.   jpgSize: Integer;
  7. begin
  8. //  Image1.Picture.SaveToFile('d:\test.bmp');
  9.   stream := TMemorystream.Create;
  10.   Image1.Picture.SaveToStream(stream);
  11.   bmpSize := stream.Size;
  12.   stream.Free;
  13.  
  14.   jpg := TJpegImage.Create;
  15.   jpg.CompressionQuality := 20;
  16.   jpg.Assign(Image1.Picture.Bitmap);
  17.   stream := TMemorystream.Create;
  18.   jpg.SaveToStream(stream);
  19.   jpgSize := stream.Size;
  20.   stream.Free;
  21.   //jpg.SaveToFile('d:\temp.jpg');
  22.   jpg.Free;
  23.  
  24.   Label1.Caption := Format('Bitmap size: %d KB, jpeg size: %d KB', [bmpSize div 1024, jpgSize div 1024]);
  25. end;

panosdk

  • New Member
  • *
  • Posts: 16
Re: Need some help with my first lazarus project.
« Reply #4 on: May 04, 2016, 01:32:43 pm »
Yes i added the stream from the example code before seeing your message and everything works smooth. Also you saved me of a great headache of trying to find a way to calculate the size of the image. I have a lot to learn from this code. Thank you once again.

 

TinyPortal © 2005-2018