Click here to Skip to main content
15,918,742 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi everybody,

An image process program that it has a brightness function and so on for changing brightness. So I want to implement my purpose using System.Threading.Tasks library (particularly Parallel.For) and represent in progress and finally we have a responsive UI. Also I a lot of Googling and find out many benefit topics. But don't update progress element whilst process image. Where is the problem in this program?

XAML code:
XML
<Window x:Class="WpfApp_Tmp.DiagramPic.DiagramPic"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DiagramPic" Height="600" Width="400">
    <Grid>
        <StackPanel>
            <Button Click="Button_Click_1">Brightness using Ptr</Button>
            <ProgressBar Name="progress" Height="20"></ProgressBar>
            <Image Name="image" Stretch="UniformToFill" />
        </StackPanel>
    </Grid>
</Window>


Code behind:
C#
BitmapSource SetBrightnessWithPtr(BitmapSource bmp, int amount)
{
    WriteableBitmap bDest = null;
    bDest = new WriteableBitmap(bmp);
    bDest.Lock();
    IntPtr buff = bDest.BackBuffer;
    int stride = bDest.BackBufferStride;

    int nWidth = bmp.PixelWidth;
    int nHeight = bmp.PixelHeight;

    double percentage = 100 / (progress.Maximum = nHeight);
    progress.Value = 0.0;

    //Task.Factory.StartNew(delegate
    //{
        Parallel.For(0, nHeight, y =>
        //for(int y=0;y<nHeight;y++)
        {
            IntPtr buffer = buff;
            buffer += y * stride;

            for (int x = 0; x < nWidth; x++)
            {
                Int32 abgr = Marshal.ReadInt32(buffer);

                int r = (abgr & 0x000000ff) + amount;
                int g = ((abgr & 0x0000ff00) >> 0x08) + amount;
                int b = ((abgr & 0x00ff0000) >> 0x10) + amount;
                //int a = (byte)((abgr & 0xff000000) >> 0x18);

                r = Math.Max(Math.Min(r, 255), 0);
                g = Math.Max(Math.Min(g, 255), 0);
                b = Math.Max(Math.Min(b, 255), 0);
                //a = 0xff;

                abgr |= r;
                abgr |= g << 0x08;
                abgr |= b << 0x10;
                //abgr |= a << 0x18;

                Marshal.WriteInt32(buffer, abgr);

                buffer += 4;
            }

            progress.Dispatcher.BeginInvoke((Action)delegate { this.Title = Convert.ToByte(++progress.Value * percentage).ToString(); });
        });
    //});

    //bDest.AddDirtyRect(new Int32Rect(0, 0, bDest.PixelWidth, bDest.PixelHeight));
    bDest.Unlock();

    return bDest;
}

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    opening();

    int startTime = System.Environment.TickCount;

    if (image.Source != null)
        image.Source = SetBrightnessWithPtr(image.Source as BitmapSource, 128);

    this.Title += " " + (System.Environment.TickCount - startTime).ToString();
}

void opening()
{
    Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
    ofd.Filter = "All images|*.bmp;*.jpg;*.png|Bitmap|*.bmp|Jpeg|*.jpg|Png|*.png";
    if (ofd.ShowDialog().Value)
    {
        Uri imageUri = new Uri(ofd.FileName, UriKind.Absolute);

        this.image.Source = new BitmapImage(imageUri);
    }
}


Your help very appreciated.
Posted
Comments
hzawary 6-Aug-13 19:00pm    
Note and issue: Progress.Value must be updated and presented in per line of image.
Sergey Alexandrovich Kryukov 6-Aug-13 23:36pm    
It's simple: don't use Parallel, it's not helpful in this case.
—SA

1 solution

I think you might misunderstand the purpose of Parallel.For(). It is not to execute tasks in the background but merely in parallel. To be fair, the MSDN article[^] doesn't state that outright, but it says:
Quote:
Executes a for (For in Visual Basic) loop in which iterations may run in parallel.

This does imply that even parallelism is not guaranteed (I know they are becoming rare but think of single core CPUs) and the calling thread may actually be used for loop execution. Furthermore, For() returns a ParallelLoopResult[^] which doesn't give you any way of cancelling or waiting for completion (notice how IsCompleted indicates premature completion) which would be unusual at best for an asynchronous API. Finally, a short test easily confirms this behavior:
static void Main(string[] args)
{
    Console.WriteLine("Invoking Parallel.For() on thread {0}",
                        Thread.CurrentThread.ManagedThreadId);

    Parallel.For(0, Environment.ProcessorCount, i =>
    {
        Thread.Sleep(1000);
        Console.WriteLine("    Wasted 1 sec on thread {0}",
                            Thread.CurrentThread.ManagedThreadId);
    });

    Console.WriteLine("Parallel.For() returned on thread {0}",
                        Thread.CurrentThread.ManagedThreadId);
    Console.ReadKey(true);
}

The last two lines will not execute until the completion of the loop. Long story short, what you are really looking for is Task[^] (or some other way of running code asynchronously like QueueUserWorkItem()[^] or spinning up your own background thread).
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 6-Aug-13 23:35pm    
Very good, a 5.
—SA
hzawary 7-Aug-13 9:08am    
Very thanks so, what your offer for obtain this program purposes?

1- Ideal in higher performance (lower time & memory complicated) and processing image to faster.

2- Progress reporting (represent progress per line of image).

3- Be responsible UI.

Is use BackgroundWorker good for this?
and also Parallel.For for iteration?
if its positive, How to resolve value updating problem of represent progress bar in UI.
hzawary 7-Aug-13 8:52am    
Very thanks so, what your offer for obtain this program purposes?

1- Ideal in higher performance (lower time & memory complicated) and processing image to faster.

2- Progress reporting (represent progress per line of image).

3- Be responsible UI.

Is use BackgroundWorker good for this?
and also Parallel.For for iteration?
if its positive, How to resolve value updating problem of represent progress bar in UI.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900