Einfachste Möglichkeit ein pixelweise ein Bild zu erstellen?

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
sonium
User
Beiträge: 66
Registriert: Mittwoch 27. Oktober 2004, 21:04

Hi, was ist die einfachste möglichkeit in Python pixelweise ein Bild (egal ob in Datei oder auf Bildschirm) zu erzeugen?

Code wäre nett :)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Nutzen der PIL?
Was anderes fällt mir jetzt nicht direkt ein, du kannst auch versuchen pygame oder gtk.DrawingArea zu nutzen, das sollte auch ok gehen nur wie es mit dem speichern aussieht..
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hier gab es mal ein Mandelbrot Skript, welches mit TK pixelweise das Bild aufbaute... wobei es aber nicht wirklich Grafikpixel war, sondern Textpunkte, glaube ich...
BlackJack

Hi sonium,

Was möchtest Du denn mit dem Bild machen? Das am einfachsten zu erzeugende Format in irgendeiner beliebigen Programmiersprache, die Text in Dateien ausgeben kann, sind wohl die Netpbm Formate pbm (Schwarzweiss), pgm (Graustufen (auch mehr als 256)) und ppm (RGB).

Die Bilder lassen sich dann zum Beispiel mit den Netpbm Programmen, ImageMagick oder Gimp weiterverarbeiten.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Also ich finde XBM (X11 Bitmap) und XPM (X11 Pixmap) besser, finde ich von der Struktur einfacher.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Dann hast Du Dir nicht angeschaut, wie die NetPBM Formate aussehen. Was kann man denn an der Struktur noch einfacher machen? Es wird das Format, Höhe und Breite, eventuell noch die Anzahl der Graustufen als Text in eine Datei geschrieben und dann folgen die Bilddaten, entweder als Höhe*Breite Bytes/Words bei den "Raw" Formaten oder als Zahlen als Text durch Whitespace getrennt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

BlackJack hat geschrieben:Dann hast Du Dir nicht angeschaut, wie die NetPBM Formate aussehen. Was kann man denn an der Struktur noch einfacher machen? Es wird das Format, Höhe und Breite, eventuell noch die Anzahl der Graustufen als Text in eine Datei geschrieben und dann folgen die Bilddaten, entweder als Höhe*Breite Bytes/Words bei den "Raw" Formaten oder als Zahlen als Text durch Whitespace getrennt.
Doch das habe ich:
PPM:

Code: Alles auswählen

P3
# feep.ppm
4 4
15
 0  0  0    0  0  0    0  0  0   15  0 15
 0  0  0    0 15  7    0  0  0    0  0  0
 0  0  0    0  0  0    0 15  7    0  0  0
15  0 15    0  0  0    0  0  0    0  0  0
gegen XPM. Da finde ich XPM irgendwie übersichtlicher. Also ein bild einfacher als das Bild mit buchstaben zu malen kann ich mir wirklich nicht einfacher vorstellen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Das malen mit Buchstaben ist doch gar nicht das Problem, es ging darum ein Bild von einem Programm erzeugen zu lassen. Ich würde beides nicht per Hand erstellen wollen. Mit mehr als 4-5 Farben wird's auch ziemlich unübersichtlich bei XPM. Schau Dir mal das hier an: http://strony.ac-net.pl/magdah/jxpm/kod ... odim03.xpm

Die NetPBM Formate sind von der Struktur her einfacher aufgebaut und einfacher von einem Programm zu erzeugen. Vom einlesen mal ganz zu schweigen. Man muss jedenfalls kein C-Programm scannen.
BlackJack

Eine kleine Klasse mit der man ein PGM (Graustufen) erstellen und speichern kann:

Code: Alles auswählen

import struct

class PGM:
    def __init__(self, width, height, maxval=None, comment='producer: pnm.py'):
        if width <= 0 or height <= 0:
            raise ValueError("Dimensions must be > 0")
        
        self.width = width
        self.height = height
        self.maxval = maxval
        self.comment = comment
        
        #
        # Create empty image.
        #
        self.data = list()
        for dummy in xrange(self.height):
            self.data.append([0] * self.width)
    
    def __getitem__(self, coordinate_or_row):
        try:
            x, y = coordinate_or_row
            return self.data[y][x]
        except TypeError:
            return self.data[coordinate_or_row]
    
    def __setitem__(self, coordinate_or_row, pixel_or_row):
        try:
            x, y = coordinate_or_row
            self.data[y][x] = pixel_or_row
        except TypeError:
            self.data[coordinate_or_row] = pixel_or_row

    def write(self, fileobj):
        #
        # Write header.
        #
        fileobj.write('P5\n')
        if self.comment:
            fileobj.write('# %s\n' % self.comment)
        fileobj.write('%s %s\n' % (self.width, self.height))
        if self.maxval is None:
            self.maxval = max(map(max, self.data))
        fileobj.write('%s\n' % self.maxval)
        
        #
        # Write image data.
        #
        row_format = '>%d%s' % (self.width, 'BH'[int(self.maxval > 255)])
        for row in self.data:
            fileobj.write(struct.pack(row_format, *row))

    def save(self, filename):
        image_file = open(filename, 'wb')
        self.write(image_file)
        image_file.close()
So zu benutzen:

Code: Alles auswählen

from __future__ import division
import math

image = PGM(320, 240)
for y in xrange(image.height):
    for x in xrange(image.width):
        image[x, y] = int(abs((math.sin(x / 23)
                               + math.sin(y / 42)
                               + math.sin(x / 6.4)
                               + math.sin(y / 3.2))) * (255 / (2*math.pi)))
image.save('sin.pgm')

image = PGM(320, 240)
for row_nr in xrange(image.height):
    image[row_nr] = [row_nr] * image.width

image.save('gradient_h.pgm')
Die Klasse auf TrueColor Bilder (PPM) umzustellen sollte nicht weiter schwer sein. Es fehlt natürlich auch ein wenig Dokumentation und ein paar Überprüfungen von Paramtern.
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!

Sehr nett. Im Beispiel sollte man aber auch PGM importieren, sonst bleibts ziemlich finster :wink:

Gruß, mawe
sonium
User
Beiträge: 66
Registriert: Mittwoch 27. Oktober 2004, 21:04

mitlerweile hab bin ich auf pygame.surfarray gekommen. Hier eine Fläche pixelweise Blau anmalen:

Code: Alles auswählen

try:
    import pygame
    import Numeric as N
    from pygame.locals import *
    surfarray = pygame.surfarray
    if not surfarray: raise ImportError
except:
    raise ImportError, 'Error Importing Pygame/surfarray or Numeric'
    
pygame.init()
    

def show(img):
    screen = pygame.display.set_mode(img.shape[:2], 0, 32)
    surfarray.blit_array(screen, img)
    pygame.display.flip()
    pygame.display.set_caption("Simple GFX Output")
    while 1:
        e = pygame.event.wait()
        if e.type == QUIT: raise SystemExit
            
img = N.zeros((320, 240, 3))

for x in range(img.shape[0]):
    for y in range(img.shape[1]):
        img[x,y,:] = [100,155,255]

show(img)
Antworten