![]() |
Jpeg komprimieren
Hallo,
ich habe für eine JPEG Bildkomprimierung den Delphi Beispiel Code genommen... Er macht auch alles wunderbar...Nur das Problem ist ich wollte das neue Bild was in TImage angezeigt wird speichern. Mit:
Delphi-Quellcode:
Wenn ich diesen schritt aber ausführe speichert er mir das alte (nicht komprimierte) bild....
image1.picture.savetofile('xyz.jpeg');
Was mach ich falsch?
Delphi-Quellcode:
unit jpegdemo;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, jpeg, ExtCtrls, FileCtrl, ComCtrls, Menus, printers; type TForm1 = class(TForm) Panel1: TPanel; DirectoryListBox1: TDirectoryListBox; FileListBox1: TFileListBox; Panel3: TPanel; DriveComboBox1: TDriveComboBox; Scale: TComboBox; PixelFormat: TComboBox; ColorSpace: TComboBox; Performance: TComboBox; ProgressiveDisplay: TCheckBox; IncrementalDisplay: TCheckBox; MainMenu1: TMainMenu; File1: TMenuItem; Open1: TMenuItem; N1: TMenuItem; Print1: TMenuItem; PrinterSetup1: TMenuItem; N2: TMenuItem; Exit1: TMenuItem; OpenDialog1: TOpenDialog; PrinterSetupDialog1: TPrinterSetupDialog; PrintDialog1: TPrintDialog; ScrollBox1: TScrollBox; Image1: TImage; procedure FileListBox1DblClick(Sender: TObject); procedure SetJPEGOptions(Sender: TObject); procedure FormCreate(Sender: TObject); procedure ProgressUpdate(Sender: TObject; Stage: TProgressStage; PercentDone: Byte; RedrawNow: Boolean; const R: TRect; const Msg: string); procedure Open1Click(Sender: TObject); procedure Print1Click(Sender: TObject); procedure PrinterSetup1Click(Sender: TObject); procedure Exit1Click(Sender: TObject); private { Private declarations } public { Public declarations } procedure OpenFile(const Filename: string); end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.OpenFile(const Filename: string); begin try Image1.Picture.LoadFromFile(Filename); except on EInvalidGraphic do Image1.Picture.Graphic := nil; end; SetJPEGOptions(self); end; procedure TForm1.FileListBox1DblClick(Sender: TObject); begin OpenFile(FileListbox1.Filename); end; procedure TForm1.SetJPEGOptions(Sender: TObject); var Temp: Boolean; begin Temp := Image1.Picture.Graphic is TJPEGImage; if Temp then with TJPEGImage(Image1.Picture.Graphic) do begin PixelFormat := TJPEGPixelFormat(Self.PixelFormat.ItemIndex); Scale := TJPEGScale(Self.Scale.ItemIndex); Grayscale := Boolean(Colorspace.ItemIndex); Performance := TJPEGPerformance(Self.Performance.ItemIndex); ProgressiveDisplay := Self.ProgressiveDisplay.Checked; end; Scale.Enabled := Temp; PixelFormat.Enabled := Temp; Colorspace.Enabled := Temp; Performance.Enabled := Temp; ProgressiveDisplay.Enabled := Temp and TJPEGImage(Image1.Picture.Graphic).ProgressiveEncoding; Image1.IncrementalDisplay := IncrementalDisplay.Checked; end; procedure TForm1.FormCreate(Sender: TObject); begin Scale.ItemIndex := 0; PixelFormat.ItemIndex := 0; Colorspace.ItemIndex := 0; Performance.ItemIndex := 0; OpenDialog1.Filter := GraphicFilter(TGraphic); FileListbox1.Mask := GraphicFileMask(TGraphic); Image1.OnProgress := ProgressUpdate; end; procedure TForm1.ProgressUpdate(Sender: TObject; Stage: TProgressStage; PercentDone: Byte; RedrawNow: Boolean; const R: TRect; const Msg: string); begin if Stage = psRunning then Caption := Format('%d%%',[PercentDone]) else Caption := 'Form1'; end; procedure TForm1.Open1Click(Sender: TObject); begin if OpenDialog1.Execute then OpenFile(OpenDialog1.FileName); end; procedure TForm1.Print1Click(Sender: TObject); var AspectRatio: Single; OutputWidth, OutputHeight: Single; begin if not PrintDialog1.Execute then Exit; Printer.BeginDoc; try OutputWidth := Image1.Picture.Width; OutputHeight := Image1.Picture.Height; AspectRatio := OutputWidth / OutputHeight; if (OutputWidth < Printer.PageWidth) and (OutputHeight < Printer.PageHeight) then begin if OutputWidth < OutputHeight then begin OutputHeight := Printer.PageHeight; OutputWidth := OutputHeight * AspectRatio; end else begin OutputWidth := Printer.PageWidth; OutputHeight := OutputWidth / AspectRatio; end end; if OutputWidth > Printer.PageWidth then begin OutputWidth := Printer.PageWidth; OutputHeight := OutputWidth / AspectRatio; end; if OutputHeight > Printer.PageHeight then begin OutputHeight := Printer.PageHeight; OutputWidth := OutputHeight * AspectRatio; end; Printer.Canvas.StretchDraw(Rect(0,0, Trunc(OutputWidth), Trunc(OutputHeight)), Image1.Picture.Graphic); finally Printer.EndDoc; end; end; procedure TForm1.PrinterSetup1Click(Sender: TObject); begin PrinterSetupDialog1.Execute; end; procedure TForm1.Exit1Click(Sender: TObject); begin Close; end; end. |
Re: Jpeg komprimieren
Das jpeg-Format ist doch schon eine Möglichkeit Bildinformationen mit möglichst wenig Speicherbedarf darzustellen.
Macht da der Versuchg das noch mal zu "packen" wirklich Sinn ? Ich meine - Nein Gruß Matthias |
Re: Jpeg komprimieren
das ding ist für einen streamshot der erzeugt wird und ca. 3mb groß wird...
Das ding soll dann über LAN verschickt werden....(und das jede sekunde) Das ist das Problem an der Sache. Der Vorgang läuft dabei so ab, dass zuerst ein vitruelles BMP erzeugt wird, das wird in ein Timage geladen und als jpeg gespeichert. Vllt. liegt ja da der fehler drin... |
Re: Jpeg komprimieren
HI,
ich glaube mal du möchtest dann doch eher einen Screenshot verschicken, keinen Streamshot. Aber irgendwie fehlt ein wenig der Code, der von dir stammt oder sehe ich den nur nicht? Was die Anzeige auf deinem Bildschirm (damit insbesondere auf deinem TImage) angeht, so wirst du garnicht um ein Bitmap rumkommen. In wie weit dieses jetzt rein virtuell ist, nun ja. Wenn du ein TJpeg verwendest, kannst du hier mittel BitmapNeeded (oder so ähnlich) sagen, dass der Inhalt dekomprimiert werden soll, analog wird er erst mit JpegNeeded komprimiert. Wichtig ist es, dass du daran denkst, dass ein JPEG immer verlustbehaftet komprimiert, selbst bei 100% Qualität. Also möglichst selten das gleiche Bild speichern. Wenn du jede Sek. einen Screenshot machst und verschickst, hätte ich mal die Frage, warum du das Bild dann auch immer gleich anzeigst? Also auf dem Rechner der es empfängt mag das noch sinnvoll sein, aber da wo du den Screenshot machst? Lass einfach das Image weg, nimm dir direkt eine TBitmap-Instanz, weiß die (mittels assign) einem TJpeg zu und verschick dieses (achtung, nach dem Verschicken natürlich den Speicher des TJpeg frei geben!). Ok, sehe gerade deinen Fehler. Wie gesagt, alles was dein Image anzeigt ist immer ein Bitmap (im Speicher). Du musst schon die Instanz von TJpeg abspeichern! Gruß Der Unwissende |
Re: Jpeg komprimieren
das hab ich irgendwie net kapiert wie speicher ich die instanz als tjepg????
|
Re: Jpeg komprimieren
Sorry, meine die Instanz von TJpegImage, nicht TJpeg.
Du hast etwas in der Art:
Delphi-Quellcode:
Zudem entfällt im zweiten Fall auch gleich die eventuell unnötige Anzeige des Jpegs.
var Image : TImage;
bitmap : TBitmap; jpeg : TJpegImage; begin bitmap := macheDeinenScreenshot; jpeg := TJpegImage.Create; try jpeg.Assign(bitmap); // stell alles an Kompression und ähnlichem ein ... // hier der falsche Weg: // Es wird eigentlich nur das angezeigte Bitmap gespeichert Image.Picture := jpeg; Image.Picture.SaveToFile(...); // hier der richtige Weg: jpeg.SaveToFile(...); finally jpeg.Free; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz