![]() |
Fernsehrauschen zeichnen?
Hi,
kann mir jemand sagen, wie man den "TV - Schnee" selber machen kann? Damit meine ich das Bild, was ein Fernseher anzeigt, wenn man keinen Empfang hat. Also einfach ne Menge von weißen/schwarzen Punkten, die ständig die Position ändern ![]() |
Re: Fernsehrauschen zeichnen?
Also wenn mein TV keinen Empfang hat, dann zeigt er ein blaues Bild an. :???:
|
Re: Fernsehrauschen zeichnen?
Zitat:
Also Ich würde einfach die Zeichenfläche Pixel für Pixel durchlaufen und einen zufälligen Grauwert dort zeichnen.
Delphi-Quellcode:
...
Randomize; // *einmalig* im Programm aufrufen, z.B. im FormCreate ... // Hilfsfunktion function RGBToColor(R, G, B : byte): TColor; begin Result := ((R and $FF) shl 16) + ((G and $FF) shl 8) + (B and $FF); end; ... // Zufälligen Grauwert erzeugen var Farbe: TColor; r,g,b: integer; begin r := Random(256); g := r; b := r; Farbe := RGBToColor(r,g,b); |
Re: Fernsehrauschen zeichnen?
Setze den Bildschirmbereich fest z.b. 200 X 200
[delphi]Procedure Randomize; begin end; dann packst du in deiner procedure BkColor erstmal auf Black und dann for i:=1 to beliebig do //(je mehr desto mehr Schnee) Image1.Canvas.Pixels[(Random(200),Random(200)]:=clWhite end; Viel Spass :bounce1: |
Re: Fernsehrauschen zeichnen?
@Pinki
- randomize solltest Du die Prozedur nicht nennen, die Funktion gibt es schon. Grüße Klaus |
Re: Fernsehrauschen zeichnen?
danke schonmal, das "Bild" bekomme ich nun hin, aber es sollte sich auch ständig bewegen...wie beim tv halt
hab versucht, einfach aus dem FOR nen while true do zu machen, aber da wird die form garnicht erst angezeigt. |
Re: Fernsehrauschen zeichnen?
Zitat:
@Pinki: Ich feinde deine Version nicht ganz so toll, da dabei viele Freiräume entstehen können. Außerdem machst du nur Schwarz-Weiss-Gekriesel, welches zusätzlich noch irgendwann alles Weiss gefärbt hat. @Stefan: Pack den Quellcode - meinen oder Pinkis - in einen Timer. (Sollte es nicht neu gezeichnet werden, einfach noch ein Application.ProcessMessages; anhängen) |
Re: Fernsehrauschen zeichnen?
um das alles etwas echter aussehen zu lassen,
kannst Du Dir mal überlegen, das Malen von dem Schnee in mehrer Threads auszulagern. Wenn ein weißer Punkt gemalt wurde, muss er nach eniger Zeit auch wieder entfernt werden. Ansonsten hast Du nach einer gewissen Zeit Dein Bild weiß. zum while true do in der Schleife solltest Du noch application.processMessages einbringen und vielleicht noch ein delay() von einigen millisekunden. delay findest Du in der Codelib. Grüße Klaus |
Re: Fernsehrauschen zeichnen?
@ Handy dein RGBtoColor gibts Schon
Delphi-Quellcode:
Color := RGB(R,G,B);
Delphi-Quellcode:
Aufruf dannrandomize; //Wie oben schon gesagt einmal aufrufen ... procedure Schnee(Img : TImage); var i,j:integer; begin For i := 1 to Img.Width do For j := 1 to Img.height do begin Img.Canvas.Pixels[i,j] := RGB(random(256),random(256),random(256)); application.ProcessMessages end; end;
Delphi-Quellcode:
Schnee(Image1);
|
Re: Fernsehrauschen zeichnen?
Zitat:
Threads sind glaub ich auch direkt mal Spatzen mit Kanonen abschießen ;) Höstens einer würde hier passen, damit das Hauptprogramm nicht vom Zeichenvorgang ausgebremst wird. @pacman1986: Ich glaub ich hatte RGB() schonmal benutzt, war mir aber nicht mehr sicher. Deshalb hab ich fix mal einen Ersatz dafür gesucht ^^ Aso: Du erzeugst übrigends bunten Schnee ;) Du musst für RGB dreimal den selben Wert benutzen, damit ein Grauwert entsteht. |
Re: Fernsehrauschen zeichnen?
Zitat:
Zitat:
|
Re: Fernsehrauschen zeichnen?
Zitat:
Zitat:
|
Re: Fernsehrauschen zeichnen?
Zitat:
Zitat:
|
Re: Fernsehrauschen zeichnen?
Zitat:
|
Re: Fernsehrauschen zeichnen?
:idea: :oops:
PS: wers noch net bemerkt hat, OT und ironisch |
Re: Fernsehrauschen zeichnen?
wie macht man das mit threads?
Mehrere erstellen und von da aus dann jeweils einen Timer erstellen? Oo |
Re: Fernsehrauschen zeichnen?
für Threads gibt es ein Tutorial von Luckie, das findest Du hier
![]() Grüße Klaus |
Re: Fernsehrauschen zeichnen?
Oder du guckst im "Demos" - Ordner deines Delphi. Da müsste auch 'ne Thread - Demo drinne sein.
|
Re: Fernsehrauschen zeichnen?
Ok ich habs mal probiert so testweise.
Wenn ich folgendes mache (ohne Threads) :
Delphi-Quellcode:
Ich starte das Programm, und wenn die Form erscheint, dann ist bereits das fertig gezeichnete Bild zu sehen.
procedure TForm1.Snow(image: Timage);
var i,j,r:integer; begin For i := 1 to Image.Width do For j := 1 to Image.height do begin r := random(256); Image.Canvas.Pixels[i,j] := RGB(r,r,r); application.ProcessMessages; end; end; procedure TForm1.FormCreate(Sender: TObject); begin Randomize; Snow(Image); end; Wenn ich jetzt aber ein Thread-Object erstelle :
Delphi-Quellcode:
und dieses dann erzeuge mit :
constructor Tsnow.Create(image: TImage);
begin FImage := image; inherited Create(False); end; procedure Tsnow.Execute; begin Snow(FImage); end; procedure Tsnow.SetPixels; var r : Integer; begin r := Random(256); FImage.Canvas.Pixels[FX,FY] := RGB(r,r,r) end; procedure Tsnow.Snow(image: Timage); var i,j:integer; begin For i := 1 to FImage.Width do For j := 1 to FImage.height do begin FX := i; FY := j; Synchronize(SetPixels); application.ProcessMessages end; end;
Delphi-Quellcode:
dann kann ich schön zugucken, wie Linie für Linie gezeichnet wird und es dauert etwa 20 Sekunden bis das Image gefüllt ist....
tsnow.Create(Image);
Mache ich was falsch? |
Re: Fernsehrauschen zeichnen?
Delphi-Quellcode:
Solltest du besser so schreiben:
For i := 1 to FImage.Width do
For j := 1 to FImage.height do begin FX := i; FY := j; Synchronize(SetPixels); application.ProcessMessages end; end;
Delphi-Quellcode:
Sonst wird Application.ProcessMessages bei jedem (!) Pixel ausgeführt,
For i := 1 to FImage.Width do
For j := 1 to FImage.height do begin FX := i; FY := j; Synchronize(SetPixels); end; end; application.ProcessMessages; was der Geschwindigkeit nicht gerade zuträglich ist ;) Und wenn du ein Rauschen haben willst solltest du ins Execute schreiben:
Delphi-Quellcode:
Dadurch wird Show() solange ausgeführt, bis du deinen Tread beendest/zerstörst.
while not Terminated do begin
Snow(FImage); end; (Thread.Terminate) |
Re: Fernsehrauschen zeichnen?
Delphi-Quellcode:
und nicht vergessen, die Threads irgendwann zu beenden und freizugeben.
constructor Tsnow.Create(image: TImage);
begin FImage := image; inherited Create(False); end; procedure Tsnow.Execute; begin while true do begin synchronize(setPixels); end; end; procedure Tsnow.SetPixels; var r : Integer; x,y:Integer; begin r := Random(256); x:=random(FImage.width); y:=random(FImage.height); FImage.Canvas.Pixels[x,y] := RGB(r,r,r) end; im Hauptprogramm: var snow1,snow2 : TSnow; begin snow1 := TSnow.create(image1); snow2 := TSnow.create(image1); end; in Deinem Quellcode zeichnest Du zeilenweise Deine Punkt und nicht zufällig auf das Image. Mußt mal schauen, ob der obige Code geht habe ich nicht ausgetestet. Grüße Klaus |
Re: Fernsehrauschen zeichnen?
Zitat:
|
Re: Fernsehrauschen zeichnen?
Liste der Anhänge anzeigen (Anzahl: 1)
danke für den Tipp, klingt ja auch einleuchtend, aber irgendwas stimmt nicht.
Erst hab ich das Application.ProcessMessages nach unten gesetzt, was der Geschwindigkeit aber nichts gebracht hat, beim ersten durchlauf konnte ich schön zugucken, wie das Weiss von Grauton-Punkten überzogen wird. Dann hab ich die Zeile komplett rausgenommen. Jetzt geht der erste Durchgang so fix, dass ich die "Bewegung" nichtmehr sehen kann, d.h. ich starte das Programm und das image erscheint schon gefüllt mit Punkten. Allerdings ist das nur beim ersten Durchlauf der Fall . Ich hab mal das Projekt angehängt. vielleicht guckt sich das mal jemand an, wenn er Zeit hat. |
Re: Fernsehrauschen zeichnen?
hallo,
wäre es nicht besser, statt der direkten Zuweisung der Pixelfarbe
Delphi-Quellcode:
die viel schnellere Variante mit Scanline zu verwenden?
Img.Canvas.Pixels[i,j] := RGB(random(256),random(256),random(256));
wie man jetzt Scanline anwendet weiss ich auch nicht mehr so genau, aber man braucht nur noch eine Variable, welche die Zeile beschreibt und die Spalten werden durch erhöhen des Pointer bestimmt. d.h. man müsste nur noch einen Pointer zuwesein, der den Farbcode (bzw. schwarz oder weiss) enthält. nur mal son gedanke, mfg heiopei |
Re: Fernsehrauschen zeichnen?
Könnte man schon, das fällt dann aber erstmal unter "Optimierungsmöglichkeiten" ;)
Es ging ja erstmal primär ums "wie überhaupt". |
Re: Fernsehrauschen zeichnen?
aber das würde doch sein problem lösen, dass die anzeige so lange dauert, oder nicht?!?
|
Re: Fernsehrauschen zeichnen?
es muss doch aber woanders dran liegen, denn ohne thread geht das ganze 1000 mal schneller, als jetzt so
bei ner kleinen größe von z.b. 200x200 , wo ich einfach alle 10 ms durch nen Timer die Snow funktion aufgerufen habe, sieht das ganze sogar Original so aus wie im TV.....nur im Thread dauerts auf der gleichen Größe viel länger. |
Re: Fernsehrauschen zeichnen?
Ich schätze mal das Synchronize schluckt viel Zeit.
Ich glaube sogar, dass da immer das Image neugezeichnet wird. Versuchs mal mit einem TBitmap im Thread, welches du nach dem komplette be-zeichnen einfach auf das Image kopierst. |
Re: Fernsehrauschen zeichnen?
jau, das funktioniert um einiges schneller, vielen Dank.
Für den vollbildmodus auf 1280 x 1024 reicht dann wohl allgemein die Performance nicht. da kommt nach ner Zeit immer OutOfResources. Aber wenn mans etwas kleiner macht, dann gehts ab wie schmidts Katze |
Re: Fernsehrauschen zeichnen?
Liste der Anhänge anzeigen (Anzahl: 1)
wollte Euch mal meine Lösung zeigen, schreibt direkt auf die Form.
Delphi-Quellcode:
lustiger wird es wenn man nicht nur von einem Pixel die Farbe ändert
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type TForm1 = class(TForm) procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end; TSnow = class(TThread) private procedure setPixel; protected procedure execute; override; end; var Form1: TForm1; snow1,snow2: TSnow; implementation {$R *.dfm} procedure TSnow.setPixel; var x,y : Integer; r,g,b: Byte; begin x := random(Form1.Width); y := random(Form1.Height); r := random(256); g := random(256); b := random(256); Form1.Canvas.Pixels[x,y]:=RGB(r,g,b); end; procedure TSnow.execute; begin while not terminated do begin synchronize(setPixel); end; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin snow1.Terminate; snow2.Terminate; snow1.Free; snow2.Free; end; begin randomize; snow1 := TSnow.create(false); snow2 := TSnow.Create(false); end. sonder von [x-1,y], [x,y], [x+1,y], [x,y-1], [x,y], [x,y+2] Grüße Klaus |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz