Task: Image noise



C#: 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; 

    static IEnumerable<byte> YieldVodoo()
    {
        

        for (int i = 0; i < numpixels; i++)
        {
            tmp = rand.Next() < halfmax ? black : white; 

            
            yield return tmp;
            yield return tmp;
            yield return tmp;
        }
    }

    static Image Randimg()
    {
        
        var bitmap = new Bitmap(size.Width, size.Height);
        var data = bitmap.LockBits(rectsize, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

        Marshal.Copy(
            YieldVodoo().ToArray<byte>(),
            0, 
            data.Scan0, 
            numbytes); 

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

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


Go: package main

import (
    "code.google.com/p/x-go-binding/ui/x11"
    "fmt"
    "image"
    "image/color"
    "image/draw"
    "log"
    "os"
    "time"
)

var randcol = genrandcol()

func genrandcol() <-chan color.Color {
    c := make(chan color.Color)

    go func() {
        for {
            select {
            case c <- image.Black:
            case c <- image.White:
            }
        }
    }()

    return c
}

func gennoise(screen draw.Image) {
    for y := 0; y < 240; y++ {
        for x := 0; x < 320; x++ {
            screen.Set(x, y, <-randcol)
        }
    }
}

func fps() chan<- bool {
    up := make(chan bool)

    go func() {
        var frames int64
        var lasttime time.Time
        var totaltime time.Duration

        for {
            <-up
            frames++
            now := time.Now()
            totaltime += now.Sub(lasttime)
            if totaltime > time.Second {
                fmt.Printf("FPS: %v\n", float64(frames)/totaltime.Seconds())
                frames = 0
                totaltime = 0
            }
            lasttime = now
        }
    }()

    return up
}

func main() {
    win, err := x11.NewWindow()
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    defer win.Close()

    go func() {
        upfps := fps()
        screen := win.Screen()

        for {
            gennoise(screen)

            win.FlushImage()

            upfps <- true
        }
    }()

    for _ = range win.EventChan() {
    }
}