AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Problem bei Supersampling (Verkleinern einer TBitmap)
Thema durchsuchen
Ansicht
Themen-Optionen

Problem bei Supersampling (Verkleinern einer TBitmap)

Ein Thema von hellboyPS · begonnen am 28. Dez 2009 · letzter Beitrag vom 29. Dez 2009
Antwort Antwort
Seite 1 von 2  1 2      
hellboyPS

Registriert seit: 28. Dez 2009
5 Beiträge
 
#1

Problem bei Supersampling (Verkleinern einer TBitmap)

  Alt 28. Dez 2009, 14:07
Hallo liebe Foren-Mitglieder.
Ich programmiere seit einem halben mit Delphi und habe zu vielen mir aufgetauchten Fragen hier im Forum über die Forensuche oder über Google Antwort gefunden. Jedoch nicht zu diesem Problem.

Ich habe ein Programm geschrieben, dass die Mandelbrotmenge berechnet, was auch soweit sehr gut funktioniert. Jetzt habe ich mir überlegt das Bild schärfer zu machen und will Antialiasing (Supersampling) benutzen. Ich rendere also die Mandelbrotmenge vergrößert und muss sie danach möglichst intelligent auf die normale Größe bringen. Und das Problem liegt nun beim Verkleinern. Ich habe zuerst versucht Delphiinterne Funktionen wie StretchDraw() oder CopyRect() oder ähnliches, was aber immer zu einem schlechten Ergebnis führte (keine Verbesserung der Qualität!). Ich habe auch zu Testzwecken das größer gerenderte Bild als .bmp gespeichert und mit IrfanView geöffnet und dort wird es ja automatisch "verkleinert" zur Ansicht, da sieht es wunderbar aus.
Als Nächstes habe ich versucht einen eigenen Algorythmus zum Verkleinern geschrieben, welcher jedoch auch nicht wirklich die Qualität verbessert, einige Ungenauigkeiten und Fehler hat und außerdem recht viel Zeit beansprucht (4 bis 5 Sekunden, wobei die Delphiinternen Algorythmen ohne Zeitverzug arbeiten). Ich poste den Quellcode am Schluss (Vielleicht sind ja nur kleine Fehler drin =/ ).
Meine Frage ist also ob es etwas besonderes zu beachten gibt bei Supersampling und mein Ziel ist ein Algorythmus der das TBitmap qualitätsfördernd verkleinert.

Hier noch mein Quellcode zum Verkleinern meiner TBitmap:

Dabei ist Bitmap das groß gerenderte Bild (Höhe, Breite sind jeweils 400*Antialiase also beispielsweise bei 4x Antialiasing also 1600x1600) und die Variable Antialiase legt eben die Stärke vom Antialiasing fest (Also wie sehr das Bild vergrößert wurde)
Das Bild soll später die Maße 400x400 haben.
Das komplette Bild wird in Sektoren unterteilt und die Durchschnittsfarbe eines solchen Sektors wird ermittelt und damit das kleinere Bild erzeugt.

Delphi-Quellcode:
procedure TForm1.Antialiasing(Bitmap: TBitmap; Antialiase: Integer);
var secx,secy,x,y,sum:integer;
begin
 for secx := 0 to 399 do
 begin
  for secy := 0 to 399 do
  begin
   sum := 0;
   for x := 0 to Antialiase-1 do
   begin
    for y := 0 to Antialiase-1 do
    begin
     sum := sum+bitmap.canvas.Pixels[x+Antialiase*secx,y+Antialiase*secy];
    end;
   end;
   sum := round(sum/(Antialiase*Antialiase));
   bitmap.canvas.Pixels[secx,secy] := sum;
  end;
 end;
 bitmap.width := 400;
 bitmap.height := 400;
end;

Ich hoffe ihr könnt mir helfen

MfG hellboyPS
  Mit Zitat antworten Zitat
Benutzerbild von wicht
wicht

Registriert seit: 15. Jan 2006
Ort: Das schöne Enger nahe Bielefeld
809 Beiträge
 
Delphi XE Professional
 
#2

Re: Problem bei Supersampling (Verkleinern einer TBitmap)

  Alt 28. Dez 2009, 14:17
Hi,

deine eigene Funktion ist vermutlich so langsam, weil du Canvas.Pixels benutzt. ScanLine() geht da wesentlich schneller, danach solltest du vielleicht mal suchen.
Du könntest auch Graphics32 benuzen, ich habe mal etwas geschaut und es sieht so aus, als wäre da auch was zum AntiAliasing drin.

HTH
http://streamwriter.org

"I make hits. Not the public. I tell the DJ’s what to play. Understand?"
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#3

Re: Problem bei Supersampling (Verkleinern einer TBitmap)

  Alt 28. Dez 2009, 14:20
Wie erstellst du denn das Originalbild?
Womöglich läßt es sich dort schon so optimieren, daß es direkt in das Antialiase-Bild übertragen werden kann, also ohne eine vergößerte Vorstufe und anschließende Verkleinerung.
$2B or not $2B
  Mit Zitat antworten Zitat
hellboyPS

Registriert seit: 28. Dez 2009
5 Beiträge
 
#4

Re: Problem bei Supersampling (Verkleinern einer TBitmap)

  Alt 28. Dez 2009, 17:18
Hallo und danke für die Antworten.
Das mit ScanLine werde ich mal umsetzen, nichts desto trotz funktioniert die Prozedur jedoch nicht so wie man sich das vorstellt. Auch bei Graphics32 werd ich mich reinarbeiten, hört sich vielversprechend an. Die Mandelbrotmenge wird eben ganz simpel erzeugt und dann gefärbt. Der Quellcode hierzu sieht ungefähr so aus:

Delphi-Quellcode:
for x := 0 to bitmap.width do
begin
 for y := 0 to bitmap.height do
 begin
  re := (x/bitmap.width)*zoom+movex; // mit Startwerten zoom = 4, move = -2
  im := (y/bitmap.height)*zoom+movey;
  rez := 0;
  imz := 0;
  a := true;
  it := 0;
  for i := 0 to iterations do
  begin
   if a then
   begin
    rezold := rez;
    rez := rez*rez-imz*imz+re;
    imz := 2*rezold*imz+im;
    if rez*rez+imz*imz > 4 then
    begin
     a := false;
     it := i;
    end;
   end;
  end;
  col := (rez*rez+imz*imz)/4*colchangevar*10
  if a then
   bitmap.canvas.Pixels[x,y] := clBlack
  else
   bitmap.canvas.Pixels[x,y] := round(col+256*col+256*256+col);
 end;
end;
Das Verkleinern mit Delphiinternen Funktionen geht auch wirklich schnell nur führt es nicht zu gewünschten Ergebnis, ich bräuchte also etwas, das in dieser Form das Bild verkleinert.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#5

Re: Problem bei Supersampling (Verkleinern einer TBitmap)

  Alt 28. Dez 2009, 17:44
Du solltest jeden Farbkanal für sich behandeln, sonst können sich Farben durch quasi "TColor-interne Überläufe" gegenseitig beeinflussen. AA macht ein Bild übrigens nicht schärfer, ganz im Gegenteil! Es sieht meist besser aus, ja, aber schärfer, niemals. Die Geschwindigkeit ist ein Problem von TCanvas.Pixels, Alternativen wurden schon genannt. Insbesondere die GR32 liefert schon ein paar sehr ansehnliche Resampling-Filter mit, so dass du da nicht mal mehr selbst Hand anlegen müsstest.
Vom Grundsatz her ist dein Ansatz sonst okay, es ist quasi das Gegenstück zum linearen Filtering beim Vergrößern. Nur musst du wie gesagt die Farben einzeln vermitteln.
"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
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#6

Re: Problem bei Supersampling (Verkleinern einer TBitmap)

  Alt 28. Dez 2009, 17:46
Eine Möglichkeit wäre die folgende: Färbe das Bitmap zunächst komplett schwarz ein. Verdopple die Durchläufe der For-Schleife bei Höhe und Breite, teile "x" und "y" jedoch bei allen Zugriffen mit "/" durch zwei - bei dem Zugriff auf "Pixels[x, y]" musst du entsprechend runden, also "Pixels[round(x/2), round(y/2)]". Beim Setzen der Farbe multipilizierst du den Farbwert jeweils mit 1/4 und addierst diesen Wert auf die alte Pixelfarbe drauf.

Ungefähr so (ungetestet):
Delphi-Quellcode:
for x := 0 to bitmap.width * 2 do
begin
for y := 0 to bitmap.height * 2 do
begin
  re := (x/bitmap.width/2)*zoom+movex; // mit Startwerten zoom = 4, move = -2
  im := (y/bitmap.height/2)*zoom+movey;
  rez := 0;
  imz := 0;
  a := true;
  it := 0;
  for i := 0 to iterations do
  begin
   if a then
   begin
    rezold := rez;
    rez := rez*rez-imz*imz+re;
    imz := 2*rezold*imz+im;
    if rez*rez+imz*imz > 4 then
    begin
     a := false;
     it := i;
    end;
   end;
  end;
  col := (rez*rez+imz*imz)/4*colchangevar*10
  if not a then
  begin
   oldcolor := bitmap.canvas.Pixels[round(x/2),round(y/2)];
   newcolor := round(col+256*col+256*256+col);
   bitmap.canvas.Pixels[round(x/2),round(y/2)] := RGB(
     rounc(GetRValue(oldcolor) + GetRValue(newcolor) * 0.25),
     rounc(GetGValue(oldcolor) + GetGValue(newcolor) * 0.25),
     rounc(GetBValue(oldcolor) + GetBValue(newcolor) * 0.25));
  end;
end;
end;
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein
  Mit Zitat antworten Zitat
hellboyPS

Registriert seit: 28. Dez 2009
5 Beiträge
 
#7

Re: Problem bei Supersampling (Verkleinern einer TBitmap)

  Alt 28. Dez 2009, 23:02
Hab den Post von igel457 mal umgesetzt.
Folgendes Ergebnis:

Vorher: http://img37.imageshack.us/i/vorher.png/
Nachher: http://img24.imageshack.us/i/nachhero.png/

Leider auch nicht das passende Ergebnis. Ich werde mich mit der GR32 Library mal auseinandersetzen.

Danke für die bisherigen Posts schon mal.
  Mit Zitat antworten Zitat
Benutzerbild von patti
patti

Registriert seit: 20. Okt 2004
Ort: Mittelfranken
665 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: Problem bei Supersampling (Verkleinern einer TBitmap)

  Alt 28. Dez 2009, 23:28
Verstehe ich das richtig? Du suchst nach einer Möglichkeit, ein Bild zu verkleinern - und das in einer möglichst guten Qualität? Hast du schonmal StretchBlt mit dem blt-Modus HALFTONE ausprobiert? Denn wenn ich dich richtig verstanden habe, willst du ja ein großes Bild "runterrechnen" und mit Hilfe von StretchBlt solltest du zumindest bessere Ergebnisse als mit StretchDraw erzielen können.

Kann sein, dass ich deine Frage völlig falsch verstanden habe - wenn dem so sein sollte, dann kannst du meine Antwort getrost ignorieren

mfg
Patrick Kreutzer
[Informatik-Student im 4. Semester]
http://www.patti-k.de/
  Mit Zitat antworten Zitat
hellboyPS

Registriert seit: 28. Dez 2009
5 Beiträge
 
#9

Re: Problem bei Supersampling (Verkleinern einer TBitmap)

  Alt 28. Dez 2009, 23:51
Nein die Frage wurde schon richtig verstanden, jedoch habe ich einige Methoden ausprobiert das Bild zu verkleinern und keiner hat mir vernünftige Ergebnisse gebracht. Es ist auch möglich, dass es hierbei nicht um eine möglichst gute Qualität sondern um eine bestimmte, passende Methode geht. Eben zum Supersampling bei der Mandelbrotmenge. Ich weiß es nicht.
StretchBlt habe ich mit diesem Modus noch nicht probiert. Werde ich gleich tun!
  Mit Zitat antworten Zitat
helgew

Registriert seit: 30. Jul 2008
125 Beiträge
 
#10

Re: Problem bei Supersampling (Verkleinern einer TBitmap)

  Alt 28. Dez 2009, 23:58
He hellboyPS,


was mir gerade so in den Sinn kam: du kannst dir doch, nachdem du über die Performancesachen durch Scanline hinaus bist, etwas Spaß genehmigen und einen 50%-Skalierer implementieren, der immer 2x2 Pixel zu 1 Pixel packt. Wenn du nur eines nimmst, hast du die Funktionsweise von StretchBlt nachgebaut, wenn du über alle vier Pixel mittelst, wird das Bild an den Kanten sehr weich, was du wohl auch nicht willst. Neben dem arithmetischen gibt es jedoch auch ein geometrisches Mittel, ein quadratisches Mittel, und die n-Norm (n-te Wurzel der Summe aus den vier Pixelfarbwerten hoch n). Für große n geht dieses Mittel gegen max(r1, r2, r3, r4).
Ebenso könntest du auch etwas content-awareness einbauen, sprich die Wahl "welches der 4 Pixel nehme ich als representativ" statistisch aus der Umgebung der 8 angrenzenden Blöcke ableiten. Damit kann man ebenfalls aliasing unterdrücken. Der Phantasie sind da nur sehr irdische Grenzen gesetzt
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 18:41 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