image.paste mit Maske verändert Bilder

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
MichaelBerlin
User
Beiträge: 4
Registriert: Montag 20. Dezember 2021, 22:00

Hallo ins Forum

Ich bin absoluter Neuling was Programmieren angeht, und um ehrlich zu sein will ich gar nicht wirklich tief in die Materie einsteigen, rein aus fehlender Zeit schon.
Ich habe mich allerdings in ein Problem verbissen, das ich auch mit vielen Stunden googlen nicht lösen konnte.

Und zwar versuche ich mittels .paste aus verschiedenen Bilder randomisiert neue Bilder bauen zu lassen. Das klappt auch alles super.
Auf 5 Ebenen wird aus je einem Set aus Bildern ein neues Bild gebaut, jeweils über .paste auf das background Bild gelegt und letztlich als neues png oder jpeg abgelegt. Alles funktioniert - nur werden beim Paste Befehl scheinbar zufällig Modi des Ineinanderkopierens angewandt, statt einfach nur transparent zu lassen was im png transparent ist.

Über einen kleinen Tipp wäre ich sehr dankbar, da ich das Problem nicht ergooglen konnte scheint mein Fehler vielleicht auf der Hand zu liegen?
Ich habe bereits versucht das finale Bild vor dem speichern zu RGB zu konvertieren und als jpeg auszugeben, aber das ändert nichts. Die Bilder werden als png aus Photoshop exportiert und enthalten nur jeweils den einzufügenden Bereich vor Transparenz, an der richtigen Stelle für das Bild.
Wie gesagt, alles klappt, nur scheint das Skript an irgendeiner Stelle LSD zu nehmen.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ohne dein Skript zu sehen, kann man dazu nix sagen. Und lass mich raten - du generierst NFTs?
MichaelBerlin
User
Beiträge: 4
Registriert: Montag 20. Dezember 2021, 22:00

__deets__ hat geschrieben: Montag 20. Dezember 2021, 23:00 Ohne dein Skript zu sehen, kann man dazu nix sagen. Und lass mich raten - du generierst NFTs?
Lieben Dank für die Antwort! Ich dachte eben man kann vielleicht doch so schon etwas sagen, wollte euch Lesearbeit ersparen :D
Da ja im Skript prinzipiell alles klappt, nur eben mit falschem Modus der Bilder. Dachte wäre irgendwas super simples.

Und ja, geht um das gleiche Prinzip wie bei vielen NFT, aber nicht weil ich wirklich welche machen will sondern weil mich der Vorgang der gesteuert randomisierten Bilderstellung en gros interessiert. Was ich damit anfangen will weiss ich selbst noch nicht. Bin schon mal recht stolz es bis hier hin ohne jegliche Programmierkenntnisse gekommen zu sein in den letzten zwei Nächten :lol:

Hier mal der code, wie gesagt "läuft super" an sich. Noch kein Check auf Duplikate drin, daran hab ich mich noch nicht versucht. Und die csv wird auch noch nicht automatisch erstellt, aber dazu komm ich noch.
(Habe ein paar Bildnamen rausgenommen aus dem Code, die eventuell Rückschlüsse auf meine Person zulassen.)

Code: Alles auswählen

from os import path, mkdir
from PIL import Image
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
import pandas as pd
import numpy as np

output_folder = "ABC_NFT"
if not path.exists(output_folder):
    mkdir(output_folder)

backgrounds = ["background_blackestnight", "background_bluenight", "background_cloudyblue", "background_cloudygrey", "background_largemoon", "background_largesun", "background_lightning", "background_snow_grey", "background_snowblue", "background_sunrise", "background_sunset", "background_meteor"]
characters = ["alle verschiedenen characters"]
mouths = ["mouth_happy1", "mouth_happy2", "mouth_happy3", "mouth_sad", "mouth_scared", "mouth_shout1", "mouth_shout2", "mouth_shout3", "mouth_smile", "mouth_smirk1", "mouth_smirk2", "mouth_smirk3", "mouth_teeth"]
brows = ["brows_angry1", "brows_angry2", "brows_angry3", "brows_neutral1", "brows_neutral2", "brows_neutral3", "brows_oh1", "brows_oh2", "brows_oh3", "brows_sus1", "brows_sus2", "brows_sus3"]
eyes = ["eyes_straight", "eyes_left", "eyes_right", "eyes_down", "eyes_angry", "eyes_angry_right", "eyes_angry_left", "eyes_sad", "eyes_sad_left", "eyes_sad_right", "eyes_sus", "eyes_sus_left", "eyes_sus_right", "eyes_red", "eyes_blue", "eyes_brown", "eyes_cash", "eyes_gold", "eyes_laser_blue"]
file_name = ["test"]

def generate_image(background, character, mouth, brow, eye, file_name):
    """Generate image with given background, given character and given object and save it with the given file name
    Args:
        background (str): background name
        character (str): character name
        mouth (str): mouth name
        brow (str): brow name
        eye (str): eye name
        file_name (str): file name
    """
    background_file = path.join("backgrounds", f"{background}.png")
    background_image = Image.open(background_file)

    #Create character
    character_file = path.join("characters", f"{character}.png")
    character_image = Image.open(character_file)

    background_image.paste(character_image, mask=character_image)

    #Create mouth
    mouth_file = path.join("mouths", f"{mouth}.png")
    mouth_image = Image.open(mouth_file)

    background_image.paste(mouth_image, mask=mouth_image)

    #Create brow
    brow_file = path.join("brows", f"{brow}.png")
    brow_image = Image.open(brow_file)

    background_image.paste(brow_image, mask=brow_image)

     #Create eye
    eye_file = path.join("eyes", f"{eye}.png")
    eye_image = Image.open(eye_file)

    background_image.paste(eye_image, mask=eye_image)
    
    output_file = path.join(output_folder, f"{file_name}.jpg")
    background_image.convert("RGB").save(output_file)

def generate_random_imgs(total_imgs):
    df = pd.DataFrame(columns = ["background", "character", "mouth", "brow", "eye", "file_name"])
    for num in range(total_imgs):
        background = np.random.choice(np.arange(0,len(backgrounds)), p=[0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.05, 0.03, 0.01, 0.01])
        background = backgrounds[background]
        
        character = np.random.choice(np.arange(0,len(characters)), p=[0.2, 0.2, 0.2, 0.2, 0.05, 0.05, 0.025, 0.025, 0.025, 0.025])
        character = characters[character]
        
        mouth = np.random.choice(np.arange(0,len(mouths)), p=[0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.05, 0.05, 0.05, 0.04, 0.005, 0.005])
        mouth = mouths[mouth]
        
        brow = np.random.choice(np.arange(0,len(brows)), p=[0.20, 0.10, 0.10, 0.10, 0.10, 0.10, 0.10, 0.05, 0.05, 0.05, 0.025, 0.025])
        brow = brows[brow]
        
        eye = np.random.choice(np.arange(0,len(eyes)), p=[0.10, 0.10, 0.10, 0.10, 0.10, 0.09, 0.05, 0.05, 0.04, 0.05, 0.03, 0.03, 0.03, 0.03, 0.03, 0.03, 0.02, 0.01, 0.01])
        eye = eyes[eye]

        generate_image(background, character, mouth, brow, eye, f"ABC_NFT{num}")
        data = [background, character, mouth, brow, eye, f"ABC_NFT{num}"]
        s = pd.Series(data, index=df.columns)
        df = df.append(s, ignore_index=True)
        
    df.to_csv('data.csv', index=False)

if __name__ == "__main__":
    #generate_all_imgs()
    generate_random_imgs(200)
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das einzige, was mir da auffällt, ist dieses truncated image flag. Das braucht man nur bei defekten Bildern. Warum ist das an?
MichaelBerlin
User
Beiträge: 4
Registriert: Montag 20. Dezember 2021, 22:00

__deets__ hat geschrieben: Dienstag 21. Dezember 2021, 09:01 Das einzige, was mir da auffällt, ist dieses truncated image flag. Das braucht man nur bei defekten Bildern. Warum ist das an?
Das hatte ich eingefügt weil es sonst manche Bilder nicht akzeptiert hat, vielleicht weil die 1 Pixel kleiner sind oder so? Der Fehler um den es mir geht ist aber auch davor schon aufgetreten.
MichaelBerlin
User
Beiträge: 4
Registriert: Montag 20. Dezember 2021, 22:00

Konnte das Problem lösen. Es lag daran dass das background Bild als png mit Alpha Kanal angelegt war. Mit einem jpeg als background funktioniert es perfekt. Lieben Dank dennoch hier rein!
Antworten