Image noise: Difference between revisions

From Rosetta Code
Content added Content deleted
m (moved Image Noise to Image noise: capitalization policy)
m (whitespace)
Line 4: Line 4:


[[Image:NoiseOutput.png]]
[[Image:NoiseOutput.png]]



=={{header|C}}==
=={{header|C}}==

{{trans|OCaml}}
{{trans|OCaml}}
{{libheader|SDL}}
{{libheader|SDL}}
Line 178: Line 176:
}
}
}</lang>
}</lang>



=={{header|D}}==
=={{header|D}}==

{{trans|C}}
{{trans|C}}
<lang D>import std.stdio, std.random, sdl.SDL;
<lang D>import std.stdio, std.random, sdl.SDL;
Line 212: Line 208:


=={{header|Factor}}==
=={{header|Factor}}==
<!-- Still learning Factor, my code may suck, please fix. -->

Still learning Factor, my code may suck, please fix.

By some reason, FPS does not show during execution on Linux.
By some reason, FPS does not show during execution on Linux.



Max 2 FPS on Factor 0.94 x86-64/Windows 7 64-bits - Athlon II X4 620 - ATI Radeon X1200.
Max 2 FPS on Factor 0.94 x86-64/Windows 7 64-bits - Athlon II X4 620 - ATI Radeon X1200.
Line 275: Line 268:


=={{header|J}}==
=={{header|J}}==

<lang j>coclass'example'
<lang j>coclass'example'
(coinsert[require)'jzopengl'
(coinsert[require)'jzopengl'
Line 332: Line 324:


=={{header|Javascript}}==
=={{header|Javascript}}==
<lang javascript>
<lang javascript><body>
<body>
<canvas id='c'></canvas>
<canvas id='c'></canvas>
<script>
<script>
Line 372: Line 363:
animate();
animate();
</script>
</script>
</body>
</body></lang>
</lang>


=={{header|OCaml}}==
=={{header|OCaml}}==
{{libheader|OCamlSDL}}
{{libheader|OCamlSDL}}

with the [[OCamlSDL|ocaml-sdl]] bindings:
with the [[OCamlSDL|ocaml-sdl]] bindings:
<lang ocaml>let frames =
<lang ocaml>let frames =
Line 483: Line 472:


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
This solution works on ErsatzLisp, the Java version of PicoLisp. It creates a
This solution works on ErsatzLisp, the Java version of PicoLisp. It creates a 'JFrame' window, and calls inlined Java code to handle the image.
'JFrame' window, and calls inlined Java code to handle the image.
<lang PicoLisp>(javac "ImageNoise" "JPanel" NIL
<lang PicoLisp>(javac "ImageNoise" "JPanel" NIL
"java.util.*"
"java.util.*"
Line 572: Line 560:
=={{header|Python}}==
=={{header|Python}}==
{{libheader|Tkinter}}
{{libheader|Tkinter}}

{{libheader|PIL}}
{{libheader|PIL}}

Max 23 FPS on Python 2.7 (r27:82525 MSC v.1500 32 bit Intel), Windows 7 64-bit on Athlon II X4 620 - ATI Radeon X1200.
Max 23 FPS on Python 2.7 (r27:82525 MSC v.1500 32 bit Intel), Windows 7 64-bit on Athlon II X4 620 - ATI Radeon X1200.


Line 625: Line 611:
=={{header|Tcl}}==
=={{header|Tcl}}==
{{libheader|Tk}}
{{libheader|Tk}}

<lang tcl>package require Tk
<lang tcl>package require Tk



Revision as of 14:45, 29 November 2010

Task
Image noise
You are encouraged to solve this task according to the task description, using any language you may know.

Generate a random black and white 320x240 image continuously, showing FPS (frames per second).

Sample image:

C

Translation of: OCaml
Library: SDL

<lang c>#include <stdlib.h>

  1. include <stdio.h>
  2. include <time.h>
  3. include <SDL/SDL.h>

unsigned int frames = 0; unsigned int t_acc = 0;

void print_fps () {

 static Uint32 last_t = 0;
 Uint32 t = SDL_GetTicks();
 Uint32 dt = t - last_t;
 t_acc += dt;
 if (t_acc > 1000)
 {
   unsigned int el_time = t_acc / 1000;
   printf("- fps: %g\n",
           (float) frames / (float) el_time);
   t_acc = 0;
   frames = 0;
 }
 last_t = t;

}

void blit_noise(SDL_Surface *surf) {

 unsigned int i;
 long dim = surf->w * surf->h;
 while (1)
 {
   SDL_LockSurface(surf);
   for (i=0; i < dim; ++i) {
     ((unsigned char *)surf->pixels)[i] = ((rand() & 1) ? 255 : 0);
   }
   SDL_UnlockSurface(surf);
   SDL_Flip(surf);
   ++frames;
   print_fps();
 }

}

int main(void) {

 SDL_Surface *surf = NULL;
 srand((unsigned int)time(NULL));
 SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
 surf = SDL_SetVideoMode(320, 240, 8, SDL_DOUBLEBUF | SDL_HWSURFACE);
 blit_noise(surf);

}</lang>

C#

Max 185 FPS on .NET 4.0/Windows 7 64-bit on Athlon II X4 620 - ATI Radeon X1200.

<lang csharp>using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Runtime.InteropServices; using System.Windows.Forms;

class Program {

   static Size size = new Size(320, 240);
   static Rectangle rectsize = new Rectangle(new Point(0, 0), size);
   static int numpixels = size.Width * size.Height;
   static int numbytes = numpixels * 3;
   static PictureBox pb;
   static BackgroundWorker worker;
   static double time = 0;
   static double frames = 0;
   static Random rand = new Random();
   static byte tmp;
   static byte white = 255;
   static byte black = 0;
   static int halfmax = int.MaxValue / 2; // more voodoo! calling Next() is faster than Next(2)!
   static IEnumerable<byte> YieldVodoo()
   {
       // Yield 3 times same number (i.e 255 255 255) for numpixels times. 
       for (int i = 0; i < numpixels; i++)
       {
           tmp = rand.Next() < halfmax ? black : white; // no more lists!  
           // no more loops! yield! yield! yield!
           yield return tmp;
           yield return tmp;
           yield return tmp;
       }
   }
   static Image Randimg()
   {
       // Low-level bitmaps  
       var bitmap = new Bitmap(size.Width, size.Height);
       var data = bitmap.LockBits(rectsize, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
       Marshal.Copy(
           YieldVodoo().ToArray<byte>(),// source
           0, // start
           data.Scan0, // scan0 is a pointer to low-level bitmap data
           numbytes); // number of bytes in source
       bitmap.UnlockBits(data);
       return bitmap;
   }
   [STAThread]
   static void Main()
   {
       var form = new Form();
       form.AutoSize = true;
       form.Size = new Size(0, 0);
       form.Text = "Test";
       form.FormClosed += delegate
       {
           Application.Exit();
       };
       worker = new BackgroundWorker();
       worker.DoWork += delegate
       {
           System.Threading.Thread.Sleep(500); // remove try/catch, just wait a bit before looping
           while (true)
           {
               var a = DateTime.Now;
               pb.Image = Randimg();
               var b = DateTime.Now;
               time += (b - a).TotalSeconds;
               frames += 1;
               if (frames == 30)
               {
                   Console.WriteLine("{0} frames in {1:0.000} seconds. ({2:0} FPS)", frames, time, frames / time);
                   time = 0;
                   frames = 0;
               }
           }
       };
       worker.RunWorkerAsync();
       FlowLayoutPanel flp = new FlowLayoutPanel();
       form.Controls.Add(flp);
       pb = new PictureBox();
       pb.Size = size;
       flp.AutoSize = true;
       flp.Controls.Add(pb);
       form.Show();
       Application.Run();
   }

}</lang>

D

Translation of: C

<lang D>import std.stdio, std.random, sdl.SDL;

void main() {

 SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
 auto surface = SDL_SetVideoMode(320,240,8, SDL_DOUBLEBUF|SDL_HWSURFACE);
 uint frameNumber, totalTime, lastTime;
 while (true) {
   SDL_LockSurface(surface);
   foreach (i; 0 .. surface.w * surface.h)
     (cast(ubyte*)surface.pixels)[i] = (uniform(0, 2) ? 255 : 0);
   SDL_UnlockSurface(surface);
   SDL_Flip(surface);
   frameNumber++;
   uint time = SDL_GetTicks();
   totalTime += time - lastTime;
   if (totalTime > 1000) {
     writeln("FPS: ", frameNumber / (totalTime / 1000.0));
     totalTime = frameNumber = 0;
   }
   lastTime = time;
 }

}</lang> This D version shows about 155 FPS, while on the same PC the C version shows about 180 FPS.

Generating random bits with the C core.stdc.stdlib.rand the performance becomes about the same of the C version.

Factor

By some reason, FPS does not show during execution on Linux.

Max 2 FPS on Factor 0.94 x86-64/Windows 7 64-bits - Athlon II X4 620 - ATI Radeon X1200.

<lang factor>USING: namespaces ui ui.gadgets ui.gadgets.buttons ui.gadgets.tracks ui.gadgets.borders images images.viewer models timers accessors kernel sequences sequences.deep byte-vectors random calendar io math math.functions math.parser prettyprint debugger system ; FROM: models => change-model ;

IN: imagenoise

TUPLE: imgmodel < model content ; SYMBOL: dispimg SYMBOL: num SYMBOL: ttime

randimg ( -- img )
<image>
 { 320 240 } >>dim
 RGB >>component-order
 ubyte-components >>component-type
 dup dim>> product
 [ { 255 0 } random 3 swap <repetition> ] replicate flatten >byte-vector >>bitmap ;

randimg imgmodel new-model dispimg set-global 0 num set-global 0 ttime set-global

[

 now
 dispimg get-global
 [ drop randimg ] change-model
 num get-global 1 +
 num set-global

 now swap time- duration>seconds
 ttime get-global +  
 ttime set-global
 
 num get-global 10 <= 
  [ ]
  [
   num get-global 
   ttime get-global 
   [ / round number>string " FPS" append ] try print
   0 num set-global
   0 ttime set-global ] if  

] 1 nanoseconds every

[ vertical <track>

dispimg get-global <image-control> { 5 5 } <border> f track-add  
 
"Test" open-window

] with-ui</lang>

J

<lang j>coclass'example' (coinsert[require)'jzopengl'

P=: 0 : 0 pc p nosize; xywh 0 0 160 120;cc c isigraph opengl; pas 0 0;pcenter; rem form end;

pshow;
timer 1;

)

timestamp=: (6!:8) %~ 6!:9

create=:3 :0

 ogl=:conew'jzopengl'
 frames=:0
 start=: timestamp
 sys_timer_base_=: 1 :('p_c_paint_',(;coname),'_')
 wd P

)

p_run=: 3 : 0

 conew'example'

)

destroy=:3 :0

 end=:timestamp
 smoutput 'frames per second: ',":frames%end-start
 wd 'timer 0'
 destroy__ogl
 wd'pclose'
 codestroy

)

p_close=: destroy

p_c_paint=: 3 : 0

 rc__ogl
 glClear GL_COLOR_BUFFER_BIT
 glBegin GL_POINTS
   glVertex _1+2*53050 2?@$ 0
 glEnd
 show__ogl
 frames=:frames+1

)

p_run</lang>

The script auto-starts when run (that last line p_run'' is responsible for the auto-start.

Average FPS are displayed when the window is closed.

With this revision, on my laptop, I typically get in the range of 58..59 FPS, with a cpu load from J of about 3% (sometimes as much as 5%, sometimes as low as 0.1%). I am probably limited by v-sync, and (hypothetically speaking) if I tuned my opengl drivers I perhaps could get significantly faster fps. However, since my screen only refreshes approximately 60 times per second, anything over that would be meaningless.

JavaScript

<lang javascript><body>

 <canvas id='c'></canvas>
 <script>

var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d');

var w = canvas.width = 320; var h = canvas.height = 240; var t1 = new Date().getTime(); var frame_count = 0; ctx.font = 'normal 400 24px/2 Unknown Font, sans-serif'; var img = ctx.createImageData(w,h);

function animate() {

   for (var x = 0; x < w; x++)
   {
       for (var y = 0; y < h; y++)
       {
           var index = 4* (x + w*y);
           var value = (Math.random() > 0.5) ? 255 : 0;
           img.data[index] = value;
           img.data[index+1] = value;
           img.data[index+2] = value;
           img.data[index+3] = 255;
       }
   }
   
   ctx.putImageData(img,0,0);
   frame_count++;
   var fps = frame_count / (new Date().getTime() - t1) * 1000;
   ctx.fillStyle = "red";
   ctx.fillText(fps.toFixed(2) + " fps", 20, 40);
   setTimeout(animate, 0);

}

animate();

 </script>

</body></lang>

OCaml

Library: OCamlSDL

with the ocaml-sdl bindings: <lang ocaml>let frames =

 { contents = 0 }

let t_acc =

 { contents = 0 }

let last_t =

 { contents = Sdltimer.get_ticks () }

let print_fps () =

 let t = Sdltimer.get_ticks () in
 let dt = t - !last_t in
 t_acc := !t_acc + dt;
 if !t_acc > 1000 then begin
   let el_time = !t_acc / 1000 in
   Printf.printf
     "- fps: %g\n%!"
     (float !frames /. float el_time);
   t_acc := 0;
   frames := 0;
 end;
 last_t := t

let blit_noise surf =

 let ba = Sdlvideo.pixel_data_8 surf in
 let dim = Bigarray.Array1.dim ba in
 let rec aux () =
   for i = 0 to pred dim do
     ba.{i} <- if Random.bool () then max_int else 0
   done;
   Sdlvideo.flip surf;
   incr frames;
   print_fps ();
   aux ()
 in
 aux ()

let blit_noise surf =

 try blit_noise surf
 with _ -> Sdl.quit ()

let () =

 Sdl.init [`VIDEO; `TIMER];
 Random.self_init();
 let surf =
   Sdlvideo.set_video_mode
     ~w:320 ~h:240 ~bpp:8
     [(*`HWSURFACE;*) `DOUBLEBUF]
 in
 Sys.catch_break true;
 blit_noise surf</lang>

compile to native-code with:

ocamlopt bigarray.cmxa -I +sdl sdl.cmxa noise_fps_sdl.ml -o noise_fps_sdl.opt

or using findlib:

ocamlfind opt -linkpkg -package sdl noise_fps_sdl.ml
./a.out

compile to bytecode with:

ocamlc bigarray.cma -I +sdl sdl.cma noise_fps_sdl.ml -o noise_fps_sdl.byte

In script mode, run with:

ocaml bigarray.cma -I +sdl sdl.cma noise_fps_sdl.ml

In a more idiomatic way, using the modules Graphics and Unix from the standard OCaml library: <lang ocaml>open Graphics

let white = (rgb 255 255 255) let black = (rgb 0 0 0)

let t_last = ref (Unix.gettimeofday())

let () =

 open_graph "";
 let width = 320
 and height = 240 in
 resize_window width height;
 try 
   while true do
     for y = 0 to pred height do
       for x = 0 to pred width do
         set_color (if Random.bool() then white else black);
         plot x y
       done;
     done;
     let t = Unix.gettimeofday() in
     Printf.printf "- fps: %f\n" (1.0 /. (t -. !t_last));
     t_last := t
   done
 with _ ->
   flush stdout;
   close_graph ()</lang>

run this script with:

ocaml unix.cma graphics.cma g.ml

And using an OCaml-Xlib bindings, or an OCaml-Allegro binding.

PicoLisp

This solution works on ErsatzLisp, the Java version of PicoLisp. It creates a 'JFrame' window, and calls inlined Java code to handle the image. <lang PicoLisp>(javac "ImageNoise" "JPanel" NIL

     "java.util.*"
     "java.awt.*" "java.awt.image.*" "javax.swing.*" )
  int DX, DY;
  int[] Pixels;
  MemoryImageSource Source;
  Image Img;
  Random Rnd;
  public ImageNoise(int dx, int dy) {
     DX = dx;
     DY = dy;
     Pixels = new int[DX * DY];
     Source = new MemoryImageSource(DX, DY, Pixels, 0, DX);
     Source.setAnimated(true);
     Img = createImage(Source);
     Rnd = new Random();
  }
  public void paint(Graphics g) {update(g);}
  public void update(Graphics g) {g.drawImage(Img, 0, 0, this);}
  public void draw() {
     for (int i = 0; i < Pixels.length; ++i) {
        int c = Rnd.nextInt(255);
        Pixels[i] = 0xFF000000 | c<<16 | c<<8 | c;
     }
     Source.newPixels();
     paint(getGraphics());
  }

/**/

(de imageNoise (DX DY Fps)

  (let
     (Frame (java "javax.swing.JFrame" T "Image Noise")
        Noise (java "ImageNoise" T DX DY) )
     (java Frame "add" Noise)
     (java Frame "setSize" DX DY)
     (java Frame "setVisible" T)
     (task (/ -1000 Fps) 0
        Image Noise
        (java Image "draw") ) ) )
  1. Start with 25 frames per second

(imageNoise 320 240 25)</lang>

PureBasic

<lang PureBasic>#filter=0.2  ; Filter parameter for the FPS-calculation

  1. UpdateFreq=100  ; How often to update the FPS-display

OpenWindow(0,400,300,320,240,"PureBasic") Define w=WindowWidth(0), h=WindowHeight(0) Define x, y, T, TOld, FloatingMedium.f, cnt InitSprite() OpenWindowedScreen(WindowID(0),0,0,w,h,1,0,0,#PB_Screen_NoSynchronization) Repeat

 StartDrawing(ScreenOutput())
 For y=0 To h-1
   For x=0 To w-1
     If Random(1)
       Plot(x,y,#Black)
     Else
       Plot(x,y,#White)
     EndIf
   Next
 Next
 StopDrawing()
 FlipBuffers()
 cnt+1
 If cnt>=#UpdateFreq
   cnt =0
   TOld=T
   T   =ElapsedMilliseconds()
   FloatingMedium*(1-#filter)+1000*#filter/(T-TOld)
   SetWindowTitle(0,"PureBasic: "+StrF(#UpdateFreq*FloatingMedium,2)+" FPS")
   Repeat ; Handle all events
     Event=WindowEvent()
     If Event=#PB_Event_CloseWindow
       End
     EndIf
   Until Not Event
 EndIf

ForEver</lang>

Python

Library: Tkinter
Library: PIL

Max 23 FPS on Python 2.7 (r27:82525 MSC v.1500 32 bit Intel), Windows 7 64-bit on Athlon II X4 620 - ATI Radeon X1200.

<lang python>import Tkinter import Image, ImageTk import random import time

size = (320,240) pixels = size[0] * size[1]

class App():

   def __init__(self, root):  
       self.root = root
       self.root.title("Test")
       
       self.img = Image.new("RGB",size)        
       self.label = Tkinter.Label(root)
       self.label.pack()
       self.time = 0.0
       self.frames = 0        
       self.loop() 
   def loop(self):
       self.ta = time.time()
       # 13 FPS boost. half integer idea from C#.
       self.img.putdata([(255,255,255) if random.random() > 0.5 else (0,0,0) for i in range(pixels)])
       self.pimg = ImageTk.PhotoImage(self.img)
       self.label["image"] = self.pimg        
       self.tb = time.time()
       
       self.time += (self.tb - self.ta)
       self.frames += 1
       if self.frames == 30:
           try:
               self.fps = self.frames / self.time
           except:
               self.fps = "INSTANT"
           print "%d frames in %3.2f seconds (%s FPS)" % (self.frames, self.time, self.fps)
           self.time = 0
           self.frames = 0
     
       self.root.after(1, self.loop)

root = Tkinter.Tk() app = App(root) root.mainloop()</lang>

Tcl

Library: Tk

<lang tcl>package require Tk

proc generate {img width height} {

   set data {}
   for {set i 0} {$i<$height} {incr i} {

set line {} for {set j 0} {$j<$width} {incr j} { lappend line [lindex "#000000 #FFFFFF" [expr {rand() < 0.5}]] } lappend data $line

   }
   $img put $data

}

set time 0.0 set count 0

proc looper {} {

   global time count
   set t [lindex [time {generate noise 320 240}] 0]
   set time [expr {$time + $t}]
   if {[incr count] >= 30} {

set time [expr {$time / 1000000.0}] set fps [expr {$count / $time}] puts [format "%d frames in %3.2f seconds (%f FPS)" $count $time $fps] set time 0.0 set count 0

   }
   after 1 looper

}

image create photo noise -width 320 -height 240 pack [label .l -image noise] update looper</lang>