bmp nach ppm

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.
IgelaufReisen
User
Beiträge: 49
Registriert: Montag 29. Oktober 2007, 20:10
Wohnort: Berlin
Kontaktdaten:

bmp nach ppm

Beitragvon IgelaufReisen » Mittwoch 5. Dezember 2007, 21:34

Hallöchen liebe Community.
Ich habe ein bmp-Bild und möchte dies mit Hilfe von Python und PIL in eine ppm-Datei umwandeln. Da kann man bestimmt irgendwas mit convert oder tostring machen, aber ich bin Neuling im Programmieren und verstehe den Text in der Erläuterung dazu nicht, da mein Englisch zu schlecht ist und den Inhalt ähnlicher Threads verstehe ich auch nicht wirklich.
Kann mir da irgendwer helfen?
Liebe Grüße
Der Igel
BlackJack

Beitragvon BlackJack » Mittwoch 5. Dezember 2007, 21:40

Auf Dauer solltest Du Dein Englisch verbessern. Ohne ist man beim Programmieren aufgeschmissen.

Code: Alles auswählen

In [90]: from PIL import Image

In [91]: img = Image.open('test.bmp')

In [92]: img.save('test.ppm')
IgelaufReisen
User
Beiträge: 49
Registriert: Montag 29. Oktober 2007, 20:10
Wohnort: Berlin
Kontaktdaten:

Beitragvon IgelaufReisen » Mittwoch 5. Dezember 2007, 22:03

Ok...
Ich trag mich morgen für nen Volkshochschulkurs Englisch ein.
Aber danke für die Hilfe.
Aber kriegt man das auch irgendwie hin, dass die ppm-Datei nich aus den ASCII-Zeichen besteht, sondern aus den Ordnungszahlen derselbigen? Mit denen kann ich besser umgehen.
BlackJack

Beitragvon BlackJack » Mittwoch 5. Dezember 2007, 22:26

PIL unterstützt nur die "raw"-Formate und nicht die "plain"-Formate von PPM/PGM/PBM.
IgelaufReisen
User
Beiträge: 49
Registriert: Montag 29. Oktober 2007, 20:10
Wohnort: Berlin
Kontaktdaten:

Beitragvon IgelaufReisen » Donnerstag 6. Dezember 2007, 20:47

Das is ja doof.
Und wie baut man aus ner Bmp-Datei ne PPM im 'Plain'-Format ohne PIL?
Gibt es da noch mehr MOdule?
IgelaufReisen
User
Beiträge: 49
Registriert: Montag 29. Oktober 2007, 20:10
Wohnort: Berlin
Kontaktdaten:

Beitragvon IgelaufReisen » Montag 10. Dezember 2007, 20:50

Da keine weitere Hilfe mehr kam, wollte ich das jetzt selbst in die Hand nehmen. Habe dazu das folgende Programm geschrieben. Für kleine Bilder funktioniert es auch (11 * 11). Aber für größere Bilder geht es nicht (340*486). Da zeigt er mir dann nur noch den oberen Teil des Bildes an. Ich weiß nicht, woran das liegt, und hoffe, dass mich jemand auf meinen grundlegenden Fehler aufmerksam machen kann.
Gruß
Igel

Code: Alles auswählen

from PIL import Image
class neu:
    def __init__(self):
        self.bild=[]
        self.karl=[]
   
    def dat_lesen(self,datei):
        f = file(datei,"r")   
        li = f.readlines()
        f.close()
        return li
   
    def dat_schreiben(self,text,datei):
        f = file(datei,"w")
        f.writelines(text)
        f.close()
   
    def eins(self,datei):
        self.bild_2 = Image.open(datei)
        self.bild_2.save('neu_karl.ppm')
        self.bild = self.dat_lesen('neu_karl.ppm')
        vorn = self.bild[:3]
        vorn[1] = vorn[1].split(' ')
        reihen = vorn[1][0]
        spalten = vorn[1][1]
        self.bild = self.bild[3:]
        self.bild = self.bild[0].strip()
        op1 = 0
        while op1 < len(self.bild):
            self.karl.append(ord(self.bild[op1]))
            op1 += 1


        aufloesung = str(reihen) + (' ') + str(spalten)
        text=''
        c = []
        c.append('P3\n')
        c.append('# Created by IrfanView\n')
        c.append(aufloesung)
        c.append('255\n')
       
        op1 = 0
        op2 = 1
        while op1 < len(self.karl):
            text += str(self.karl[op1])
            if (op2%9)==0:text += '\n'
            text += ' '
            op1 += 1
            op2 += 1
        c.append(text)
        self.dat_schreiben(c,'neu.ppm')
       
        print 'fertig'
       
horst = neu()
horst.eins('test.bmp')
BlackJack

Beitragvon BlackJack » Montag 10. Dezember 2007, 21:13

Das liegt daran, das der Quelltext so verdammt "unpythonisch" ist und an der Namensgebung.

Na gut nicht wirklich, aber der Compiler sollte solchen Code echt zurückweisen. :twisted:

Warum steckt das ganze in einer Klasse?

Wenn man Namen wie `karl`, `horst`, und `eins` verwendet, hat man sich offenbar nicht genug Gedanken um die Funktion der Objekte gemacht, sonst hätte man aussagekräftige Namen gefunden.

Die beiden ``while``-Schleifen mit manuell verwaltetem Index sind zwar Python-Syntax, aber eindeutig nicht idiomatisches Python. Man kann bei "iterables" direkt mit ``for`` über die Elemente iterieren.
IgelaufReisen
User
Beiträge: 49
Registriert: Montag 29. Oktober 2007, 20:10
Wohnort: Berlin
Kontaktdaten:

Beitragvon IgelaufReisen » Montag 10. Dezember 2007, 21:20

Die beiden ``while``-Schleifen mit manuell verwaltetem Index sind zwar Python-Syntax, aber eindeutig nicht idiomatisches Python. Man kann bei "iterables" direkt mit ``for`` über die Elemente iterieren.


Tut mir leid, aber ich weiß wirklich nicht, was damit gemeint ist. Ich bin Pythonneuling und programmiere eben so, wie ich es weiß.
Und liegt der Fehler also wirklich an den while-Schleifen? Würde es also mit

Code: Alles auswählen

for i in range(0,len(self.bild)):
...

funktionieren?
IgelaufReisen
User
Beiträge: 49
Registriert: Montag 29. Oktober 2007, 20:10
Wohnort: Berlin
Kontaktdaten:

Beitragvon IgelaufReisen » Montag 10. Dezember 2007, 21:30

Code: Alles auswählen

from PIL import Image
class umwandler:
    def __init__(self):
        self.bild=[]
        self.karl=[]
   
    def dat_lesen(self,datei):
        f = file(datei,"r")   
        li = f.readlines()
        f.close()
        return li
   
    def dat_schreiben(self,text,datei):
        f = file(datei,"w")
        f.writelines(text)
        f.close()
   
    def hauptprogramm(self,datei):
        self.bild_2 = Image.open(datei)
        self.bild_2.save('neu_karl.ppm')
        self.bild = self.dat_lesen('neu_karl.ppm')
        print len(self.bild[3])
        vorn = self.bild[:3]
        vorn[1] = vorn[1].split(' ')
        reihen = vorn[1][0]
        spalten = vorn[1][1]
        self.bild = self.bild[3:]

        print len(self.bild[0])
       
        self.bild = self.bild[0].strip()

        print len(self.bild)

        for i in range(0,len(self.bild)):
            self.karl.append(ord(self.bild[i]))
        #print self.karl

        print len(self.karl)

        aufloesung = str(reihen) + (' ') + str(spalten)
        text=''
        c = []
        c.append('P3\n')
        c.append('# Created by IrfanView\n')
        c.append(aufloesung)
        c.append('255\n')
       
        op2 = 1

        for i in range(0,len(self.karl)):
            text += str(self.karl[i])
            if (op2%27)==0:text += '\n'
            text += ' '
            op2 += 1
        #print text
       
        c.append(text)
        self.dat_schreiben(c,'neu.ppm')
       
        print 'fertig'
       
horst = umwandler()
horst.hauptprogramm('test.bmp')



Programmcode den Hinweisen angepasst.
Ergebnis das gleiche. Also lag es nicht daran.
BlackJack

Beitragvon BlackJack » Montag 10. Dezember 2007, 22:05

Es steckt immer noch in einer Klasse.

Mit direkt über die Elemente iterieren ist ohne Index gemeint. Eben direkt. ``for element in iterable:``.

Du kannst die PPM-Datei von PIL nicht einfach als Text behandeln. Nur die Kopfzeilen sind "Text", der Rest sind beliebige Bytes. Unter anderem können da auch Bytes vorkommen, die in Texten als Zeilenwechsel dienen.
BlackJack

Beitragvon BlackJack » Mittwoch 12. Dezember 2007, 11:23

Direkte Umwandlung in ein "plain" PPM als einfache Funktion:

Code: Alles auswählen

from PIL import Image

def image2ppm(image):
    if image.mode != 'RGB':
        image = image.convert('RGB')
    return (('P3\n%d %d\n%d\n' % (image.size + (255,)))
            + '\n'.join(str(ord(byte)) for byte in image.tostring()))


def main():
    image = Image.open('test.bmp')
    ppm = image2ppm(image)
    ppm_file = open('test.ppm', 'wb')
    ppm_file.write(ppm)
    ppm_file.close()


if __name__ == '__main__':
    main()
IgelaufReisen
User
Beiträge: 49
Registriert: Montag 29. Oktober 2007, 20:10
Wohnort: Berlin
Kontaktdaten:

Beitragvon IgelaufReisen » Mittwoch 12. Dezember 2007, 17:58

Das is ja cool.
Danke!
Genau verstehen tue ich den Quelltext zwar noch nicht, aber da werd ich mich heute abend genauer reinlesen.
Jedenfalls nochmals ein ganz großes Danke dafür!
IgelaufReisen
User
Beiträge: 49
Registriert: Montag 29. Oktober 2007, 20:10
Wohnort: Berlin
Kontaktdaten:

ppm nach bmp

Beitragvon IgelaufReisen » Mittwoch 12. Dezember 2007, 18:26

Ok,
aber wie geht das ganze in die andere Richtung?
Denn so:

Code: Alles auswählen

from PIL import Image

def image2bmp(image):
    if image.mode != 'RGB':
        image = image.convert('RGB')
    return (('BM\n%d %d\n%d\n' % (image.size + (255,)))
            + '\n'.join(chr(byte) for byte in image.tostring()))


def main():
    image = Image.open('test.ppm')
    ppm = image2ppm(image)
    ppm_file = open('test.bmp', 'wb')
    ppm_file.write(ppm)
    ppm_file.close()


if __name__ == '__main__':
    main()

...geht es ja leider nicht.
Er meckert da rum, dass er irgendetwas nicht kennt.
Aber von bmps verstehe ich noch viel weniger, als von ppms..
:(
BlackJack

Beitragvon BlackJack » Mittwoch 12. Dezember 2007, 20:12

So ein PPM sollte man dann wieder in ein `PIL.Image`-Objekt umwandeln. Mit BMPs kann `PIL` ja umgehen.

Code: Alles auswählen

from itertools import imap
from PIL import Image

def p3_ppm2image(ppm):
    values = (value for value in ppm.split() if not value.startswith('#'))
    if values.next() != 'P3':
        raise ValueError('no plain PPM')
    values = imap(int, values)
    size = (values.next(), values.next())
    if values.next() != 255:
        raise ValueError('max value not 255')
    result = Image.new('RGB', size)
    result.fromstring(''.join(imap(chr, values)))
    return result


def main():
    ppm_file = open('test.ppm')
    ppm_data = ppm_file.read()
    ppm_file.close()
    image = p3_ppm2image(ppm_data)
    image.save('test2.bmp')


if __name__ == '__main__':
    main()
IgelaufReisen
User
Beiträge: 49
Registriert: Montag 29. Oktober 2007, 20:10
Wohnort: Berlin
Kontaktdaten:

Beitragvon IgelaufReisen » Mittwoch 12. Dezember 2007, 20:56

Alter wie krass.
Wie soll denn nen Neueinsteiger auf sowas kommen?
Also das finde ich wirklich beeindruckend.
Also nochmal nen gaaaaanz großes Dankeschön dafür;)

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]