Autor |
Beitrag |
jackie05
Beiträge: 357
|
Verfasst: Fr 14.06.13 22:07
Hallo,
ich habe ein Problem beim verkleinern von sehr große JPEG Dateien z.B. von (3872x2592) auf (272x272) Pixel, alles klappt zwar, nur ist es dann stark verpixelt, wenn ich es verkleiner.
Hier ist mal der Code:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| function ResizeJPEG(jpeg: TJpegImage; width, height: integer): TJpegImage; var bmp:TBitmap; begin try bmp:=TBitmap.Create; try bmp.width:=width; bmp.height:=height;
bmp.canvas.StretchDraw(Rect(0,0,bmp.width,bmp.height),jpeg); jpeg.assign(bmp); finally bmp.free; end; jpeg.CompressionQuality := 100; jpeg.Compress; result := jpeg; finally
end; end;
procedure SavePNG(name: string; width: integer; height: integer); var JPG:TJPEGImage; BMP:TBitmap; PNG:TPNGImage; begin JPG:= TJPEGImage.Create; BMP:= TBitmap.Create; PNG:= TPngImage.Create; JPG.LoadFromFile('img/'+name); JPG := ResizeJPEG(JPG, width, height); BMP.Assign(JPG); PNG.Assign(BMP); PNG.SaveToFile(ChangeFileExt('img/'+name,'.png')); end; |
Wie kann ich TJpegImage so einstellen, das es noch weich gezeichnet wird?
Weil das Bild stark verpixelt ist, nachdem ich es verkleinert habe.
Ich bedanke mich schonmal im Voraus.
MfG
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 14.06.13 22:17
Dafür kannst du nach smooth resize suchen:
www.swissdelphicente...showcode.php?id=1896
|
|
jackie05
Beiträge: 357
|
Verfasst: Fr 14.06.13 23:21
Ich danke Dir.
Das klappt irgendwie nicht.
Kann ich nicht irgendwie mein Code ausbessern um eine gute Qualität zu erzielen?
MfG
|
|
MeierZwoo
Beiträge: 94
Erhaltene Danke: 11
Win 7, DOS5
Delphi 2007 Architect, BP7/TP5, LISP, PS
|
Verfasst: Sa 15.06.13 02:39
Grundsätzlich sollte es beim VERKLEINERN keine Artefakte geben - das passiert normal nur beim vergrößern.
Was ich nicht ganz verstehe, ist, weshalb Du erst auf eine BitMap zeichnest, dann aber der JPG die BitMap zuweist und dann die BitMap "wegwirfst" statt mit der BitMap weiter zu arbeiten. Dein Verpixeln entsteht wohl gerade an dieser Stelle, der Zuweisung einer BitMap an eine JPG. Dem Programm und auch dem Speicher und auch der Ausgabe ist es völlig egal, da beim Zeichnen eh eine BitMap gezeichnet wird, also die JPG wieder in RAW-Daten umgerechnet wird - denn eine JPG, GIF ... kann der Bildschirm (oder ein anderes pixelorientiertes Ausgabegerät) eh nicht darstellen.
|
|
jackie05
Beiträge: 357
|
Verfasst: Sa 15.06.13 20:07
Ich danke Dir.
Ich möchte ja eine JPEG Datei laden und diese verkleinern, anschließend möchte ich es dann als PNG speichern.
Wenn ich Bitmap entferne und nur mit JPEG und PNG arbeite:
Delphi-Quelltext 1: 2:
| PNG.Assign(JPG); PNG.SaveToFile(ChangeFileExt('img/'+name,'.png')); |
dann bekomme ich folgende fehlermeldung:
Delphi-Quelltext 1:
| TJPEGImage kann nicht zu TPNGImage zugewiesen werden. |
Wie könnte ich das anders lösen?
MfG
|
|
MeierZwoo
Beiträge: 94
Erhaltene Danke: 11
Win 7, DOS5
Delphi 2007 Architect, BP7/TP5, LISP, PS
|
Verfasst: Sa 15.06.13 20:19
Nochmal: Wieso entfernst Du denn die BitMap? Und wieso speicherst Du nicht die BitMap als PNG?
Es ist doch vollkommen egal, was für einen Grafiktyp Du lädst und als was Du speichern willst, das interne "Arbeits-Rohformat" (RAW) ist immer BitMap - von diesem Rohformat kann alles andere hergestellt werden. (Alternativ auch TIFF, weil TIFF nur ein encodetes Rohformat ist, welches durch decoden direkt wieder ins ursprüngliche Rohformat zurückgeführt werden kann und deshalb z.B. für Datenübertragung (z.B. zum Drucker) intern benutzt wird.)
Nachtrag:
Was ich auch nicht ganz verstehe, wieso man JPG läd um sie als PNG zu speichern.
a) Wenn man skalierbare Grafiken haben möchte. speichert man GLEICH als PNG (oder TIFF) und nicht als JPG - JPG ist als ENDformat gedacht und nicht zum weiteren skalieren, im Gegensatz zu PNG, welches zum skalieren gedacht ist.
b) macht man das nicht mit einem eigenen Tool, sondern benutzt fertige Tools, z.B. Irfan, die auch Batchbetrieb anbieten.
|
|
jackie05
Beiträge: 357
|
Verfasst: Sa 15.06.13 20:30
Danke Dir.
Das habe ich auch versucht, aber trotzdem ist das Bild dann verpixelt, wie es im anhang zusehen ist.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| bmp.width:=width; bmp.height:=height;
bmp.canvas.StretchDraw(Rect(0,0,bmp.width,bmp.height),jpeg); png.Assign(bmp); png.SaveToFile('test.png'); |
Woran könnte es liegen?
MfG
Einloggen, um Attachments anzusehen!
|
|
MeierZwoo
Beiträge: 94
Erhaltene Danke: 11
Win 7, DOS5
Delphi 2007 Architect, BP7/TP5, LISP, PS
|
Verfasst: Sa 15.06.13 21:06
LOL, also im Anhang kann man garnichts erkennen, selbst mit Lupe nicht - und da der Ursprung nicht bekannt ist, kann man auch nichts über verpixelt oder so aussagen.
Im allgemeinen wird überall berichtet, daß StretchDraw wohl allgemein eine Sauqualität abliefert. Ich selbst kann dazu nichts sagen, da ich es vermeide und Images VORHER auf Ausgabegröße anpasse bzw. wenn, nur Strich-Images damit skaliere (keine Graustufen, keine Farbe ..).
Aber eine Suche nach stretchdraw in den einschlägigen Delphi-Foren (auch hier) liefert genug Ergebnisse im Bezug auf die miese Qualität von stretchdraw. In den meisten Fällen wird auf Routinen von
graphics32.org/wiki//Main/HomePage
verwiesen.
|
|
WasWeißDennIch
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Sa 15.06.13 21:53
Wenn man statt TCanvas.StretchDraw StretchBlt verwendet und vorher ggf. noch mit SetStretchBltMode den Modus umschaltet, bekommt man auch oft schon recht brauchbare Ergebnisse. Beispielcode findet sich z.B. hier: www.delphipraxis.net/1095307-post20.html
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 15.06.13 22:14
Folgender Code funktioniert sehr gut:
www.delphidabbler.com/tips/99
Note: to test this code you need to drop a TButton and a TOpenPictureDialog on a form and add the JPEG unit to the uses statement.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, JPEG, StdCtrls, ExtDlgs;
type TForm1 = class(TForm) OpenPictureDialog1: TOpenPictureDialog; Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var bmp: TBitmap; jpg: TJpegImage; scale: Double; begin if OpenPictureDialog1.execute then begin jpg := TJpegImage.Create; try jpg.Loadfromfile(OpenPictureDialog1.filename); if jpg.Height > jpg.Width then scale := 500 / jpg.Height else scale := 500 / jpg.Width; bmp := TBitmap.Create; try bmp.Width := Round(jpg.Width * scale); bmp.Height:= Round(jpg.Height * scale); bmp.Canvas.StretchDraw(bmp.Canvas.Cliprect, jpg); Self.Canvas.Draw(100, 10, bmp); jpg.Assign(bmp); jpg.SaveToFile( ChangeFileext(OpenPictureDialog1.filename, '_thumb.JPG')); finally bmp.free; end; finally jpg.free; end; end; end;
end. |
Zuletzt bearbeitet von hathor am Do 24.07.14 07:45, insgesamt 1-mal bearbeitet
|
|
bummi
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Sa 15.06.13 22:26
Wenn GDI+ eine Option für Dich ist, hier gibt es diverse Filter für das Scalieren.
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 16.06.13 08:16
|
|
|