Image noise: Difference between revisions
m (→{{header|PureBasic}}: Increased FPS by running without synchronization) |
m (→{{header|PureBasic}}: improved readability) |
||
Line 257:
OpenWindowedScreen(WindowID(0),0,0,w,h,1,0,0,#PB_Screen_NoSynchronization)
Repeat
StartDrawing(ScreenOutput())
For y=0 To h-1
Line 272 ⟶ 271:
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
|
Revision as of 07:59, 2 October 2010
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#
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>
Factor
Still learning Factor, my code may suck, please fix.
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 100;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*?16000 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.
Frames will be updated no more often than once every millisecond, to allow for window events to be processed, though this is a relatively minor effect on my laptop.
FPS would probably be improved if I moved the camera so that I could eliminate the _1+2* from the noise generation line.
With this revision, on my laptop, I typically get in the range of 55..60 FPS.
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 ( 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
Please add FPS info.
<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>