Forum > Graphics

[SOLVED] How to set the maximum height and size of JPEG with TFPWriterJPEG

(1/1)

Gizmo:
I had assumed this would be really simple, but, it is currently defeating me!

All I want to do is :

1) Read an existing file of type JPEG
2) Not display it, or drag it on screen, at all.
3) Save it as a new file, with a max height of 1024, or a max width of 1024

Like what you can do using ImageMagick -convert. The following code (courtesy of rvk in another thread) creates a new copy of the JPEG with lesser filesize due to lesser compression which is a great start. I just need to also say "make sure the output is no bigger than 1024 pixels wide or high". :


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---uses  ... BGRABitmap, FPWriteJpeg;...procedure TForm1.Button1Click(Sender: TObject);var  bmp: TBGRABitmap;  jpgWriter: TFPWriterJPEG;begin  bmp := TBGRABitmap.Create('MyInputFile.jpg');  jpgWriter := TFPWriterJPEG.Create;  jpgWriter.CompressionQuality := 80;  bmp.SaveToFile('MyOutputFile.jpg', jpgWriter);  jpgWriter.Free;  bmp.Free;end; end. 
But is there not an easy way to set the maximum height and size with TFPWriterJPEG?

TRon:

--- Quote from: Gizmo on February 10, 2024, 12:19:43 am ---All I want to do is :

1) Read an existing file of type JPEG
2) Not display it, or drag it on screen, at all.
3) Save it as a new file, with a max height of 1024, or a max width of 1024

--- End quote ---

You need to actually crop the image.

Example that uses fpimage:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure cropimage(aImage: TFPCustomImage; aWidth, aHeight: integer);var  tmpimage  : TFPCustomImage;  tmpcanvas : TFPCustomCanvas;begin  if aImage.Width  < aWidth  then aWidth  := aImage.Width;  if aImage.Height < aHeight then aHeight := aImage.Height;   tmpimage  := TFPMemoryImage.Create(aWidth,aHeight);  tmpcanvas := TFPImageCanvas.Create(tmpimage);   tmpcanvas.Draw(0,0, aImage);  aImage.Assign(tmpimage);   tmpCanvas.Free;  tmpImage.Free;end; procedure dodo;var  img : TFPCustomImage;  writer : TFPCustomImageWriter;begin  img := TFPMemoryImage.Create(0,0);   img.LoadFromFile('MyInputFile.jpg');  cropimage(img, 1024, 1024);   writer := TFPWriterJpeg.Create;  (writer as TFPWriterJpeg).CompressionQuality := 80;  img.SaveToFile('MyOutputFile.jpg', writer);  writer.free;   img.Free;end; 
PS: do realize that every time you load and save a jpg that you have (further) loss of quality as jpg is lossy by default.

wp:
I don't fully understand what you mean by "max height of 1024, or a max width of 1024". Probably you want to rescale the image and keep the width-to-height aspect ratio such that the longest of the two is 1024. You can do this with fcl-image by using a pixel interpolation. The attached project reads the Lazarus cheetah (copy the image from (lazarus)/images/splash_source in the project folder) and rescales it to a width or height of 512 pixels (whichever is larger).


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project1;uses  FPImage, FPCanvas, FPImgCanv, FPReadJPEG, FPWriteJPEG;const  FILE_NAME = 'cheetah.jpg';  MAX_SIZE = 512;var  srcImg, destImg: TFPMemoryImage;  canvas: TFPImageCanvas;  scaleFactor: Double;begin  // Create and load the source image  srcImg := TFPMemoryImage.Create(0, 0);  srcImg.LoadFromFile(FILE_NAME);   // Calculate the image scaling factor  if srcImg.Width > srcImg.Height then    scaleFactor := MAX_SIZE / srcImg.Width  else    scaleFactor := MAX_SIZE / srcImg.Height;   // Create the destination image in the requested size  destimg := TFPMemoryImage.Create(round(srcImg.Width*scaleFactor), round(srcImg.Height*scaleFactor));   // Create a canvas for the destination image ...  canvas := TFPImageCanvas.Create(destImg);   // ... and an interpolation  canvas.Interpolation := TFPBaseInterpolation.Create;   // Use the interpolation to stretch the source image to the new size  canvas.StretchDraw(0, 0, destImg.Width, destImg.Height, srcImg);   // Save destination image to file  destImg.SaveToFile('resized.jpg');   // Clean up  canvas.Interpolation.Free;  canvas.Free;  destImg.Free;  srcImg.Free;end.
Updated the wiki with this sample code (https://wiki.freepascal.org/fcl-image#Rescaling_a_bitmap_image).

Gizmo:
Many thanks for the methods here all. I've gone with wp's suggestion which, having looked at it, works just fine and I am kicking myself for not figuring it out myself. Thanks for the guidance.

Navigation

[0] Message Index

Go to full version