Image noise: Difference between revisions
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}}== |
||
⚫ | |||
⚫ | |||
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](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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
<lang c>#include <stdlib.h>
- include <stdio.h>
- include <time.h>
- 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
<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
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") ) ) )
- Start with 25 frames per second
(imageNoise 320 240 25)</lang>
PureBasic
<lang PureBasic>#filter=0.2 ; Filter parameter for the FPS-calculation
- 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
Python
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
<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>