[gelöst] JPG Größe anpassen
-
- Beiträge: 99
- Registriert: Do 23. Dez 2010, 19:10
- OS, Lazarus, FPC: Windows 10/11 32/64bit, L 3.2.0 32/64bit, FPC 3.2.2 32/64bit
[gelöst] JPG Größe anpassen
Hallo,
ich habe folgendes Problem:
Ich habe eine Datenbank. In dieser Datenbank sind Informationen gespeichert.
Jede Information soll so eine Art kleines Bild besitzen.
Der Benutzer wählt erin Bild aus.
Das Bild (egal welche Größe) soll kopiert und auf eine bestimmte Größe reduziert werden.
Ich habe nichts (vielleicht die falsche Frage bei g**gle eingegeben) gefunden, wie ich ein Bild (jpg) on the fly in der Größe reduzieren kann.
Gibt es eine einfache Methode die Bildgröße (ohne Controls) entsprechend zu reduzieren?
Danke.
ich habe folgendes Problem:
Ich habe eine Datenbank. In dieser Datenbank sind Informationen gespeichert.
Jede Information soll so eine Art kleines Bild besitzen.
Der Benutzer wählt erin Bild aus.
Das Bild (egal welche Größe) soll kopiert und auf eine bestimmte Größe reduziert werden.
Ich habe nichts (vielleicht die falsche Frage bei g**gle eingegeben) gefunden, wie ich ein Bild (jpg) on the fly in der Größe reduzieren kann.
Gibt es eine einfache Methode die Bildgröße (ohne Controls) entsprechend zu reduzieren?
Danke.
Zuletzt geändert von VB_Lazarus am So 31. Aug 2014, 12:04, insgesamt 1-mal geändert.
Re: JPG Größe anpassen
Auf ein neues TBitmap oder TJPEGImage Stretchdrawen.
http://lazarus-ccr.sourceforge.net/docs ... hdraw.html
Z.B.
Könnte man noch proportional machen.
http://lazarus-ccr.sourceforge.net/docs ... hdraw.html
Z.B.
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
var i:TJPEGImage;
begin
i:=TJPEGImage.Create;
i.SetSize(100,100);
i.Canvas.StretchDraw(Rect(0,0,100,100),Image1.Picture.Jpeg);
i.SaveToFile('/home/theo/test38.jpg');
i.free;
end;
-
- Beiträge: 298
- Registriert: Di 23. Nov 2010, 23:41
- OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
- CPU-Target: 32Bit/64Bit
- Wohnort: Geldern
- Kontaktdaten:
Re: JPG Größe anpassen
also bei mir klappt das mit g**gle
g**gle:) free pascal dynamisch skalierte bilder
bei dieser Abrage führt der 1.Treffer http://www.gocher.me/dynamic-scaled-images zu meiner Methode (ohne visuelle Komponenten), einfach ist dieser Weg allerdings nicht, aber sehr schnell!
Ich nutze diese Variante um auf meiner Homepage die Thumbnails zu generieren, bei JPGs nutze ich dafür auch das Vorschaubild falls vorhanden,
ich speichere die Bilder allerdings nicht, denn das ist nur Platzverschwendung und die Zeit zum auslesen der internen Vorschau ist zu vernachlässigen, dabei fällt mir auf, dass ich die Unit FPWriteGIF (enthält allerdings keine Lösung für animierte GIFs) noch veröffentlichen sollte die existiert in Free Pascal noch nicht. (ist nun bereits passiert!!)
sMimeType = 'image/jpeg', 'image/png', 'image/gif', 'image/bmp' ( 'image/bmp' wird automatisch nach 'image/jpeg' konvertiert)
bCrop (nie verzerren, bei bCrop beschneiden auf LWidth, LHeight, sonst einpassen)
das skalierte Bild liegt dann im MemoryStream, kann man dann speichern, muss man aber nicht
g**gle:) free pascal bilder skalieren --> ... etliche Treffer zu deiner Frage
g**gle:) free pascal dynamisch skalierte bilder
bei dieser Abrage führt der 1.Treffer http://www.gocher.me/dynamic-scaled-images zu meiner Methode (ohne visuelle Komponenten), einfach ist dieser Weg allerdings nicht, aber sehr schnell!
Ich nutze diese Variante um auf meiner Homepage die Thumbnails zu generieren, bei JPGs nutze ich dafür auch das Vorschaubild falls vorhanden,
ich speichere die Bilder allerdings nicht, denn das ist nur Platzverschwendung und die Zeit zum auslesen der internen Vorschau ist zu vernachlässigen, dabei fällt mir auf, dass ich die Unit FPWriteGIF (enthält allerdings keine Lösung für animierte GIFs) noch veröffentlichen sollte die existiert in Free Pascal noch nicht. (ist nun bereits passiert!!)
sMimeType = 'image/jpeg', 'image/png', 'image/gif', 'image/bmp' ( 'image/bmp' wird automatisch nach 'image/jpeg' konvertiert)
bCrop (nie verzerren, bei bCrop beschneiden auf LWidth, LHeight, sonst einpassen)
das skalierte Bild liegt dann im MemoryStream, kann man dann speichern, muss man aber nicht
Code: Alles auswählen
uses ..., ImgUtils;
var MemoryStream: TMemoryStream;
...
MemoryStream := TMemoryStream.Create;
scaleImageToStream(AFilename, sMimeType, MemoryStream, LWidth, LHeight, bCrop);
...
g**gle:) free pascal bilder skalieren --> ... etliche Treffer zu deiner Frage
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me
-
- Beiträge: 99
- Registriert: Do 23. Dez 2010, 19:10
- OS, Lazarus, FPC: Windows 10/11 32/64bit, L 3.2.0 32/64bit, FPC 3.2.2 32/64bit
Re: JPG Größe anpassen
Hallo,
sorry, das ich mich so spät melde.
Danke an theo und gocher, für die beiden Lösungen.
Ich glaube ich suche meistens verkehrt (Lazarus + Frage).
Ich habe vorerst die Lösung von theo verwendet.
Gruß
sorry, das ich mich so spät melde.
Danke an theo und gocher, für die beiden Lösungen.
Ich glaube ich suche meistens verkehrt (Lazarus + Frage).
Ich habe vorerst die Lösung von theo verwendet.
Gruß
-
- Beiträge: 351
- Registriert: Di 17. Feb 2009, 10:44
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Re: [gelöst] JPG Größe anpassen
Guten Abend,
ich würde gerne "scaleImageToStream" von gocher benutzen um jpg's vor dem Einfügen in ein pdf (mit fpPDF) zu verkleinern.
Ich habe mal was zum Versuchen gebastelt:
Es kommt die Meldung:
unit1.pas(53,49) Error: Incompatible type for arg no. 2: Got "AnsiString", expected "TFPCustomImageReaderClass"
Darf man bei scaleImageToStream als zweiten Parameter eine String-Variable (ImgJPG) übergeben?
Was muß ich als zweiten Parameter bei AddFromStream übergeben?
Vielen Dank für Eure Hilfe
ich würde gerne "scaleImageToStream" von gocher benutzen um jpg's vor dem Einfügen in ein pdf (mit fpPDF) zu verkleinern.
Ich habe mal was zum Versuchen gebastelt:
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
var D: TPDFDocument; S: TPDFSection; P: TPDFPage; I: Integer;
BildPfad, Bild: String; F: TFileStream; MemStream: TMemoryStream; ImgJPG: String;
begin
D:= TPDFDocument.Create(Nil);
if OpenPictureDialog1.Execute then begin
BildPfad:= OpenPictureDialog1.FileName;
Bild:= ExtractFileNameOnly(BildPfad);
Memo1.Lines.Add(BildPfad);
Memo1.Lines.Add(Bild);
D.StartDocument;
S:= D.Sections.AddSection;
P:= D.Pages.AddPage;
S.AddPage(P);
P.PaperType:= ptA4;
P.UnitOfMeasure:= uomMillimeters;
MemStream:= TMemoryStream.Create;
scaleImageToStream(BildPfad, ImgJPG, MemStream, 40, 20, false);
I:= D.Images.AddFromStream(MemStream, ImgJPG, false);
P.DrawImage(20,250,40,20,I);
F:= TFileStream.Create('ErstesTestPDF.pdf',fmCreate);
D.SaveToStream(F);
F.Free;
D.Free;
end;
end;
unit1.pas(53,49) Error: Incompatible type for arg no. 2: Got "AnsiString", expected "TFPCustomImageReaderClass"
Darf man bei scaleImageToStream als zweiten Parameter eine String-Variable (ImgJPG) übergeben?
Was muß ich als zweiten Parameter bei AddFromStream übergeben?
Vielen Dank für Eure Hilfe
Re: [gelöst] JPG Größe anpassen
Wahrscheinlich einen Reader wie hier beschrieben:ErnstVolker hat geschrieben: Di 17. Okt 2023, 22:34 Was muß ich als zweiten Parameter bei AddFromStream übergeben?
https://wiki.freepascal.org/fcl-image#R ... image_file
Vermutlich eine TFPReaderJPEG Instanz.
- Ally
- Beiträge: 278
- Registriert: Do 11. Jun 2009, 09:25
- OS, Lazarus, FPC: Win und Lazarus Stable release
- CPU-Target: x64
Re: [gelöst] JPG Größe anpassen
Anbei ein Beispielprogramm das die Unit rhsBitmapScale.pas verwendet und Bilder in guter Qualität skaliert.
- Dateianhänge
-
BitmapScale.zip
- (43.86 KiB) 102-mal heruntergeladen
-
- Beiträge: 351
- Registriert: Di 17. Feb 2009, 10:44
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Re: [gelöst] JPG Größe anpassen
Hallo Theo,
vielen Dank für den Tipp mit dem TFPReaderJPEG. Damit kann man AddFromStream ausführen. Das funktioniert sehr gut wenn man die Funktion "scaleImageToStream" weglässt und den Memorystream mit LoadFromFile "befüllt".
Wenn ich "scaleImageToStream" aufrufe kommt eine Debuggerausnahmen-Nachricht, dass mein Projekt die Exception-Klasse FPImageException ausgelöst hat. Die Meldung lautet: "Wrong image format".
Die zu ladende Datei ist ein JPEG mit der Endung jpg. Ich übergebe der Funktion eine Stringvariable MimeType:= 'image/jpeg';
Was mache ich hier falsch bzw. wie ist diese Funktion aufzurufen?
Vielen Dank
vielen Dank für den Tipp mit dem TFPReaderJPEG. Damit kann man AddFromStream ausführen. Das funktioniert sehr gut wenn man die Funktion "scaleImageToStream" weglässt und den Memorystream mit LoadFromFile "befüllt".
Wenn ich "scaleImageToStream" aufrufe kommt eine Debuggerausnahmen-Nachricht, dass mein Projekt die Exception-Klasse FPImageException ausgelöst hat. Die Meldung lautet: "Wrong image format".
Die zu ladende Datei ist ein JPEG mit der Endung jpg. Ich übergebe der Funktion eine Stringvariable MimeType:= 'image/jpeg';
Was mache ich hier falsch bzw. wie ist diese Funktion aufzurufen?
Vielen Dank
Re: [gelöst] JPG Größe anpassen
Keine Ahnung, der Code ist von Gocher.
Vielleicht ist dein Bild wirklich nicht in Ordnung. Hast du mal ein anderes JPEG probiert?
Sonst könntest du noch prüfen, was ein TFPCustomImage denn vorschlägt:
Vielleicht ist dein Bild wirklich nicht in Ordnung. Hast du mal ein anderes JPEG probiert?
Sonst könntest du noch prüfen, was ein TFPCustomImage denn vorschlägt:
Code: Alles auswählen
var
image: TFPCustomImage;
aRd: TFPCustomImageReaderClass;
.... etc. etc.
aRd := image.FindReaderFromStream(AFileStream);
ShowMessage(ARd.ClassName);
-
- Beiträge: 351
- Registriert: Di 17. Feb 2009, 10:44
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Re: [gelöst] JPG Größe anpassen
Hallo Theo,
das Bild/die Bilder sind in Ordnung. Kann sie ja auch mit IrfanView öffnen. Wenn ich das Spiel mit PNG's mache kommt auch die Meldung.
Dein Vorschlag aus dem Stream den Reader zu erkennen funktioniert. Da wird der "TFPReaderJPEG" ausgegeben.
Ohne die Skalierungsfunktion von gocher funktioniert es. Die hätte halt den Vorteil mal eben 120 Bilder zu verkleinern und im pdf zu platzieren.
Vielen Dank auch Dir, Ally! Mit Deinem Prgramm habe ich das "Testbild" in unterschiedliche Größen gebracht um zu sehen was bei hinreichender Auflösung eine geringer PDF-Größe akzeptabel erscheinen lässt.
Meine "Vorgabedatei" (mit Excel erzeugt) hat 18 Seiten mit 81 Bildern und dabei nur 3,2 MB. Da will ich hin.
Vielleicht liest ja gocher hier mit.
Viele Grüße und schönen Abend!
Volker
das Bild/die Bilder sind in Ordnung. Kann sie ja auch mit IrfanView öffnen. Wenn ich das Spiel mit PNG's mache kommt auch die Meldung.
Dein Vorschlag aus dem Stream den Reader zu erkennen funktioniert. Da wird der "TFPReaderJPEG" ausgegeben.
Ohne die Skalierungsfunktion von gocher funktioniert es. Die hätte halt den Vorteil mal eben 120 Bilder zu verkleinern und im pdf zu platzieren.
Vielen Dank auch Dir, Ally! Mit Deinem Prgramm habe ich das "Testbild" in unterschiedliche Größen gebracht um zu sehen was bei hinreichender Auflösung eine geringer PDF-Größe akzeptabel erscheinen lässt.
Meine "Vorgabedatei" (mit Excel erzeugt) hat 18 Seiten mit 81 Bildern und dabei nur 3,2 MB. Da will ich hin.
Vielleicht liest ja gocher hier mit.
Viele Grüße und schönen Abend!
Volker
Re: [gelöst] JPG Größe anpassen
Das ist das generelle Problem, wenn man mehrere Operationen am selben Stream ausführt:
In ScaleImageToStream gibt es keine Anweisung wie "MemoryStream.Position := 0", das heißt, der Stream steht beim Verlassen dieser Routine am Ende, hinter den Bilddaten. Wenn der nachfolgende Code nun den Stream nicht selbst wieder an den Anfang setzt, wird versucht, Daten hinter dem Stream-Ende zu verarbeiten, was nicht gut geht.
Daher nach ScaleImageToStream einfach "MemStream := 0" aufrufen.
Der folgende Code, basierend auf deinem, aber alles mit pdf entfernt, funktioniert einwandfrei:
Eine Beschleunigung für jpeg-Bilder ohne Thumbnail im EXIF wüsste ich noch: Nachdem die Größe des original-Bildes ermittelt worden ist, könnte man das Scale des FPReaderJPEG je nachdem auf jsHalf, jsQuarter oder jsEighth setzen und damit nur den entsprechenden Bruchteil der Bilddaten einlesen, was entsprechend schneller abläuft als das Einlesen des vollen Bildes (jsFullSize).
In ScaleImageToStream gibt es keine Anweisung wie "MemoryStream.Position := 0", das heißt, der Stream steht beim Verlassen dieser Routine am Ende, hinter den Bilddaten. Wenn der nachfolgende Code nun den Stream nicht selbst wieder an den Anfang setzt, wird versucht, Daten hinter dem Stream-Ende zu verarbeiten, was nicht gut geht.
Daher nach ScaleImageToStream einfach "MemStream := 0" aufrufen.
Der folgende Code, basierend auf deinem, aber alles mit pdf entfernt, funktioniert einwandfrei:
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
var
BildPfad, Bild: String;
MemStream: TMemoryStream;
ImgJPG: String;
begin
BildPfad := 'irgendein_jpeg_foto.jpg';
Bild:= ExtractFileNameOnly(BildPfad);
MemStream:= TMemoryStream.Create;
scaleImageToStream(BildPfad, ImgJPG, MemStream, 40, 20, false);
MemStream.Position := 0; // <---- Stream wieder an den Anfang setzen
Image1.Picture.LoadFromStream(MemStream);
MemStream.Position := 0; // <----- Stream wieder an den Anfang setzen
MemStream.SaveToFile(ChangeFileExt(Bild, '') + '-klein.jpg');
MemStream.Free;
end;
-
- Beiträge: 351
- Registriert: Di 17. Feb 2009, 10:44
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Re: [gelöst] JPG Größe anpassen
Hallo wp_xyz,
vielen lieben Dank! Die Position wieder auf "0" setzen war es wieso es bei mir nicht ging. Jetzt funzt es.
Noch einen schönen Abend!
vielen lieben Dank! Die Position wieder auf "0" setzen war es wieso es bei mir nicht ging. Jetzt funzt es.
Noch einen schönen Abend!