AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Graphics32: trotz Runterskalierung größere Datei. Was nun???
Thema durchsuchen
Ansicht
Themen-Optionen

Graphics32: trotz Runterskalierung größere Datei. Was nun???

Ein Thema von changlee · begonnen am 21. Aug 2008 · letzter Beitrag vom 23. Aug 2008
Antwort Antwort
changlee
(Gast)

n/a Beiträge
 
#1

Graphics32: trotz Runterskalierung größere Datei. Was nun???

  Alt 21. Aug 2008, 17:06
Hallo,

ich Ich lade einen Screenshot in ein normales TBitmap und erhalte nach dem Abspeichern als *.bmp eine Dateigröße von 3 MB.
Wandele ich das TBitmap in ein TPNGObject (mit der freien Bibliothek PNGImage) um, erhalte ich eine Dateigröße von 313 kB.

Das ist mir noch zu groß. Also ging ich noch einen anderen Weg. Hier im Forum fand ich Empfehlungen zu Graphics32 für Skalirung mit sehr wenig Qualitätsverlust.

Ich lade jetzt also den Screenshot gleich in ein TBitmap32 und skaliere das mit dem Faktor 0.8.
Anschließend lade ich das TBitmap32 in ein TBitmap um es schließlich wieder zu png konvertieren zu können. Die png-Datei hat aber nun 354 kB. Also mehr als im unskalierten Fall.

Weiß jemand, woran es liegt und wie ich die Dateigrößen besser reduzieren kann (ohne den drastischen Qualitätsverlust von Stretchdraw zu erhalten)?

Hier ist der Quellcode der beiden Funktionen:
Delphi-Quellcode:

procedure CaptureScreen;
var
  DC: HDC;
  mypng:TPNGObject;
  Bitmap:TBitmap;
begin
  // Capture the Desktop screen
  DC := GetDC(GetDesktopWindow);
  Bitmap := TBitmap.Create;
  mypng:=TPNGOBJect.create;
  try
    Bitmap.Width := GetDeviceCaps(DC, HORZRES);
    Bitmap.Height := GetDeviceCaps(DC, VERTRES);
    BitBlt(Bitmap.Canvas.Handle,0,0,Bitmap.Width,Bitmap.Height,DC,0,0,SRCCOPY);
    Bitmap.SaveToFile('normalBitmap.bmp');
    mypng.Assign(Bitmap);
    mypng.SaveToFile('normalPng.png');
  finally
    ReleaseDC(GetDesktopWindow, DC);
    Bitmap.Free;
    mypng.Free;
  end;
end;


procedure CaptureScreen32;
var
  DC: HDC;
  mypng:TPNGObject;
  Bitmap,b,SmallBitmap:TBitmap32;
  bmap:TBitmap;
  resmplr: TKernelResampler;
  scalefactor : double;
  x,y:integer;
begin
  // Capture the Desktop screen
  DC := GetDC(GetDesktopWindow);
  Bitmap := TBitmap32.Create;
  try
    Bitmap.Width := GetDeviceCaps(DC, HORZRES);
    Bitmap.Height := GetDeviceCaps(DC, VERTRES);
    BitBlt(Bitmap.Canvas.Handle,0,0,Bitmap.Width,Bitmap.Height,DC,0,0,SRCCOPY);
  finally
    ReleaseDC(GetDesktopWindow, DC);
  end;
  scalefactor := 0.8;
  x := round(Bitmap.Width*scalefactor);
  y := round(Bitmap.Height*scalefactor);
  b := TBitmap32.Create;
  SmallBitmap := TBitmap32.Create;
  bmap:=TBitmap.Create;
  mypng:=TPNGOBJect.create;
  try
    resmplr := TKernelResampler.Create(b);
    resmplr.Kernel := TLanczosKernel.Create;
    SmallBitmap.SetSize(x,y);
    resmplr.Resample(SmallBitmap,rect(0,0,x,y),rect(0,0,x,y),Bitmap,rect(0,0,Bitmap.Width,Bitmap.Height),dmOpaque,nil);

    SmallBitmap.SaveToFile('reduced.bmp');

    bmap.Width := smallbitmap.Width;
    bmap.Height := smallbitmap.Height;
    bmap.Assign(Smallbitmap);

    mypng.Assign(bmap);
    mypng.SaveToFile('reduced.png');
  finally
    b.free;
    Bitmap.free;
    SmallBitmap.free;
    bmap.free;
    mypng.free;
  end;
end;
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#2

Re: Graphics32: trotz Runterskalierung größere Datei. Was nu

  Alt 21. Aug 2008, 17:25
Hallo,

ich vermute, dass das geladene PNG eine Farbtiefe von 24 Bit hat, du durch das speichern des TBitmap32 einen Alphachannel, also sprich ca 1/4 mehr Daten, hinzugewinnst.

Versuche, die Farbtiefe des TBitmap, das du an das PNG übergibst, vorher mit Bitmap.PixelFormat := pf24Bit auf 24 Bit herabzusetzen.

//Edit: Vergessen zu sagen: Durch die Interpolation beim herunterskalieren hast du im herunterskalierten Bild natürlich auch noch mehr Farbabstufungen.
  Mit Zitat antworten Zitat
changlee
(Gast)

n/a Beiträge
 
#3

Re: Graphics32: trotz Runterskalierung größere Datei. Was nu

  Alt 21. Aug 2008, 17:40
Hallo Namenlozer,

danke für den Tip. Mit pf24bit ging es zwar nicht, mit pf16bit hatte ich völlig falsche Farben aber mit pf8bit geht es. Bilder sehen dann zwar nicht mehr so schön aus, aber für meine Zwecke (hauptsächlich Schrift) reicht es aus.

Viele Grüße,
Stefan.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: Graphics32: trotz Runterskalierung größere Datei. Was nu

  Alt 22. Aug 2008, 02:55
Und hier der wahre Grund für diesen Umstand (TBitmap kennt keine Aplhakanäle, es wäre wenn dann Einstellungssache an der PNG-Lib, aber das ist es hier auch nicht):
PNG nutzt eine verlustfreie Kompression, und wird insbesondere durch das Vorhandensein von einfarbigen Flächen in seiner Kompressionsleistung begünstigt. Benutzt man nun zum Verkleinern eines Bildes einen interpolierenden Resamplefilter "bluten" vormals harte Kanten ein klein wenig in diese Flächen hinein, wodurch der "weniger gut zu komprimierende" Flächenanteil im Bild wächst. Gleich große PNG Bilder erzeugen eben auch nicht immer gleich große PNG Dateien, sondern wie bei nahezu allen Kompressionsverfahren ist Bildinhalt mindestens so wichtig wie die Ausmaße.

Paradoxerweise würde JPEG ein auf diese Weise verkleinertes Bild noch kleiner als erwartet bekommen müssen, da dort ein verlustbehaftetes Verfahren zum Einsatz kommt, bei dem grad "weiche" (niederfrequente) Kanten zu einer höheren Kompression führen, so dass o.s. Aussage keinesfalls auf alle komprimierende Verfahren verallgemeinert werden darf. (Das aber nur, damit sich nachher keiner wundert )


Wie kannst du dem Problem bei dir beikommen? Als erstes würde ich schauen was ich da machen will. Bisher riecht das nach einem Remote-Desktop, und du willst Screenshots via Netzwerk/Internet zu einem Client schicken, weshalb diese klein sein sollten. Da sticht einem schon ins Auge, dass sich grad bei der "normalen" Arbeit unter Windows (Office, Adminkrams, etc.) sehr sehr selten in kuzen Abständen das gesamte Bild verändert. Also würde es sich massiv lohnen immer nur je die veränderten Bildbereiche zu schicken, nachdem man nur als erstes Bild einen vollen Screenshot als Basis gesendet hat.
Wie bekomme ich die geänderten von den gleich gebliebenen Bereichen getrennt? Du brauchst die Bilddifferenz, welche nichts weiter ist, als das Resultat aus der Differenz aller Farbwerte aller Pixel zweier aufeinanderfolgender Bilder. Überall wo sich nichts geändert hat hast du darin schwarz. Folglich kannst du alle Pixel in dem zu schickenden Bild einfarbig machen, wodurch du dass was bisher dein Problem ist, nun zur Problemlösung nutzt: Große einfarbige sehr gut komprimierbare Bereiche!
Nun kann es aber sein, dass schwarz auch so auftaucht, weshalb es sich lohnt zusätzlich zu dem via Differenzbild maskiertem und per PNG komprimierten Bild eine 1-Bit-Maske zu schicken, die angibt welche Bereiche im grad geschickten Bild als "neu" zu sehen sind. (Alternativ kann man schwarz auch durch rgb(1,1,1) ersetzen und ganz schwarz als Maske interpretieren, aber das gefällt mir nicht so recht.)
PNG ist da auch schon eine exzellente Wahl, da du diese Maske gleich in das selbe PNG verpacken kannst wie das zugehörige Bitmap, wodurch diese ebenfalls durch die prima Kompression verkleinert wird.


So, jetzt hab ich mir die Finger fusselig geschrieben, und du wirst sicherlich als nächstes antworten, dass du sowas überhaupt nicht vor hattest
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#5

Re: Graphics32: trotz Runterskalierung größere Datei. Was nu

  Alt 22. Aug 2008, 14:39
Diese Vermutung hatte ich ja auch, aber irgendwie ist es doch paradox, dass das Bild herunterskaliert mehr Platz beanspruchen soll
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#6

Re: Graphics32: trotz Runterskalierung größere Datei. Was nu

  Alt 22. Aug 2008, 19:08
Ist es nicht, nö. Lies den ersten Abschnitt meines vorigen Postings einfach nochmal

Evtl. deutlicher: Ich kann dir ein 1920x1200 dass 2 einfarbige Quader auf einfarbigem Grund beinhaltet auf eine Hand voll Kilobyte verlustfrei komprimieren, ein 640x480 Bild mit Farbrauschen wird bei weitem nicht so klein werden können. Bildausmaße sind nur ein Teil der enthaltenen Information, der bei Kompression relevante Teil ist jedoch viel mehr der Bildinhalt. Durch das Herunterskalieren mit Filtern veränderst du eben den Informationsgehalt im Bild, wobei sich diese Veränderung bei unterschiedlichen Kompressionsansätzen auch mal gegensätzlich auswirkt.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#7

Re: Graphics32: trotz Runterskalierung größere Datei. Was nu

  Alt 22. Aug 2008, 20:34
Ich brauch deinen Post nicht nochmal zu lesen, wie gesagt, hatte ich die Vermutung selbst schon.

Das Paradoxe an der Sache ist ja, dass das Bild mehr Informationen enthält, obwohl weniger davon relevant sind.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#8

Re: Graphics32: trotz Runterskalierung größere Datei. Was nu

  Alt 23. Aug 2008, 00:44
Sobald Relevanz ins Spiel kommt, sind wir ja zwangsläufig schon bei verlustbehafteten Verfahren. Bei JPEG z.B. drückt sich diese Relevanzabschätzung in der Quantisierungsmatrix aus z.B., während ein verlustfreies Verfahren wie PNG nicht nach Relevanz fragen darf. Kein Verlust = alles ist gleichermaßen relevant.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:43 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz