Pic in Pic Generator

  • Guten Tag,

    vor einigen Monaten habe ich mit autoit angefangen und schreibe seit dem funktionale(*) Programme für den Alltag.
    *Umschreibung für unübersichtliche Codewurst die ich in meiner Freizeit schnell schreibe.


    Was macht das Programm?
    Das Programm erzeugt aus ganz vielen kleinen Bildern ein großes ganzes Bild.
    Programmablauf
    - Ein Hauptbild wird ausgewählt welches von weitem erkennbar sein soll (sollte so 128x128 sein Seitenformat ist egal)
    - Als Vorlage wird ein Album mit jpg Fotos ausgewählt (Seitenformat sollte 1 zu 1 sein)
    - Das Album wird auf eine vom Benutzer vorgegebene Größe skaliert (Aktuell 64x64) und unter Album rescale gespeichert
    - Jeder Pixel und Position des Hauptbild wird zwischen gespeichert und wird durch ein kleines zufälligtes Foto aus dem Album rescale neu zusammengesetzt
    - jedes Kleine Foto bekommt eine Umrandung der jeweiligen ermittelten Pixelfarbe. Transparenz und Dicke der Umrandung lässt sich einstellen
    - zusätzlich lässt sich jedes kleine Bild mit der jeweiligen ermittelten Farbe und einer Transparenz einfärben, von weiten sieht es einfach besser aus.


    Warum das ganze?
    Die Grundidee habe ich aus einem Foto, dass ich mal über Whatsapp bekommen habe. (Kann ich aus Jugendschutzgründen nicht posten)
    Mein Ziel ist es für Valentinstag eine große Pärchen Fotocollage zu erstellen und auf Leinwand,Poster oder Foto zu bringen.

    Probleme
    Bei einem Hauptbild mit 128x128 Pixel wird jeder Pixel mit 64x64 Bildern aufgefüllt.
    Die Ausgabe hat eine Auflösung von 8192x8192. (128*64) als jpg ca 8MB weshalb ich das hier nur verkleinert hochladen konnte.
    Keine Ahnung ob sich so etwas überhaupt als Poster in A4 oder A3 in einer vernünftigen DPI ausdrucken lässt, vielleicht hat jemand von euch Ideen und Anregungen :P Hab noch bis Dienstag Zeit.


    Luxusproblem: Das Programm ist relativ lahm und braucht für die o.g Auflösung ca 2 Minuten.


    Paar Beispiele
    GUI:
    Beispiel.jpg

    Ausgabe: (50% skaliert)
    1.jpg

    Etwas näher dran. (auch 50% skaliert)
    2.jpg


    Wenn ich was Zeit finde mach ich den Code vorzeigbar und veröffentliche den bei Interesse auch hier.


    EDIT 2
    Neues in Version 1.1
    - Das generieren dauert nur noch wenige Sekunden, THX @ UEZ!
    - Neue Option "Keine identischen Bilder nebeneinander"
    - Die Minibilder haben jetzt können jetzt gedreht oder gespiegelt eingesetzt werden
    - Menü flackert nicht mehr
    - Auflösung der Ausgabe wird angezeigt
    - Paar Bugfixes

    DoTo
    - Schöneres GUI erstellen
    - Minibilder in Format 2:3 3:2 erlauben (Aktuell leider nur 1:1)
    - Keine identischen Bilder übereinander!
    - Quellcode einheitlich machen und aufräumen.



    Unaufgeräumten Code hochgeladen.

  • Wenn ich was Zeit finde mach ich den Code vorzeigbar und veröffentliche den bei Interesse auch hier.

    @UEZ this.

    @Romanow super, dann bist du hier aber falsch. Code sollte man schon mitliefern, wenn man hier was vorstellt... Es ist erstmal egal wie wurstig der aussieht, aber das gehört zum guten Ton.

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • Hallo Romanow,

    vielen Dank für die Bereitstellung des Code. Klappt alles gut in meinem Test, nur dass bei mir den Ordner aus der Orderwahl nicht übernommen wird. Wenig Codezeilen. Großer Effekt. Ich finde Du hast das richtig toll gemacht.

  • Hi @Romanow,
    Was soll ich sagen, dein Programm funktioniert toll! :thumbup:
    Meine Motivation war und ist Automatisierung für den Alltag. Ich bin jetzt eine Zeitlang dabei und bin immer wieder erstaunt, wenn Leute nach kurzer Zeit mit AutoIt und in ihrem ersten Beitrag schon viel besser sind als ich.
    ... das kann doch nicht an meinem Hilfsarbeiter-Intellekt liegen? :/

    Grüße autoiter

  • Die Hauptschleife produziert ein Memory Leak, d.h. du öffnest in der Schleife immer wieder neue GDI+ Handles ohne diese wieder freizugeben.

    AutoIt
    For $i = 0 To $iImageHeight - 1 Step 1 ; Y Achse pro Pixel ein Bild generieren!
    		For $j = 0 To $iImageWidth - 1 Step 1 ; X Achse pro Pixel ein Bild generieren!
    ...

    _GDIPlus_BitmapGetPixel ist relativ langsam -> schaue dir mal die _GDIPlus_BitmapLockBits Funktion an und wie man die Pixel Farbe ausliest. Innerhalb dieser Schleife solltest du auch keine Variablen deklarieren, macht keinen Sinn und kostet nur Zeit.

    Ansonsten funzt der Code. :thumbup:

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Das Valentinsgeschenk ist sehr gut angekommen.

    Die Druckqualität am DM Druckerautomaten ist unerwartet gut gewesen. Bei einer Auflösung von 6400x8768 ist bei einer Minibildauflösung von 64x64 auf 30x20cm Fotodruck alles gut erkennbar.

    Hab noch ein paar Sachen eingebaut.

    Neues in Version 1.1
    - Das generieren dauert nur noch wenige Sekunden, THX @ UEZ!
    - Neue Option "Keine identischen Bilder nebeneinander"
    - Die Minibilder haben jetzt können jetzt gedreht oder gespiegelt eingesetzt werden
    - Menü flackert nicht mehr
    - Auflösung der Ausgabe wird angezeigt
    - Paar Bugfixes


    ToDo
    - Schöneres GUI erstellen
    - Minibilder in Format 2:3 3:2 erlauben (Aktuell leider nur 1:1)
    - Neue Option Keine identischen Bilder übereinander!
    - Quellcode einheitlich machen und aufräumen.
    - Der Bildspeicher wird immer noch nicht vernünftig freigegeben

    Einmal editiert, zuletzt von Romanow (19. Februar 2017 um 14:43)

  • Hallo @Romanow,

    Vorneweg. Ich finde es ganz toll. Als ich mir die Einzelbilder größer anzeigen lassen wollte und die Pixeldimensionen auf 265 erhöht habe, kam folgendes heraus:
    Unbenannt.PNG
    Sollten nicht auch die Bilder größer werden?

    Ich wollte dann ganz schlau sein und habe vor _GDIPlus_GraphicsDrawImage

    AutoIt
    $bitmap_from_file = _GDIPlus_ImageResize($bitmap_from_file, GUICtrlRead($idwidth), GUICtrlRead($idwidth))

    eingefügt. Das war aber nix (ich habe auch keine Ahnung davon :D).
    Dabei ist mir aber aufgefallen, dass hier überall in der Schleife das Control $idwidth ausgelesen wird. Besser wäre es, GUICtrlRead($idwidth) vor der Schleife in einer Variable zu speichern und damit weiterzuarbeiten. (Ich weiß nicht, ob das viel Zeit kostet, es besteht aber die theoretische Möglichkeit, dass der Nutzer während der Bearbeitung schon die Einstellungen ändert. Das würde sich dann mittendrin auf den aktuellen Job auswirken).

    Grüße autoiter

  • Hab das Problem gefunden.

    In der Funktion _PIC_scale muss der Ordner mit den Minibildern immer vorher gelöscht werden, da er sonst die alte Minibilderauflösung verwendet.
    DirRemove("Album rescale\")