(SOLVED) Unit Resize image error lazarus / 39-Graphics ---------------------------------------------------------------------- xinyiman · 2012-07-24 06:10 Hello guys I know who explain why the following code in linux and windows not working properly? I do not understand this function should reduce the image passed.  Alternatively if anyone has some code that does the same job that runs on both windows and linux that it could post? Why this unit generate error in windows?! (correctly run in linux) Code: [Select] unit RidimensionareImmagini; {$mode objfpc}{$H+} interface uses   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,   ExtCtrls; procedure GenerarMini(var MioStream: TStream; mode:integer; Altezza: integer; Larghezza: integer; NomeFileAppoggio: string); implementation uses unit1; procedure GenerarMini(var MioStream: TStream; mode:integer; Altezza: integer; Larghezza: integer; NomeFileAppoggio: string); var   jpg1, jpg2: TJPEGImage;   nf, nf2:    string;   esX, esY: double;   an, al, X, Y: integer;   swOk: boolean; begin   try   try   jpg1 := TJPEGImage.Create;   jpg2 := TJPEGImage.Create;   jpg2.SetSize(Larghezza, Altezza);   If FileExists(NomeFileAppoggio) Then     DeleteFile(NomeFileAppoggio);   nf2 := NomeFileAppoggio;   try     swOk := True;     jpg1.LoadFromStream(MioStream);   except     swOk := False;   end;   if swOk then   begin     // +---- Calcular la escala para no deformar ------------------------------+     // +---- Calculating the scale to avoid deforming -------------------------+     an := jpg2.width;     al  := jpg2.height;     esX := an / jpg1.Width;     esY := al / jpg1.Height;     // +---- Solo se escala el lado que sea necesario -------------------------+     if esX > esY then       an := trunc(jpg1.Width * esY + 0.5)     else       al := trunc(jpg1.Height * esX + 0.5);     case mode of       1:begin         // +----- Fijo a 120x90, centrando --------------------------------------+         // +----- Fixed 120x90, centering ---------------------------------------+         //X:=(120-an) div 2; Y:=(90-al) div 2; // Centrar         X:=(Larghezza-an) div 2; Y:=(Altezza-al) div 2; // Centrar         jpg2.Canvas.StretchDraw(Rect(X, Y, X+an, Y+al), jpg1);       end;       2: begin         // +----- Respetando el tamaño -----------------------------------------+         // +----- keeping the ratio -----------------------------------------------+         jpg2.SetSize(an, al);         jpg2.Canvas.StretchDraw(Rect(0, 0, an, al), jpg1);       end;     end;     jpg2.CompressionQuality := 90;  // Or whatever you want.     jpg2.SaveToFile(nf2);   end;   MioStream.Destroy;   MioStream:=TFileStream.Create(NomeFileAppoggio, fmOpenRead);   MioStream.Position := 0;   jpg1.Free;   jpg2.Free;   If FileExists(NomeFileAppoggio) Then     DeleteFile(NomeFileAppoggio);   finally   end; except      on E: Exception do      begin           ShowMessage(E.Message);      end; end; end; end. Test code: Code: [Select]procedure TForm3.Button1Click(Sender: TObject); var    FileStream: TFileStream; begin      Form1.AltezzaDaRidimensionare:=Spin_Altezza.Value;      Form1.LarghezzaDaRidimensionare:=Spin_Larghezza.Value;      {ora mi sono recuperato le dimensioni che mi interessano}      If FileExists(application.Location + 'temp.jpg') then         DeleteFile(application.Location + 'temp.jpg');      Form1.Img_Rimpicciolita.Picture.SaveToFile(application.Location + 'temp.jpg');      FileStream := TFileStream.Create(application.Location + 'temp.jpg', fmOpenRead);      GenerarMini(FileStream, 1, Form1.AltezzaDaRidimensionare , Form1.LarghezzaDaRidimensionare, Application.Location + 'temp.jpg');      Form1.Img_Rimpicciolita.Picture.LoadFromStream(FileStream);      FileStream.Destroy;      If FileExists(application.Location + 'temp.jpg') then         DeleteFile(application.Location + 'temp.jpg');      Close; end; Errors: 1#: Unable to create file 'c:\softwareP\temp.jpg' 2#: Stream read error ---------------------------------------------------------------------- xinyiman · 2012-07-24 06:23 Solved with this code GenerarMini(FileStream, 1, Form1.AltezzaDaRidimensionare , Form1.LarghezzaDaRidimensionare, Application.Location + 'temp1.jpg'); ---------------------------------------------------------------------- BigChimp · 2012-07-24 12:12 Ciao Xinyiman, So instead of telling it to process a file with Code: [Select]Application.Location + 'temp.jpg' you're specifying Code: [Select]Application.Location + 'temp1.jpg' ? Note: you could run into permission issues, e.g. on Windows if you install the application under admin e.g. in c:\program files\yourapplication, you don't have write access to that directory as a normal user (and on Vista and higher, IIRC even as an admin user unless you request elevated privileges from UAC). IIRC, Windows Vista+ with UAC has some "file overlay" system that transparently redirects these write operations for legacy applications into some directory that is writable by users, but it's a stopgap solution. On Linux/Unix/OSX, if your application is installed by e.g. root under a directory that normal users don't have write access to (which is normally everything except ~ and some other less relevant ones), you'll have similar problems. Solutions: - storing read-only unchanging data files in the application directory is fine. On Linux, IIRC, you might need to place large files somewhere in /var. No idea about OSX. - use the temp directory for temporary files (GetTempDirectory/GetTempFileName etc). For added security you can specify you want to use the user temp directory instead of the global temp directory - store user-specific data generated by the application where they belong (e.g. using fileutil.GetAppConfigDirUTF8/sysutils.GetAppConfigD ir/fileutil.GetAppConfigFileUTF8/sysutils.GetAppConfigFile; set the Global parameter to false) - store application wide configuration/data generated by the application where they belong (e.g. using fileutil.GetAppConfigDirUTF8 /sysutils.GetAppConfigDir/fileutil.GetAppConfigFileUTF8/sysutils.GetAp pConfigFile; set the Global parameter to true) I think there are some wiki pages (on multiplatform programming) that illustrate this. Regarding what your code actually does: does it generate a thumbnail jpg or something? Don't know much about graphics programming, suppose it looks reasonable, especially if you don't wnat to use external libraries. I would clean up the code indentation though... PS: Code with Italian variable names, and Spanish and English comments... very... international