[Delphi] zmiana rozmiarow JPEG

0

Chcę zrobić prosty program, który:

  • pobierze nazwę pliku z parametrów wywołania
  • jeżeli plikiem tym jest JPG, to ma zmienić jego rozmiar (np. do 33%)
  • zamknąć program

No i chodzi o to, że problem wydaje się być na tyle prosty, że chciałbym wiedzieć, jak go nie komplikować
Czy program taki potrzebuje formatki?
Czy ma własną obsługę zmiany rozmiaru i zapisu pliku JPEG?

Korzystam z Borland Delhi 6.0 PE

0

Nie program, nie potrzebuje formatki. Piszesz tak zwaną aplikację konsolową, działającą w trybie wsadowym. O aplikacjach konsolowych chyba był kiedyś artykuł.

A obsługa JPEG jest wpudowana w Delphi 6, wystarczy dodać moduł jpeg do sekcji uses.

0

O zmianie rozmiarów JPEGów możesz poczytać tutaj

0

Sposób na zmianę rozmiaru jpeg już znalazłem
dokładnie taki sam, dzieki :)
tylko nie mogę w żaden sposób znaleźć, jak pozbyć się formatki z programu
umiem ją ukryć za pomocą Application.ShowMainForm:=false; dodanym w głónym unicie, jednak wciąż wydaje mi się, że sam fakt jej istnienia w programie, powoduje że program zajmuje dużo i wolno się uruchamia

nie mogę znaleźć nic o tym, jak wykorzystać barch file, czy console application tak, żeby nic mi nie wyskakiwało, działalo w tle i szybko

Enybady?

Aplikację kosolową stworzyć umiem, ale dalej problem jest taki, że wyskakuje to czarne okienko, a ja żadnego nie chcę :/

0

Chciałbym jeszcze pociągnąć temat, chociaż już sprawa tyczy się tylko zmniejszenia rozmiaru aplikacji. Z UPX korzystać umiem, jednak wydaje mi się, że coś tu się jeszcze da zrobić. Oto dwa kody:

Pierwszy, utworzony jako aplikacja konsolowa:

program Resizer;

uses
  JPEG, Graphics, Types;

var
  JPG : TJPEGImage;
  BMP : TBitmap;
  NewHeight, NewWidth : Integer;
  OldName, NewName:string;
  i :integer;

begin
  { TODO -oUser -cConsole Main : Insert code here }

  if (ParamCount<1) then halt;

  JPG := TJPEGImage.Create;
  BMP := TBitmap.Create;
  for i:=1 to ParamCount do begin
   try
    OldName:=ParamStr(i);
    if ((ExtractFileExt(OldName)<>'.jpg') and (ExtractFileExt(OldName)<>'.jpeg')) then continue;
    JPG.LoadFromFile(OldName);
    NewName:=ExtractFilePath(ParamStr(i))+'sm_'+ExtractFileName(ParamStr(i));
    BMP.Assign(JPG);

    NewHeight := BMP.Height div 3; //tu ustawiamy jaką wielkośc ma mieć pomniejszony obrazek
    NewWidth := BMP.Width div 3;

    BMP.Canvas.StretchDraw(Rect(0, 0, NewWidth, NewHeight), BMP);
    BMP.Width := NewWidth;
    BMP.Height := NewHeight;
    JPG.Assign(BMP);
    JPG.SaveToFile(NewName);
   except
   end;
  end;
  BMP.Free;
  JPG.Free;
end.

Pozbyłem się nim wszystkich packages (w opcjach projektu), kilku elementów uses oraz dyrektywy(?) na początku pliku "{$APPTYPE CONSOLE}", która zablokowała wyświetlanie denerwującego mnie okienka.
Rozmiar aplikacji 234kB.

Drugi kod, pierwotny, pisany jako zwykłą aplikacja, w której schowałem formatkę:

program resizer;

uses
  Forms, Unit1 in 'Unit1.pas';

{$R *.res}

begin
  Application.Initialize;
  Application.Title := 'Beton''s Resizer';
  Application.Run;
end.

i kod unit1:

unit Unit1;

interface

uses SysUtils, Classes, Graphics, Forms, JPEG;

implementation

procedure Zmniejsz;
var
  JPG : TJPEGImage;
  BMP : TBitmap;
  NewHeight, NewWidth : Integer;
  OldName, NewName:string;
  i :integer;
begin
  // sprawdź, czy podano parametry
  if (ParamCount<1) then Application.Terminate;

  JPG := TJPEGImage.Create;
  BMP := TBitmap.Create;
  for i:=1 to ParamCount do begin
   try
    OldName:=ParamStr(i);
    // sprawdź, czy ma rozszerzenie jpg lub jpeg
    if ((ExtractFileExt(OldName)<>'.jpg') and (ExtractFileExt(OldName)<>'.jpeg')) then continue;
    NewName:=ExtractFilePath(ParamStr(i))+'sm_'+ExtractFileName(ParamStr(i));
    JPG.LoadFromFile(OldName);
    BMP.Assign(JPG);

    //tu ustawiamy jaką wielkośc ma mieć pomniejszony obrazek
    NewHeight := BMP.Height div 3;
    NewWidth := BMP.Width div 3;

    BMP.Canvas.StretchDraw(Rect(0, 0, NewWidth, NewHeight), BMP);
    BMP.Width := NewWidth;
    BMP.Height := NewHeight;
    JPG.Assign(BMP);
    JPG.SaveToFile(NewName);
   except
   end;
  end;
  BMP.Free;
  JPG.Free;
  Application.Terminate;
end;

begin
  Zmniejsz;
end.

I w tym programie również pozbyłem się elementów uses, pliku *.dfm oraz packages. Formatka się nie wyświetla, bo zablokowałem jej tworzenie.
Program ten jednak po skompilowaniu ma 437kB.

I jedyne, co wiem, ze mogę zrobić w drugim przypadku, to usunięcie resources (tak jak w artykule "Mały EXE").

Ciągle jednak podejrzewam, że robię to źle i kompilator za dużo dodaje do mojego programu. Na forum i w artykułach nie mogę znaleźć już nic na ten temat.

Kompresję UPX-em chcę stosować dopiero po wyczerpaniu wszystkich możliwości, a ta w tym przypadku daje zysk 50%, chociaż zwalnia działanie programu.

0

uses SysUtils, Classes, Graphics, Forms, JPEG;

Ten moduł w drugim wypadku odpowiada ze tą ogromną wielkość - bo zawiera cały VCL dotyczący form. Spróbuj go wykopać, a takzę usunać Appliation.Terminate (Bo Application jest zadeklarowana w Forms). Chyba nic więcej co wykorzystuje FOrms nie zauważyłem.

0

w pierwszym przypadku "zjadło mi się" SysUtils w sekcji uses :/

no i wychodzi na to, że przy tych modyfikacjach kod drugi będzie taki sam, jak w pierwszym wypadku.

Może coś z opcjami kompilacji trzeba namieszać?
Plik resizer.cfg:

-$A8
-$B-
-$C+
-$D+
-$E-
-$F-
-$G+
-$H+
-$I+
-$J-
-$K-
-$L+
-$M-
-$N+
-$O+
-$P+
-$Q-
-$R-
-$S-
-$T-
-$U-
-$V+
-$W-
-$X+
-$YD
-$Z1
-cg
-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
-H+
-W+
-M
-$M16384,1048576
-K$00400000
-LE"c:\program files\borland\delphi6\Projects\Bpl"
-LN"c:\program files\borland\delphi6\Projects\Bpl"

wybaczcie ten alfabetyczny bełkot :P

Aha i co zmienia usunięcie packages?

Jest jeszcze plik .dof, ale wydaje mi się, że .cfg jest bardziej istotny.

0
ptaken napisał(a)

Może coś z opcjami kompilacji trzeba namieszać?
Plik resizer.cfg

Ten plik zawiera opcje kompilacji zmieniane bezpośrednio w Delphi.
A spróbować zmniejszyć rozmiar możesz na dwa sposoby:

Możesz poeksperymentować na zakładce Packages (Project|Options) - usunąć zaznaczenie bibliotek (Design Packages), których nie używasz w swoim programie, ale jest ryzyko, że bez niektórych program może się nie uruchomić albo będziesz miał problemy z kompilowaniem.

Drugim sposobem jest zaznaczenie pola Buid with runtime packages, co spowoduje całkowite wyłączenie wszystkich bibliotek z projektu. W tym przypadku program będzie korzystał z zewnętrznym bibliotek, co wymusza ich obecność na każdym komputerze, na którym ma działać program (muszą być dołączone jako osobne pliki).

0

opcje projektu->compiler->odznacz wszystko co jest w Runtime errors i w Debugging, po czym zbuduj projekt od nowa

0

Do pomniejszania exe można użyć pakera upx który zmniejszy execa do około 150 kb.

UPX.exe -9 prog.exe

0

dzięki wacek za odkrywaczą wskazówkę

czy to, co robię da się napisać w WinAPI i będzie mniejsze i szybsze?

0

Da się. I pewnie będzie mniejsze i szybsze.

See this:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6145.asp

A jeżeli chcesz to zrobić jeszce mniejsze, to chyba tylko już .NET zostanie. Można to napisać albo w C#, albo w Delphi.NET bez użycia VCL.NET. Odpowiednie procedury znajdą się pewnie w namespace System.Drawing.Imaginig. Ale to będzie wymagało .NET Framework do działania, i takie super-szybkie nie będzie (bo .NET Framework jeszce zaangażowany w uruchomienie będzie i kompilacja MSIL przed uruchomieniem...).

1 użytkowników online, w tym zalogowanych: 0, gości: 1