Seite 1 von 1
Eisfläche
Verfasst: Mittwoch 21. April 2010, 13:10
von majinv
Servus zusammen

,
ich schreibe mir gerade eine Eisfläche auf der ich mit der Mouse (in meinem Fall Finger, weil es ein TouchScreen ist) schreiben kann. Dachte eigentlich, das das schnell gehen sollte.
stoße aber gerade an ein Problem.
Ich möchte transparent zeichnen und wenn ich gezeichnet habe, möchte ich das der
Bildschirm nach einer Zeit x wieder "zufriert". Schön wäre sogar eine Art fade effekt. Ich dachte dabei an ein array in dem ich mir
die Mouseposition merke, jedoch weiß ich nicht, wie ich das Bild nur an der Position wieder ersetze...
Hat jemand eine Idee?
Verfasst: Mittwoch 21. April 2010, 13:21
von Defnull
Kannst du nicht einfach alle x Millisekunden die komplette Fläche mit der Original-Textur und 0.01 Deckung wieder überzeichnen? Dann verschwindet die Zeichnung langsam.
Verfasst: Mittwoch 21. April 2010, 13:36
von majinv
hmmm, dann bräuchte ich aber einen Counter für jedes Pixel, weil die ja zu einem unterschiedlichen Zeitpunkt bemalt wurden.
Allerdings finde ich die Idee dennoch Klasse, statt Eis könnte man auch den Bildschirm
beschlagen lassen und dann einfach von einem "pusten" ausgehend, den Bildschirm beschlagen, dann hätte ich das Zeitproblem nicht.
Du weißt nicht zufällig, wie ich den Deckungsgrad angeben kann?
EDIT: Eventuell durch eine Angabe der Helligkeit?
Sodass man das Bild immer "dunkler" werden lässt... ist aber glaub ich eher die hässliche variante...
Verfasst: Mittwoch 21. April 2010, 14:14
von majinv
Als Zwischenlösung hab ich
_image.set_alpha(i)
screen.blit(_image, (0, 10))
gewählt, falls es was besseres gibt nur her damit...
aber das ist derzeit meine Zwischenlösung, damit fadet das was übermal wurde immer wieder weg, sobald es gemalt wurde... man muss es halt vorher auf 255 setzen und
nach dem zeichnen des bildes auf 0 und die 0 dann stückweise erhöhen...
dann siehts so aus als würde es rausfaden... bzw beschlagen

Verfasst: Mittwoch 21. April 2010, 15:43
von majinv
Da das jetzt funktioniert, ich habs mir mal schöner gemacht

Eine neue Frage, ich möchte den beschlagenen Bildschirmwegwischen können,
(kann ich) aber ich will das der Hintergrund zum Vorschein kommt.
Von mir aus auch 2 übereinander gelegte Bilder, ne Art Overlay Funktion...
sprich transparent malen... jemand eine idee?
Ich hab leider das gefunden:
The alpha value will be written directly into the Surface if it contains pixel alphas, but the draw function will not draw transparently.
Zerstört das meinen Traum oder gibts n Workaround?
Verfasst: Mittwoch 5. Mai 2010, 13:19
von majinv
aloah...
ich hab leider noch keine antwort auf meine Frage gefunden, wie man transparent zeichnen kann. Wäre super falls das jmd liest oder sich jmd damit beschäftigt, der mir ne Hilfestellung geben kann... Vielen Dank!
Verfasst: Mittwoch 5. Mai 2010, 13:46
von theliquidwave
Mix die Farben selber.
Sollte eigentlich nicht schwer sein. Wenn du z.B. Rot mit einem Alpha von 128 (255 / 2) zeichnen willst, erhältst du als Rot(255, 128, 128).
Es dürfte also folgendes gelten:
Code: Alles auswählen
>>> from __future__ import division # Wichtig wenn Python 2 verwendet wird!
>>> class AlphaCalculator(object):
def __init__(self, backr, backg, backb):
self.backr = backr
self.backg = backg
self.backb = backb
def calculate(self, r, g, b, a):
r = (255 - a) / 255 * r + a / 255 * self.backr
g = (255 - a) / 255 * g + a / 255 * self.backg
b = (255 - a) / 255 * b + a / 255 * self.backb
return (int(r), int(g), int(b))
>>> simulator = AlphaCalculator(255, 255, 255) # Hintergrundfarbe: weiß
>>> half_transparent_red = simulator.calculate(255, 0, 0, 128) # Rot mit einem Alpha von 128 (255 / 2)
>>> half_transparent_red
(255, 128, 128) # Ergebnis, verblasstes Rot
Gruß
Verfasst: Mittwoch 5. Mai 2010, 14:05
von majinv
Hallo Chris,
Vielen Danke für deine Mühe

Wenn ich deinen Code richtig verstehe, dann bezieht der sich immer auf den Hintergrund...
und erzeugt nur den schein, dass man transparent zeichnen würde...
ich möchte aber praktisch gesehen, eine scheibe anhauchen und mit dem finger reinzeichnen können, sodass ich wieder durch das fenster schauen kann...
(falls ich deinen code mißinterpretiert habe, fühl dich bitte genötigt mir zu widersprechen

)
Verfasst: Mittwoch 5. Mai 2010, 14:11
von theliquidwave
Naja, das bezog sich eher auf
The alpha value will be written directly into the Surface if it contains pixel alphas, but the draw function will not draw transparently.
Das kannst du halt dementsprechend anpassen. Ich dachte das Problem liegt daran, dass das Verblassen nicht klappt.
Beispiel: So sieht dein Bild vor dem verblassen aus (1):
So in der Hälfte der Zeit (2):
Und so am Ende des Vorgangs (3):
Der Punkt stellt das halb-verblasste # dar.
Wenn deine Hintergrundfarbe beispielsweise weiß ist, die zu sichtbar machende Fläche Schwarz (der Punkte bzw. das #), und die nicht angehauchte Fläche ein Eisblau, dann gilt folgendes:
(1): Objekt = Eisblau
(2): Objekt = AlphaCalculator(Eisblau).calculate(0, 0, 0, 128)
(3): Objekt = Schwarz
Der Rest ist nur noch Code den du vervollständigen musst.
Wenn du das nicht meinst, musst du das Problem nochmal genauer beschreiben.
Gruß
Verfasst: Mittwoch 5. Mai 2010, 14:49
von majinv
Ich hab mal was zusammengeschrieben, wenn das das ist was du meinst...
ich möchte also den weißen hintergrund wegmalen... um das bild zu sehen...
das ist mein wunschtraum

aller dings, und das ist das was ich meine... ich verändere ja nur die farbe meines malens...
und zeichne nicht "echt" transparent...
Code: Alles auswählen
#!/usr/bin/python
from __future__ import division # Wichtig wenn Python 2 verwendet wird!
import pygame
from pygame.locals import *
class AlphaCalculator(object):
def __init__(self, backr, backg, backb):
self.backr = backr
self.backg = backg
self.backb = backb
def calculate(self, r, g, b, a):
r = (255 - a) / 255 * r + a / 255 * self.backr
g = (255 - a) / 255 * g + a / 255 * self.backg
b = (255 - a) / 255 * b + a / 255 * self.backb
return (int(r), int(g), int(b))
pygame.init()
def testDraw():
#Create window
# window = pygame.display.set_mode((1366, 768), pygame.FULLSCREEN)
window = pygame.display.set_mode((600, 400) )
pygame.display.set_caption('Test Drawing')
screen = pygame.display.get_surface()
background = pygame.Surface(screen.get_size())
background.fill((255,255,255))
_image = pygame.image.load("asd.jpg")# Das Bild welches hinter dem Hintergrund liegt
_image.set_alpha(255)
screen.blit(_image, (0, 0))
screen.blit(background, (0,0))# Weißer Hintergrund, welcher auf dem Bild liegt...
i = 0
while True:
for e in pygame.event.get():
if e.type in (QUIT,KEYDOWN,MOUSEBUTTONDOWN):
return
if pygame.event.get():
sim = AlphaCalculator(255,255,255)
color = sim.calculate(0,0,0,150)
pygame.draw.circle(screen, color, (pygame.mouse.get_pos()), 10, 0)
#Update screen
pygame.display.flip()
i = i + 1
######## MAIN ##########
if __name__ == '__main__':
testDraw()
print "Done."
Re: Eisfläche
Verfasst: Mittwoch 12. Mai 2010, 10:30
von majinv
Vielleicht bin ich ja festgefahren...
aber langsam weiß ich nicht mehr weiter...
hat noch keiner versucht transparent zu zeichnen?
Re: Eisfläche
Verfasst: Mittwoch 12. Mai 2010, 15:33
von Dav1d
Das was du meinst ist nich Transparent zeichen, eher eine Ebene löschen.
Du musst dir bevor du dein Bild "übermalst" an welcher Stelle welche Farbe war, wenn du dann mit deinem "Finger" das Beschlagene weggwischst, musst die die gemerkten Farben wieder Setzten.
Mit einem dict, könnte das funktionieren.
Re: Eisfläche
Verfasst: Mittwoch 19. Mai 2010, 14:16
von majinv
das hab ich auch schon überlegt, aber das müsste ich mit jedem einzelnen pixel machen,
wenn zum beispiel ein bild der hintergrund ist... und ich kann mir nicht vorstellen, dass ich mehrere
"farben" in einem strich hinbekomme... sodass ich einfach nur die eigentilchen pixel nachmale...
gibt es sowas in gtk? dann schreib ich das um... ich muss mich auch damit mal befassen...
Re: Eisfläche
Verfasst: Mittwoch 19. Mai 2010, 16:40
von theliquidwave
Naja. Wieso nimmst du nicht einfach eine XY-Matrix?
Code: Alles auswählen
data = {}
data[0] = {}
data[0][0] = (255, 0, 0) # x:0 y:0
data[0][1] = (255, 0, 22) # x:0 y:1
data[1][0] = (0, 255, 0) # x:1 y:0
# ...
Musst du halt mit einer for-Schleife machen
Gruß
Re: Eisfläche
Verfasst: Samstag 22. Mai 2010, 23:11
von derdon
Chrisber:
Code: Alles auswählen
>>> data = {}
>>> data[0] = {}
>>> data
{0: {}}
>>> data[0][0] = 255, 0, 0
>>> data
{0: {0: (255, 0, 0)}}
>>> data[0][1] = 255, 0, 25
>>> data
{0: {0: (255, 0, 0), 1: (255, 0, 25)}}
>>> data[1][0] = 0, 255, 0
Traceback (most recent call last):
File "<input>", line 1, in <module>
KeyError: 1
Re: Eisfläche
Verfasst: Mittwoch 26. Mai 2010, 09:41
von majinv
@chrisber... ich freu mich, dass sich jmd aktiv mit mir unterhält

.... wollte ich nur mal gesagt haben
hmmm, stellt das data array dann das bild dar, sprich jeden einzelnen pixel?
dann müsste ich das ja vorher auslesen können...noch dazu müsste ich dann
von der position der maus, das jeweilige pixel ableiten können... im fullscreen sicher
noch machbar, aber variabel?
ich glaube nicht... würde das dann nicht auch einen ziemlichen overhead erzeugen?
Re: Eisfläche
Verfasst: Mittwoch 26. Mai 2010, 11:22
von majinv
Du hast mich aber auf eine Idee gebracht und ich hab mal nen prototypen geschrieben...
ich verfolge nun eine andere technik... allerdings ist das kein malen mehr...
sondern eher einfaches "ausblenden" ander jeweiligen stelle... als workaround...
vielleicht fällt da jmd was ein, wie ich es schaffen könnte, dass ich statt des lokalen ausblendens...
eine art zeichnen emulieren kann...?
Code: Alles auswählen
import pygame
screen = pygame.display.set_mode((1000,500))
blueSquare = pygame.Surface((100,100))
blueSquare.fill((0,0,255))
redSquare = pygame.Surface((100,100))
redSquare.fill((255,0,0))
redSquare.set_colorkey((0,0,1))
column = pygame.Surface((20,20))
column.fill((0,0,1))
columnx = 0
columnAdd = 1
myClock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if (event.type == pygame.QUIT or event.type == pygame.KEYDOWN and
event.key == pygame.K_ESCAPE):
running = False
screen.fill((255,255,255))
redSquare.fill((255,0,0))
redSquare.blit(column,(pygame.mouse.get_pos()))
screen.blit(blueSquare,(50,50))
screen.blit(redSquare,(0,0))
pygame.display.flip()
myClock.tick(40)
columnx += columnAdd
if columnx >= 80 or columnx < 0:
columnAdd *= -1
Re: Eisfläche
Verfasst: Mittwoch 2. Juni 2010, 10:01
von majinv
Aloah, falls das Thema von jemandem anderen gesucht wird, mein letzter prototyp...
es ist noch nicht optimal, geht aber in die richtung die ich haben wollte, sollte jemand einen
weg über die drawing methode von pygame finden, das gleiche ziel zu erreichen, wäre ich mehr als
nur begeistert es hier zu lesen...
viele grüße
majin
Code: Alles auswählen
import pygame
screen = pygame.display.set_mode((1000,500))
blueSquare = pygame.Surface((300,300))
blueSquare.fill((0,0,255))
redSquare = pygame.Surface((300,300))
redSquare.fill((255,0,0))
redSquare.set_colorkey((0,0,1))
brush = pygame.Surface((10,10))
brush.fill((0,0,1))
painting = False
running = True
while running:
for event in pygame.event.get():
if (event.type == pygame.QUIT or event.type == pygame.KEYDOWN and
event.key == pygame.K_ESCAPE):
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
painting = True
if event.type == pygame.MOUSEBUTTONUP:
painting = False
if painting:
redSquare.blit(brush,pygame.mouse.get_pos())
screen.fill((255,255,255))
screen.blit(blueSquare,(50,50))
screen.blit(redSquare,(0,0))
pygame.display.flip()