Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Fernsehrauschen zeichnen? (https://www.delphipraxis.net/69987-fernsehrauschen-zeichnen.html)

StefanG 23. Mai 2006 09:14


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

Beispiel

RavenIV 23. Mai 2006 09:28

Re: Fernsehrauschen zeichnen?
 
Also wenn mein TV keinen Empfang hat, dann zeigt er ein blaues Bild an. :???:

H4ndy 23. Mai 2006 09:35

Re: Fernsehrauschen zeichnen?
 
Zitat:

Zitat von RavenIV
Also wenn mein TV keinen Empfang hat, dann zeigt er ein blaues Bild an. :???:

Sehr produktiver Beitrag ;)

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);

Pinki 23. Mai 2006 09:43

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:

Klaus01 23. Mai 2006 09:49

Re: Fernsehrauschen zeichnen?
 
@Pinki
- randomize solltest Du die Prozedur nicht nennen, die Funktion gibt es schon.

Grüße
Klaus

StefanG 23. Mai 2006 09:55

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.

H4ndy 23. Mai 2006 09:56

Re: Fernsehrauschen zeichnen?
 
Zitat:

Zitat von Klaus01
@Pinki
- randomize solltest Du die Prozedur nicht nennen, die Funktion gibt es schon.

Was man in meinem Quellcode direkt mal bewundern kann ;)

@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)

Klaus01 23. Mai 2006 10:00

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

pacman1986 23. Mai 2006 10:04

Re: Fernsehrauschen zeichnen?
 
@ Handy dein RGBtoColor gibts Schon

Delphi-Quellcode:
Color := RGB(R,G,B);


Delphi-Quellcode:

randomize; //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;
Aufruf dann
Delphi-Quellcode:
Schnee(Image1);

H4ndy 23. Mai 2006 10:08

Re: Fernsehrauschen zeichnen?
 
Zitat:

Zitat von Klaus01
um das alles etwas echter aussehen zu lassen,
kannst Du Dir mal überlegen, das Malen von dem
Schnee in mehrer Threads auszulagern.
[...]
in der Schleife solltest Du noch application.processMessages einbringen
und vielleicht noch ein delay() von einigen millisekunden.

Ich glaub Delay ist da überflüssig, da das Bildrauschen meist sehr schnell ist.
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.

pacman1986 23. Mai 2006 10:14

Re: Fernsehrauschen zeichnen?
 
Zitat:

Zitat von H4ndy
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.

Ich habs Grad nachprogrammiert man merkt schon bei einem kleinen Bild das threads sinnvoll wären.

Zitat:

Zitat von H4ndy
Aso: Du erzeugst übrigends bunten Schnee ;)
Du musst für RGB dreimal den selben Wert benutzen, damit ein Grauwert entsteht.

:thumb: Ich mag Bunten Schnee :mrgreen:

H4ndy 23. Mai 2006 10:18

Re: Fernsehrauschen zeichnen?
 
Zitat:

Zitat von pacman1986
Ich habs Grad nachprogrammiert man merkt schon bei einem kleinen Bild das threads sinnvoll wären.

Gut, dass das direkt mal getestet wurde =)

Zitat:

Zitat von pacman1986
Ich mag Bunten Schnee

Denk dran: Niemals den gelben essen :mrgreen:

pacman1986 23. Mai 2006 10:21

Re: Fernsehrauschen zeichnen?
 
Zitat:

Zitat von H4ndy
Gut, dass das direkt mal getestet wurde =)

:thumb:
Zitat:

Zitat von H4ndy
Denk dran: Niemals den gelben essen :mrgreen:

Warum ? :gruebel:

Vjay 23. Mai 2006 10:23

Re: Fernsehrauschen zeichnen?
 
Zitat:

Zitat von pacman1986
Warum ? :gruebel:

Schonmal deinen Namen in den Schnee geschrieben?

pacman1986 23. Mai 2006 10:25

Re: Fernsehrauschen zeichnen?
 
:idea: :oops:
PS: wers noch net bemerkt hat, OT und ironisch

StefanG 23. Mai 2006 12:58

Re: Fernsehrauschen zeichnen?
 
wie macht man das mit threads?

Mehrere erstellen und von da aus dann jeweils einen Timer erstellen? Oo

Klaus01 23. Mai 2006 13:02

Re: Fernsehrauschen zeichnen?
 
für Threads gibt es ein Tutorial von Luckie, das findest Du hier http://www.michael-puff.de/dirindex....phi/Tutorials/

Grüße
Klaus

Daniel G 23. Mai 2006 13:06

Re: Fernsehrauschen zeichnen?
 
Oder du guckst im "Demos" - Ordner deines Delphi. Da müsste auch 'ne Thread - Demo drinne sein.

StefanG 23. Mai 2006 14:40

Re: Fernsehrauschen zeichnen?
 
Ok ich habs mal probiert so testweise.

Wenn ich folgendes mache (ohne Threads) :

Delphi-Quellcode:
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;
Ich starte das Programm, und wenn die Form erscheint, dann ist bereits das fertig gezeichnete Bild zu sehen.
Wenn ich jetzt aber ein Thread-Object erstelle :

Delphi-Quellcode:
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;
und dieses dann erzeuge mit :

Delphi-Quellcode:
tsnow.Create(Image);
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....
Mache ich was falsch?

H4ndy 23. Mai 2006 14:47

Re: Fernsehrauschen zeichnen?
 
Delphi-Quellcode:
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;
Solltest du besser so schreiben:
Delphi-Quellcode:
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;
Sonst wird Application.ProcessMessages bei jedem (!) Pixel ausgeführt,
was der Geschwindigkeit nicht gerade zuträglich ist ;)

Und wenn du ein Rauschen haben willst solltest du ins Execute schreiben:
Delphi-Quellcode:
while not Terminated do begin
  Snow(FImage);
end;
Dadurch wird Show() solange ausgeführt, bis du deinen Tread beendest/zerstörst.
(Thread.Terminate)

Klaus01 23. Mai 2006 14:55

Re: Fernsehrauschen zeichnen?
 
Delphi-Quellcode:
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;
und nicht vergessen, die Threads irgendwann zu beenden und freizugeben.

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

H4ndy 23. Mai 2006 15:02

Re: Fernsehrauschen zeichnen?
 
Zitat:

Zitat von Klaus01
[...]in Deinem Quellcode zeichnest Du zeilenweise Deine Punkt und nicht zufällig
auf das Image

Was ja nicht stört, da ein zufälliger Farbwert für jeden Punkt benutzt wird, was ebenfalls für ein Rauschen sorgt.

StefanG 23. Mai 2006 15:04

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.

heiopei 23. Mai 2006 15:06

Re: Fernsehrauschen zeichnen?
 
hallo,
wäre es nicht besser, statt der direkten Zuweisung der Pixelfarbe

Delphi-Quellcode:
Img.Canvas.Pixels[i,j] := RGB(random(256),random(256),random(256));
die viel schnellere Variante mit Scanline zu verwenden?

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

H4ndy 23. Mai 2006 15:13

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".

heiopei 23. Mai 2006 15:22

Re: Fernsehrauschen zeichnen?
 
aber das würde doch sein problem lösen, dass die anzeige so lange dauert, oder nicht?!?

StefanG 23. Mai 2006 15:25

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.

H4ndy 23. Mai 2006 15:30

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.

StefanG 23. Mai 2006 15:44

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

Klaus01 23. Mai 2006 15:53

Re: Fernsehrauschen zeichnen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
wollte Euch mal meine Lösung zeigen, schreibt direkt auf die Form.

Delphi-Quellcode:
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.
lustiger wird es wenn man nicht nur von einem Pixel die Farbe ändert
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