views:

207

answers:

5

This code is for transforming from colored to black and white.

  • I tried to add parallel section to the code
  • just transforming from gray-scale to black-white
  • i tried to assign to each thread a number of cols which has amount of pixels

but the performance didnt improve at all.

I tried for a 800*600 image by changing the divisor value (its here 800 in code) in the 2 for loops and the counter value increment .

This change should make the number of threads increase or decrease

the results :

value |  num of thread |   time
 800       1              1.17 sec
 400       2              1.17 sec
 200       4              1.17 sec
and so on ...

Help me to increase the performance coz it takes 8 sec for bigger images and i want to make it parallel

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;

namespace IMG
{

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    string path = "";
    public void openimage()
    {
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            path = openFileDialog1.FileName;
        }
    }
    Bitmap bm;
    Bitmap gs;
    private void button1_Click(object sender, EventArgs e)
    {
        if (path == "")
        {
            openimage();
        }
        Graphics g = this.CreateGraphics();
        bm = new Bitmap(path);
        // Draw image with no effects.....
        g.DrawImage(bm, 100, 100, 200, 200);
        gs = new Bitmap(bm.Width, bm.Height);
        worker soso = new worker(gs, bm);
        worker.counter = 0;
        soso.tograyscale();
        // Draw gray image.......
        g.DrawImage(gs, 305, 100, 200, 200);
        DateTime x = DateTime.Now;
        for (int koko = 0; koko < gs.Width/400; koko++)
        {        
                Thread t1 = new Thread(new ThreadStart(soso.trasform));
                t1.Start();
                t1.Join();
                soso.increment();
        }
        g.DrawImage(bm, 510, 100, 200, 200);
        gs.Dispose();
        g.Dispose();
        textBox19.Text=(DateTime.Now - x).ToString();
    }
}
public class worker
{
    public static int counter = 0;
    public Bitmap gs;
    public Bitmap bm;
    public int xxxx;
    public worker(Bitmap a, Bitmap b)
    {
        gs = a;
        bm = b;
        xxxx = a.Height;
    }
    public void increment()
    {
        counter += 400;
    }
    public void trasform()
    {
        argtransform(counter);

    }
    public void tograyscale()
    {
        for (int i = 0; i < bm.Width; i++)
        {
            for (int j = 0; j < bm.Height; j++)
            {
                Color c = bm.GetPixel(i, j);
                int y = (int)(0.3 * c.R + 0.59 * c.G + 0.11 * c.B);
                gs.SetPixel(i, j, Color.FromArgb(y, y, y));
            }
        }
    }
    public void argtransform(int cc)
    {
        for (int i = cc; i < cc + 400; i++)
        {
            for (int j = 0; j < xxxx; j++)
            {
                Color c = gs.GetPixel(i, j);
                int y1 = 0;
                if (c.R >= 128)
                    y1 = 255;
                bm.SetPixel(i, j, Color.FromArgb(y1, y1, y1));
            }
        }
    }
  }
}

thank you please as soon as u can

+6  A: 

Don't parallelize before you optimize. Run your code under a good profiler and fix the performance issues first. Yes, this may turn out to be a good candidate for parallelization in the end, but I'm betting that 1 million calls to SetPixel is a much bigger issue.

Craig Stuntz
"but I'm betting that 1 million calls to SetPixel is a much bigger issue" - I reckon you're right! +1
Mitch Wheat
how could i edit the color of pixel without calling setpixel ? thank you for your help
FarOoOosa
Christian Vik gave you a decent example for this.
Craig Stuntz
+2  A: 

GetPixel() / SetPixel() is way to slow for doing this. Instead you should use BitmapData with "unsafe" and pointers to edit the image.

Update: And a quick google search on BitmapData and grayscale turned out to list this example.

Christian Vik
A: 

Before even thinking of parallelisation, You should profile your code to find out where the time is actually being spent.

Eqatec's profiler is a free and easy to use .NET profiling tool.

Mitch Wheat
+4  A: 

By calling Thread.Start then immediately calling Thread.Join, you're effectively working in serial rather than parallel. Place a second loop after the Thread.Start loop which calls Thread.Join.

List<Thread> threads = new List<Thread>();
for (int koko = 0; koko < gs.Width/400; koko++)
{        
    Thread t1 = new Thread(new ThreadStart(soso.trasform));
    t1.Start();
    threads.Add(t1);
    soso.increment();
}

foreach (Thread thread in threads) thread.Join();
sixlettervariables
+1 I was just typing that :)
Paolo
Additionally, +1 to what everyone else said. My answer is just identifying the problem with your example code in terms of parallelization, not in terms of performance.
sixlettervariables
it didnt work my friend coz when i did it i faced an exception "Object is currently in use elsewhere."i dont know why please can you help me if u have an email i can send the project to ur emailthanks
FarOoOosa
You may be running into the issue that you cannot call methods on a Bitmap across threads.
sixlettervariables
A: 

thank you all question for Craig Stuntz : how could i edit the color of pixel without calling setpixel ? thank you for your help

FarOoOosa