[Mac] Quiltator

  • [Mac] Quiltator

    Ich wollte hier mal mein halbfertiges Hobby-Projekt vorstellen, der "Quiltator". Ich finde es schon ganz nützlich, aber da ist
    wohl noch einiges zu tun. Nichtsdetotrozt bin ich grad so freudig, dass ich es schonmal "rumzeigen" will.

    Worum es geht:
    Wenn man aus Photos sich wiederholende Texturen erstellen will, bekommt man immer sehr schnell sichtbare Ränder. Die kann man entweder mit Photoshop und dem Stempel händisch retuschieren, oder jetzt den Quiltator probieren :) Ziel ist es also, aus einem gegebenen Bildausschnitt eine Textur zu erstellen, die sich ohne sichtbare Übergänge wiederholt und sich damit gut als Textur für 3D Objekte oder als Hintergrund von Webseiten verwenden lässt.

    Dazu einfach ein Bild öffnen, einen Bereich auswählen und an den Schiebereglern einen "Overlap" einstellen. Dieser Overlap definiert in etwa den Bereich, der überlagert wird um Ränder zu "verstecken".
    Wenn das Resultat hässlich ist, einfach am Overlap spielen, bis es besser ist. Da gilt es meist eine optimale Einstellung zu finden...

    Technische Details:
    Das ist jetzt mein erstes Cocoa Projekt, wo ich versucht habe, komplett auf Xcode zu verzichten. Alles wird in CMake gebaut, was auch ganz gut klappt. Ich finde das angenehmer, weil ich so nur Konfigurationsdateien habe, die nur das wesentliche enthalten. Ausserdem finde ich mich so besser zurecht, ich weiss wo ich was anpassen muss und ich muss nicht an fünf verschiedenen Stellen irgendwelche Einstellungen suchen. Ausserdem habe ich das Gefühl, dass CMake das mit dem Dependency-Tracking etwas besser hinbekommt.

    Das Projekt ist dann aufgeteilt in die Cocoa-GUI Anwendung, und eine static library in C++, welche die Bildberechnungen durchführt. Die Lib ist so aufgebaut, dass ich nur ein CGImageRef und die Parameter reinstecke und ich nach einer Weile ein neues CGImageRef zurückbekomme.

    Für die GUI hab ich eigene Views gebaut, die die Darstellung übernehmen und die Auswahl erlauben. Es geht zwar noch nicht soviel wie mit IKImageView, dafür war es aber einfach, das Auswahlrechteck so zu zeichnen, dass man den Overlap sieht. Ein Fullscreen-Modus, der das Ergebnis gekachelt darstellt war dann auch recht einfach umzusetzen. Mich hat ja an IKImageView genervt, dass ich keine ordentlichen ScrollBars bekomme, das war aber auch hier nicht ganz einfach und ich musste auf eine eigene NSClipView Klasse zurückgreifen (Code habe ich von hier angepasst, damit alles etwas schöner und mit Schatten dargestellt wird). Dargestellt werden immer nur CGImageRefs, das ist glaube ich auch ganz gut so. Ich bin gerade erst am entdecken, was man alles schönes mit CoreGraphic (Quartz...) anstellen kann. Das werde ich bestimmt noch etwas ausbauen.

    Grundidee für den Algorithmus habe ich von diesem etwas älteren Siggraph Paper. Um so kachelnde Texturen zu erzeugen, wie ich das will, hat sich das ganze aber noch um einiges vereinfacht. Aber ein paar Dinge muss ich noch verbessern, manchmal sieht man z.B. die Ränder immer noch sehr deutlich, da könnte man mit etwas Blending rangehen.

    Was fehlt noch?
    Naja, ein wenig "Polish" wie Icons etc. Auch hab ich bestimmt noch Leaks und nicht alle potentiellen Dummheiten des Nutzers abgefangen. Ganz wichtig ist noch eine Zoom-Funktion, denke ich. Das sollte aber an sich recht einfach gehen, muss ja nur das CGImage größer zeichnen. Naja, und der eigentlich Algorithmus könnte noch etwas optimiert werden.

    Ausprobieren?
    Ein Debug Build für Intel x86 gibt es hier: paste.ioctl.eu/Quiltator-0.1.zip
    (ca 400kB). Ich nehme an, dass es 10.6-only ist, habe das aber noch nicht genau geprüft.

    Feedback?
    Ich finde es ja jetzt schon ganz toll, vielleicht ist es dem einen oder anderem ja auch nützlich, dann würde ich mich natürlich freuen. Verbesserungsvorschläge oder Nachfragen zu Details auch gerne :) Vielleicht probiere ich mit dem ganzen ja eines Tages mal den Mac AppStore. Vielleicht lässt sich da ja noch was rausschlagen ;) Aber bevor ich es jetzt abhake als "Funktioniert soweit" und es in den Tiefen meiner Platte verschwindet, will ich es lieber hier teilen.
    C++
  • Sehr schick! Schön zu sehen, dass es Leute gibt, die mehr als Trivialitäten mit Pixeln anstellen.

    Eine Sache hat mich vom Workflow verwirrt: Beim Öffnen verhält sich das Programm so, als ob ein Dokument ein geöffnetes Quellbild ist. Beim Schließen wird dann aber bei jedem Rendering gefragt, ob ich es speichern möchte, also als ob jedes gerenderte Bild ein Dokument wäre. Wie gesagt, hat mich verwirrt, ich habe mich gefragt, was denn nun von beiden Fenstern das Dokument ist.

    Erweiterungsideen: Ein grober Live-Preview wäre gut. Das Graph-Cutting-Zeug ist wahrscheinlich nicht Echtzeitfähig, aber die Tiles mit einfachen Überblendungen im Überlappungsbereich müssten gehen - vielleicht kann man so schneller gute Parameter finden. Und: Ein drehbarer Kachelausschnitt wäre bestimmt fein.

    App Store - warum nicht? Hätte ich für Texturen ab und zu schon gebrauchen können (dann hätte ich es unter dem Namen allerdings wahrscheinlich nicht gefunden...).
    Multigrad - 360°-Produktfotografie für den Mac
  • zerm schrieb:

    Chris schrieb:

    Kannst du die Schieberegler nicht im Fullscreen anzeigen?

    Hmm, und dann quasi Live-Neuberechnung? Müsste ich mal sehen. Wenn ich wirklich grosse Bilder und viel Overlap nehme dauerst ja schon eine ganze Weile...Aber sicherlich hilfreich. Mal schauen :)

    Ja, so habe ich es gedacht. Reicht es nicht den Overlap neu zu berechnen? Hab das Sigraph Paper nur kurz überflogen.

    Den Ausschnitt sollte man verschieben können.


    Chris
    Man macht einfach solange irgendwelche Dinge, bis man tot ist.
    Und dann bekommen die anderen Kuchen.
  • Chris schrieb:

    Ja, so habe ich es gedacht. Reicht es nicht den Overlap neu zu berechnen? Hab das Sigraph Paper nur kurz überflogen.

    Hum, nein. Der Ausschnitt definiert ja gerade über welche Pixel der Cut gesucht wird. Ändert man den, muss alles neuberechnet werden. Würde ich den Cut nicht neuberechnen, würde es ja nicht mehr so schön passen und man hätte nichts gekonnt :)
    C++
  • Könntest ne Menge Abnehmer dafür kriegen.
    Luxology hatte sowas mal als Photoshop-Plugin (imageSynth) hat es aber leider wieder verworfen, da es anscheinend buggy war.
  • mattik schrieb:

    Eine Sache hat mich vom Workflow verwirrt: Beim Öffnen verhält sich das Programm so, als ob ein Dokument ein geöffnetes Quellbild ist. Beim Schließen wird dann aber bei jedem Rendering gefragt, ob ich es speichern möchte, also als ob jedes gerenderte Bild ein Dokument wäre. Wie gesagt, hat mich verwirrt, ich habe mich gefragt, was denn nun von beiden Fenstern das Dokument ist.

    Das war eigentlich Absicht ;) Also die Ergebnisse sind sogar in der Tat jeweils ein neues Dokument. Ich erzeuge ja etwas neues, und wenn man 5 Minuten gewartet hat, ist es ärgerlich, wenn man das Fenster versehentlich zu macht, so mein Gedankengang. Ausserdem möchte man vielleicht mehrere Resultate erzeugen, ausprobieren und alle abspeichern. Aber vielleicht kann ich einfach die Nachfrage, ob gespeichert werden soll, herausnehmen, da gabs glaub ich nen delegate für sowas :)

    mattik schrieb:

    Erweiterungsideen: Ein grober Live-Preview wäre gut. Das Graph-Cutting-Zeug ist wahrscheinlich nicht Echtzeitfähig, aber die Tiles mit einfachen Überblendungen im Überlappungsbereich müssten gehen - vielleicht kann man so schneller gute Parameter finden. Und: Ein drehbarer Kachelausschnitt wäre bestimmt fein.

    Vorschau, ja, das wäre nützlich. Eventuell kann man den Cut auch auf einer runtergesampelten Version machen. Wenn die Überlappung nicht so gross ist, läuft das ja ganz flott.
    Rotation hatte ich auch schon geplant, bin da am überlegen, ob es vielleicht am elegantesten wäre, wenn man das Auswahl-Rect einfach drehen könnte. Ist wahrscheinlich einfach zu bedienen, als das ganze Bild immer zu drehen..

    wolf_10de schrieb:

    Könntest ne Menge Abnehmer dafür kriegen.
    Luxology hatte sowas mal als Photoshop-Plugin (imageSynth) hat es aber leider wieder verworfen, da es anscheinend buggy war.

    Ich bin mir recht sicher, dass Photoshop auch mal so eine Funktion von Haus aus dabei hatte. Aber entweder, ich finde die nicht mehr, oder die ist irgendwo versteckt. Photoshop kann ja auch HDRs mergen und Panoramas erstellen, wenn man die Option findet. Und für die Panoramas sieht es so aus, als würden sie auch Graphcuts verwenden ;)
    Ich weiss halt nicht, wie "ungeduldig" da der normale Nutzer ist, und nicht doch lieber dann alles mit dem Stempel macht...

    Mich wundert aber auch immer, dass so wenig von den tollen "Research" Ansätzen tatsächlich ganz am "Endkunden" ankommen. Vielleicht liegt das teilweise an Patenten. Oder der Markt ist so schlecht, manche Dinge schaffen es ja nur in die extrem teuren Spezialanwendungen. Noch so ein Beispiel ist das GradientPaint:
    graphics.cs.cmu.edu/projects/gradient-paint/
    Da gibt es sogar eine fertige OSX Binary (und Sources)...Sowas als "marktreife" Anwendung wäre extrem fetzig. Oder hab ich da was übersehen? Photoshop hat jetzt ja immerhin das Content-Aware Resize und Content-Aware Fill :D
    C++
  • Tolle Arbeit!
    Ohne jetzt rumzunörgeln, schau Dir mal CoreAnimation an. Damit bekommst Du die Darstellung Deines Bildes quasi umsonst (inkl. Schatten, zoom-Funktionalität etc.). Auch das Auswahlband könntest Du als Layer umsetzen, ist dann alles animierbar, hardwarebeschleunigt und ganz wenig Arbeit. Benutzt Du ImageIO zum Abspeichern (bei mir kann ich nur jpg und png auswählen)? Dann gibt es noch eine klitzekleine Überlappung bei der Darstellung des Auswahlbereiches (siehe Screenshot).
    Nochmals Kompliment - Gruß, Markus
  • Vielen Dank für das Kompliment :)

    Markus Müller schrieb:

    Ohne jetzt rumzunörgeln, schau Dir mal CoreAnimation an. Damit bekommst Du die Darstellung Deines Bildes quasi umsonst (inkl. Schatten, zoom-Funktionalität etc.). Auch das Auswahlband könntest Du als Layer umsetzen, ist dann alles animierbar, hardwarebeschleunigt und ganz wenig Arbeit.

    Gut, mach ich mal. CoreGraphics war ja schon neu für mich, aber so schlimm ist es ja gar nicht.
    Lustig ist, dass ich in meinem Projekt /../FlatCarbon/ einbinde, um die Header nach C++ zu bekommen. Etwas beängstigend. Carbon ist doch so schlecht ;)

    Markus Müller schrieb:

    Benutzt Du ImageIO zum Abspeichern (bei mir kann ich nur jpg und png auswählen)?

    Japp. Ist aber ein eigenes NSDocument und ich hab bisher nur die zwei Typen in das writableTypes Array eingetragen. Sollte aber problemlos funktionieren, wenn ich da noch mehr Typen reinschreibe. Aber gibt es irgendwie die Möglichkeit, dass der Nutzer die Parameter auswählen kann (also etwa JPEG Kompression), ohne dass ich mich da selbst drum kümmern muss und womöglich einen eigenen Save-Dialog basteln muss? Hab ich da was übersehen?

    Markus Müller schrieb:

    Dann gibt es noch eine klitzekleine Überlappung bei der Darstellung des Auswahlbereiches (siehe Screenshot).

    Hum. Ja, ich sollte die Größe auch nochmal abrunden, halbe Pixel werden weder gerechnet noch abgespeichert :) Aber scheinbar muss ich da im XIB das Label auch noch etwas verschieben..
    C++
  • osxentwicklerforum.de/index.php/Attachment/3040/
    Jungs, ihr seid klasse. Hab jetzt mal die ganze GUI neu gemacht, komplett mit CoreAnimation und Zeug, wie vorgeschlagen. Hat ziemlich gebraucht, sich da einzuarbeiten, aber hat sich glaube ich gelohnt.

    Ich zeige jetzt den Overlap gar nicht mehr an, ist eh nicht notwendig. Dafür kann man jetzt wie gewünscht "Live-Resizing". Das ist so abgefahren, war echt eine gute Idee.
    Hier den letzten Build (x86, RELEASE, 250kB):
    paste.ioctl.eu/Quiltator-0.2.zip
    Dank Release-Build ist das auch wirklich annehmbar schnell, dass man fast Echtzeit den Overlap anpassen kann.

    Ich sage mal nicht mehr zur Bedienung und bin gespannt, ob es intuitiv genug ist.
    Ergebnisse abspeichern geht übrigens grad nicht, war ich noch zu faul, also nicht wunder ;)

    Und ich habe mich ein wenig bei CocoaControls.com bedient, damit alles schöner ausschaut. Sehr schön, was es da gibt :)
    C++
  • Wow, himmelweiter Unterschied. Sehr viel cooler! Sieht weitaus fertiger aus und fühlt sich smooth an.

    Trotzdem noch ein paar UI-Ideen, alles nix Wildes, falls Du Langeweile hast:

    - Beim Start per Doppelklick wäre ein leeres Dokument oder OpenPanel vielleicht ganz gut
    - Wenn man die Panel nicht reordern kann (sind das die CocoaControls-Dinger?) fände ich die Reihenfolge Input - Preview - Ouput wahrscheinlich intuitiver
    - Fein wäre auch die Möglichkeit, die Views gleichzeitig (vielleicht Splitviewartig) sehen zu können
    - Drag & Drop des Output-Tiles zum Exportieren des Bildes
    Multigrad - 360°-Produktfotografie für den Mac
  • Sehr schön.

    Und beim start was öffen, wie Mattik schon bemerkte.

    Ich sags ja nicht gern. aber ich hab gleich nen crash gehabt. In Output ein bisschen den Overlap x Regler hin und her geschoben, dann hat er sekundenlang Crunching pixels angezigt und bumm.
    Kann aber nicht reproduzieren.

    Chris
    Man macht einfach solange irgendwelche Dinge, bis man tot ist.
    Und dann bekommen die anderen Kuchen.
  • Chris schrieb:

    Und beim start was öffen, wie Mattik schon bemerkte.

    Blöde Frage, aber wie macht man das? Kann das jemand fix verraten, bevor ich wieder Stunden durch die Doku suchen muss?
    Und zwar am besten so, dass wenn man ein File auf die Anwendung zieht zum Starten (also die Anwendung direkt mit einer Datei gestartet wird) eben der Open-Dialog nicht kommt?

    Also ein AppDelegate anlegen und awakeFromNib oder so ist klar, aber woher weiss ich, ob die App schon mit einem Dokument gestartet wurde?
    Oder geht das irgendwie auch noch geschickter?

    Ansonsten Meinung dazu?: Ich hatte überlegt, sowas wie Adobe in manchen Produkten hat, so einen halben "Splash-Screen". Ein Fenster halt wo
    steht "Hey, willkommen, bla bla bla....Willst Du loslegen dann klick hier um ein Bild zu öffnen..". Geht dann automatisch weg, falls man selber
    "Öffnen" auswählt und so. Gute Idee, oder zu un-Mac?
    C++
  • Chris schrieb:

    Ich sags ja nicht gern. aber ich hab gleich nen crash gehabt.

    Wow, Crash-Reports sind ja wirklich nützlich :D
    Ich geh davon aus, dass ich eine C++Exception geworfen habe, die Cocoa aus dem Konzept gebracht hat, weil auch noch im Thread und so. Ursache ist wohl, dass beide Overlaps genau 0 waren, aber die Prüfung darauf irgendwie nicht ausgeführt wurde (und so dann die "sanity-check" exception flog)... Mal sehen, danke auf jeden Fall!
    C++
  • Schreibst Du nur in C++ oder nutzt Du auch Objective-C? In Objective-C könntest Du dann einfach die NSUserDefaults bemühen, die dann ggf. den String zur zuletzt geöffneten Datei sichern und anzeigen. Zum Beispiel soetwas in die Delegate Datei:

    Quellcode

    1. // kurz bevor die App quittet, wird noch ein Befehl ausgeführt
    2. - (void)applicationWillTerminate:(NSNotification *)aNotification {
    3. // Der Pfad wird in die UserDefaults geschrieben
    4. NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
    5. [userPreferences setObject:@"/Pfad/zur/geöffneten/Datei.jpg" forKey:@"openFile"];
    6. }


    Und in die awakeFromNib schreibst Du:

    Quellcode

    1. - (void)awakeFromNib {
    2. // Pfad wird geladen
    3. NSString *key = [[NSUserDefaults standardUserDefaults] stringForKey:@"openFile"];
    4. // nun hast Du den Pfad zur Datei und kannst sie dann ggf. öffnen
    5. }


    LG,

    MacDev27
  • MacDev27 schrieb:

    Schreibst Du nur in C++ oder nutzt Du auch Objective-C? In Objective-C könntest Du dann einfach die NSUserDefaults bemühen, die dann ggf. den String zur zuletzt geöffneten Datei sichern und anzeigen. Zum Beispiel soetwas in die Delegate Datei:

    Die ganze GUI ist Objective-C :)

    Ich versteh nicht ganz, was Du meinst. Meinst Du, dass man wenn man das Programm startet, die letzte Datei automatisch wieder geöffnet wird? Das macht doch sonst auch keine Anwendung? Ausserdem gibt es ja "Benutze Dokumente" und das Open-Panel merkt sich ja auch den letzten Pfad?
    C++
  • Hallo zerm,

    ich hab was im AppStore, das dir Farbpaletten aus Bildern erstellt. Hab ich an einem Tag mit gebrochener Hand gecoded und einfach mal reingestellt um zu sehen wie das geht und was passiert.

    Die Leute kaufen das und beschweren sich nicht über den Preis von 1.50. Gibt ein kleines Taschengeld und hat die Entwicklerlizenz wieder eingespielt.

    Mach das!

    Gruß
    Manfred
    Seminare, Artikel, Code. ObjectiveCeeds - alles für die Apfelzucht.